> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dintero.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage terminals remotely

> Send administrative commands to a Dintero payment terminal and read the results, including end-of-day, log upload, update checks, opening the terminal menu, pinging the terminal, and printing.

Terminal operations let you send administrative commands to a registered payment terminal and read the results. Use them to run an end-of-day close, ask the terminal to upload its logs, check for software updates, open the terminal menu, ping the terminal to see whether it is reachable, or print on the terminal's printer, without physically touching the device.

Operations are asynchronous. You send a command, the API dispatches it to the terminal and returns immediately with a `PENDING` operation, and the terminal processes the command in the background. You then poll the operation to see how it finished.

> [!NOTE]
>
> Terminal operations are administrative commands. They do not start a payment. To take a payment on a terminal, see [creating a terminal session](/docs/checkout/in-person/creating-terminal-session.md).

## Available operations

| Operation | What it does | Use it when | Terminal status required |
| - | - | - | - |
| `end_of_day` | Closes the terminal's current batch and settles it with the acquirer, then reports the batch totals. | Once per trading day, after the last payment. | `ACTIVE` |
| `send_logs` | Has the terminal upload its log files to the terminal vendor. The logs are not returned through the API. | Support asks for logs while investigating a problem with the device. | `ACTIVE` |
| `check_update` | Has the terminal check for a software update and install one if available. May reboot the terminal. | A terminal is behind on software, or support asks you to update it. | `ACTIVE`, `PENDING` or `ACTION_REQUIRED` |
| `open_menu` | Opens the settings menu on the terminal's own screen, for an operator standing at the device. The terminal cannot take payments while the menu is open. | Someone at the terminal needs to change its configuration. | Any status except `PENDING` |
| `poll_terminal` | Pings the terminal to see whether it is online and responding. No effect on the device. | Before sending another operation, or when a terminal is reported as unresponsive. | Any status |
| `print_text` | Prints lines of text you send on the terminal's printer. Dintero does not compose or check the content. | Your cash register system uses the terminal as its printer, for example for a sales receipt. | `ACTIVE` |
| `print_receipt` | Prints a copy of the payment receipt of an in-person transaction, marked as a copy. | A customer or the merchant needs the payment receipt again. | `ACTIVE` |

If the terminal's status does not allow the operation, the API responds with
`400 Bad Request`. `poll_terminal` is never rejected on status, so it is the
safe way to check a terminal you are unsure about.

## Send a command

```http theme={null}
POST https://api.dintero.com/v1/accounts/{account_id}/payments/admin/terminals/operations
Authorization: Bearer <token>
Content-Type: application/json
```

The request body identifies the terminal and the operation to run.

```json theme={null}
{
  "terminal_id": "P12345678-T0012",
  "operation": "end_of_day"
}
```

The response is returned as soon as the command is dispatched to the terminal. The terminal's response is processed asynchronously, so the operation starts with status `PENDING`.

```json theme={null}
{
  "id": "3f1a9c2e-8b7d-4f6a-9c1e-2d5b8a0f4e6c",
  "terminal_id": "P12345678-T0012",
  "operation": "end_of_day",
  "status": "PENDING",
  "created_at": "2026-06-29T09:00:00Z",
  "created_by": "user@example.com",
  "updated_at": "2026-06-29T09:00:00Z",
  "updated_by": "user@example.com"
}
```

See [POST /admin/terminals/operations](/api-reference/terminals/admin_terminals_operations_post.md) for the full schema.

### Idempotency

Pass an `Idempotency-Key` header to ensure the same command is only executed once, for example when retrying after a network error.

```http theme={null}
Idempotency-Key: 9b2c5d7e-1a3f-4c6b-8d9e-0f1a2b3c4d5e
```

### Check that a terminal is reachable

The `poll_terminal` operation pings the terminal without changing anything on the device. Use it to confirm that a terminal is online and responding, for example before you send another operation or when you are investigating a terminal that customers report as unresponsive.

```json theme={null}
{
  "terminal_id": "P12345678-T0012",
  "operation": "poll_terminal"
}
```

`poll_terminal` can be sent regardless of the terminal's status, so you can also use it on a terminal that is not `ACTIVE`. The operation ends as `COMPLETED` when the terminal answers, and as `TIMEOUT` when no answer arrives within the timeout window.

### Print text

`print_text` prints the lines you send, in order. Each line has its own `size` and `align`.

```json theme={null}
{
  "terminal_id": "P12345678-T0012",
  "operation": "print_text",
  "parameters": {
    "lines": [
      { "text": "Dintero Butikk AS", "size": "small", "align": "center" },
      { "text": " ", "size": "small", "align": "left" },
      { "text": "Total kr 10,00", "size": "large", "align": "left" }
    ]
  }
}
```

* Send 1 to 255 lines. Each `text` is at most 255 bytes.
* The terminal does not wrap lines. A line that is too wide is cut off at the right edge. A line fits 29 characters at `small` and `medium`, and 15 at `large`.
* A `large` line overlaps a `small` or `medium` line right above it. Put a blank line before a `large` line.
* For a blank line, send `" "`. An empty `text` is rejected with `400`.
* A tab or a newline in `text` prints as a space. Send each printed line as its own entry in `lines`.

### Print a copy of a payment receipt

`print_receipt` prints the receipt text the terminal wrote during the payment, marked as a copy. Dintero does not compose a receipt itself.

```json theme={null}
{
  "terminal_id": "P12345678-T0012",
  "operation": "print_receipt",
  "parameters": {
    "transaction_id": "P12345678.465UfBENeLpkBvwmqfTC4k",
    "type": "customer"
  }
}
```

