> For the complete documentation index, see [llms.txt](https://developers.bead.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.bead.xyz/entity-management/terminal-management/create-terminal.md).

# Create Terminal

Creates a new terminal under an existing location. This endpoint is used for terminal setup and returns the terminal record along with the terminal payments API key that should be stored securely for future payment requests.

**Endpoint**

`POST /Terminals`

**Authentication**

Use your **admin API key** in the request header for terminal management operations.

> In the example below, `X-Api-Key` is used as the header name. Replace that with your standard admin API key header name if your docs use a different label.

**Request headers**

| Header         | Value              |
| -------------- | ------------------ |
| `X-Api-Key`    | `{adminApiKey}`    |
| `Content-Type` | `application/json` |
| `Accept`       | `application/json` |

**Request body**

| Field                    | Type    | Required | Description                                                                                                                             |
| ------------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                   | string  | Yes      | Friendly name for the terminal.                                                                                                         |
| `locationId`             | string  | Yes      | ID of the location that owns the terminal.                                                                                              |
| `type`                   | enum    | Yes      | Terminal type. One of `virtual` or `physical` — see below. Set at creation and cannot be changed afterward.                             |
| `useSandboxSharedWallet` | boolean | Yes      | Must be `true` in Sandbox for USDC and crypto tenders to function. Set at creation time only — cannot be changed via the edit endpoint. |
| `tenderTypes`            | array   | No       | Tender types enabled for this terminal.                                                                                                 |
| `description`            | string  | No       | Optional terminal description.                                                                                                          |
| `displayLogo`            | boolean | No       | Controls whether the logo is displayed where supported.                                                                                 |
| `extendRedirectUrl`      | boolean | No       | Adds `paymentPageId` as a query parameter to the redirect URL.                                                                          |
| `maxTransactionAmount`   | number  | No       | Optional maximum transaction amount for this terminal.                                                                                  |

**`type` values**

| Value      | Description                                                                                                                                                       |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `virtual`  | An online or remote acceptance environment — hosted checkout, eCommerce, invoicing, or any flow where the customer is not physically present at a counter.        |
| `physical` | An in-person acceptance environment, such as a point-of-sale or service counter, where a customer is physically present and typically waiting on the transaction. |

`type` is not cosmetic. It is the primary signal Bead uses for the **standing tender-type recommendation** applied to the terminal: virtual terminals default to all approved tenders enabled, while physical terminals default to BTC (on-chain) **disabled**, because on-chain confirmation is long-running and unsuitable for a customer waiting at a counter. See [Terminal Lifecycle (Concepts)](/entity-management/terminal-management/terminal-lifecycle-concepts.md) for the full explanation, and [Choosing Tender Types by Payment Environment](/reference-guide/payment-flows/choosing-tender-types-by-payment-environment.md) for how to select tenders per environment.

`type` is set once at creation and cannot be changed later — [Update Terminal](/entity-management/terminal-management/update-terminal.md) does not accept it. If a terminal needs a different `type`, create a new terminal rather than attempting to convert an existing one.

**A merchant accepting payments in more than one environment needs a separate terminal per environment.** A merchant with both a physical point-of-sale and an online checkout needs at minimum one `physical` terminal and one `virtual` terminal — a single terminal cannot represent both. It is common for one merchant to have several terminals across locations and channels; see [Managing Tender Types](/entity-management/terminal-management/managing-tender-types.md) for how the approved tender set flows down to each one.

**Example request**

```bash
curl --request POST "https://api.test.devs.beadpay.io/Terminals" \
  --header "X-Api-Key: {adminApiKey}" \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --data '{
    "name": "Front Counter 1",
    "locationId": "67f00123456789abcdef0123",
    "type": "virtual",
    "tenderTypes": ["ethereum", "usdcBase"],
    "description": "Primary checkout terminal",
    "displayLogo": true,
    "extendRedirectUrl": false,
    "maxTransactionAmount": 5000,
    "useSandboxSharedWallet": true
  }'
```

**Example response**

```json
{
  "id": "67f10123456789abcdef0456",
  "name": "Front Counter 1",
  "description": "Primary checkout terminal",
  "merchantId": "67e90123456789abcdef0001",
  "merchantStatus": "active",
  "type": "virtual",
  "merchantLocationId": "67f00123456789abcdef0123",
  "merchantLocation": {
    "id": "67f00123456789abcdef0123",
    "name": "Main Store",
    "address": {
      "address1": "123 Main St",
      "city": "Boston",
      "region": "MA",
      "country": "US",
      "postalCode": "02110"
    },
    "isEnabled": true
  },
  "displayLogo": true,
  "webhookUrl": null,
  "isEnabled": true,
  "extendRedirectUrl": false,
  "tenderTypes": ["ethereum", "usdcBase"],
  "created": "2026-04-02T15:00:00Z",
  "updated": "2026-04-02T15:00:00Z",
  "maxTransactionAmount": 5000,
  "apiKey": {
    "secret": "pk_test_terminal_secret_value",
    "maskedSecret": "pk_****_value"
  },
  "useSandboxSharedWallet": true
}
```

**What to store**

After creating a terminal, store these values securely:

* `id` — the terminal ID
* `apiKey.secret` — the terminal payments API key

Use the terminal payments API key for payment requests associated with that terminal. Do not rely on login/password credentials for new integrations.

**Notes**

* Use your **admin API key** for terminal management operations such as create, update, delete, webhook configuration, and key reset.
* Use the returned **terminal payments API key** for payment activity performed by that terminal.
* Treat `apiKey.secret` like any other secret. Do not log it or expose it in client-side code.
* `apiKey.maskedSecret` is for display purposes only and cannot be used to authenticate.

**Error responses**

\<table>\<thead>\<tr>\<th width="108">Code\</th>\<th>Meaning\</th>\</tr>\</thead>\<tbody>\<tr>\<td>\<code>400\</code>\</td>\<td>The request body is invalid or missing required fields.\</td>\</tr>\<tr>\<td>\<code>401\</code>\</td>\<td>The admin API key is missing or invalid.\</td>\</tr>\<tr>\<td>\<code>403\</code>\</td>\<td>The caller is authenticated but not allowed to create a terminal for the target location.\</td>\</tr>\<tr>\<td>\<code>409\</code>\</td>\<td>A conflicting terminal state or duplicate condition prevented creation.\</td>\</tr>\</tbody>\</table>

**Related operations**

* [List Terminals](/entity-management/terminal-management/list-terminals.md)
* [Get Terminal](/entity-management/terminal-management/get-terminal.md)
* [Update Terminal](/entity-management/terminal-management/update-terminal.md)
* [Delete Terminal](/entity-management/terminal-management/delete-terminal.md)
* [Terminal Lifecycle (Concepts)](/entity-management/terminal-management/terminal-lifecycle-concepts.md)
* [Managing Tender Types](/entity-management/terminal-management/managing-tender-types.md)
* [Choosing Tender Types by Payment Environment](/reference-guide/payment-flows/choosing-tender-types-by-payment-environment.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.bead.xyz/entity-management/terminal-management/create-terminal.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