* `type` is `customer` for the cardholder's copy, or `merchant` for the merchant's copy.
* When no receipt text is stored for the transaction, for example for older transactions, the API responds with `400`.

### One operation of each type at a time

A terminal has at most one pending operation of each type. If an operation of the same type is already pending for the terminal, the API responds with `409 Conflict` and a `Retry-After` header indicating how many seconds to wait before retrying. Operations of other types are not blocked: a pending `end_of_day` does not block a `print_text`.

## List operation results

Poll operations to see how a command finished. The endpoint returns operations and supports filtering by `terminal_id` and `operation_id`.

```http theme={null}
GET https://api.dintero.com/v1/accounts/{account_id}/payments/admin/terminals/operations?terminal_id=P12345678-T0012
Authorization: Bearer <token>
```

To check a single operation, filter by the `id` returned when you sent the command.

```http theme={null}
GET https://api.dintero.com/v1/accounts/{account_id}/payments/admin/terminals/operations?operation_id=3f1a9c2e-8b7d-4f6a-9c1e-2d5b8a0f4e6c
Authorization: Bearer <token>
```

Operations are returned most recently created first. Use `limit` (default
100\) and `starting_after` with the `id` of the last operation you saw to page
through older ones.

See [GET /admin/terminals/operations](/api-reference/terminals/admin_terminals_operations_get.md) for the full schema.

### Operation status

| Status | Meaning |
| - | - |
| `PENDING` | The operation has been dispatched to the terminal and is awaiting a response. |
| `COMPLETED` | The terminal responded and the operation finished successfully. |
| `FAILED` | The terminal responded but reported a failure. |
| `TIMEOUT` | No response was received from the terminal within the timeout window. A new operation can be dispatched. |

Which of these an operation can reach depends on the operation.
`open_menu` and `poll_terminal` are never `FAILED` - the terminal does not
report a failure for them, so an unreachable terminal ends the operation as
`TIMEOUT`. `end_of_day`, `send_logs`, `check_update`, `print_text` and
`print_receipt` are `FAILED` when the terminal answers but reports a problem,
and the `result` says what it was.

### Operation result

An operation that reaches `COMPLETED` or `FAILED` carries a `result` object
whose contents depend on the operation - on `FAILED` it is what tells you
why. A `TIMEOUT` operation never has a `result`. The examples below show
only that field of the operation.

> [!NOTE]
>
> The fields inside `result` are camelCase, unlike the rest of the operation.
> The `end_of_day` counts and amounts are the strings the terminal reported,
> not numbers, and are only present when the terminal included them.

`poll_terminal` and `open_menu` report only that the terminal answered:

```json theme={null}
{
  "result": {
    "result": "ok"
  }
}
```

`send_logs` reports whether the terminal reached the log destination.
`connectionError` means it did not, and the operation is `FAILED`:

```json theme={null}
{
  "result": {
    "result": "connectionError"
  }
}
```

`check_update` adds whether the terminal will reboot to apply an update. When
`terminalReboot` is true, the terminal is unavailable for payments until it is
back online - use `poll_terminal` to see when it is reachable again:

```json theme={null}
{
  "result": {
    "result": "ok",
    "terminalReboot": true
  }
}
```

`print_text` and `print_receipt` report whether the terminal printed:

```json theme={null}
{
  "result": {
    "result": "unknown_error"
  }
}
```

| `result` | Meaning |
| - | - |
| `ok` | The terminal printed. |
| `out_of_paper` | The terminal reported that it is out of paper. The operation is `FAILED`. |
| `no_printer` | The terminal has no printer. The operation is `FAILED`. |
| `unknown_error` | The terminal reported a failure without a reason, for example missing paper. The operation is `FAILED`. Check the printer before you retry. |

`end_of_day` reports the outcome and the batch totals:

```json theme={null}
{
  "result": {
    "result": "accepted",
    "batchId": "42",
    "startOfDay": "2026-06-29T06:00:00Z",
    "lastEndOfDay": "2026-06-28T22:00:04Z",
    "purchasesCount": "37",
    "purchasesAmount": "1284500",
    "reversalsCount": "1",
    "reversalsAmount": "9900",
    "saleAmount": "1274600",
    "tipAmount": "12000"
  }
}
```

| `result` | Meaning |
| - | - |
| `accepted` | The batch was closed and settled. |
| `offline_accepted` | The terminal closed the batch without reaching the acquirer. It settles when the terminal is back online. |
| `not_accepted` | The acquirer rejected the batch. The operation is `FAILED`. |
| `no_user_found` | No operator matched the `operator_id` you passed, so nothing was closed. The operation is `FAILED`. |
| `unknown` | The terminal's response omitted the outcome. The operation is `FAILED` and the batch state is undetermined - check the terminal before retrying. |

## End-of-day when a terminal is removed

Removing a terminal with [`DELETE /v1/accounts/{aid}/terminals/{terminal_id}`](/api-reference/account-terminals/aid_account_management_terminals_termid_delete) also starts an `end_of_day` operation on it, to close the terminal's open batch. The operation runs asynchronously and does not block or fail the removal.

Read its result from the operations list filtered by the removed terminal's `terminal_id`, as described in [List operation results](#list-operation-results). A terminal that is turned off or unreachable when it is removed ends the operation as `TIMEOUT`. No operation is created for a terminal that is not active, for example one still being activated.

## Scopes

| Endpoint | Scopes |
| - | - |
| `POST /accounts/{account_id}/payments/admin/terminals/operations` | `admin:checkout` or `write:checkout:/admin/terminals` |
| `GET /accounts/{account_id}/payments/admin/terminals/operations` | `admin:checkout` or `read:checkout:/admin/terminals` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.