# Create a terminal ticket

Issue a single-use ticket so a browser can open the terminal without an Authorization header.

POST `/v1/customer/tenants/{tenantId}/sandboxes/{sandboxId}/terminal-ticket`

Base URL: `https://api.runzivo.dev`

## Authentication

Send `Authorization: Bearer <token>` with a customer access token or workspace API key.

API key permission: `sandboxes:write`. These are permissions, not legacy scopes. A key with the `all:all` scope also works, limited by its creator's current workspace permissions.

## Parameters

| Field | Description |
| --- | --- |
| `tenantId` string · path Required | Your workspace's tenant ID. Replace the placeholder with an ID your token can access. |
| `sandboxId` string · path Required | The id returned when the sandbox was created: sbx\_ followed by 24 lowercase hexadecimal characters. |

## Request body

No request body is required.

## Behavior and limits

- Requires a running sandbox. A ticket lasts about 30 seconds and is bound to one sandbox and workspace.
- Append the URL-encoded ticket as ?ticket= to the returned terminal URL. Do not log the query string. A sandbox can have at most ten unused tickets (429 ticket_limit_reached).
- Browser WebSocket connections cannot supply Authorization. Use the ticket without an Authorization header; API and CLI clients can instead authenticate the terminal directly.

## Responses

| Status | Meaning |
| --- | --- |
| 201 Created | application/json |
| 401 Unauthorized | Missing or invalid bearer token. A ticketed terminal request can instead return ticket_invalid. |
| 403 Forbidden | The caller lacks workspace membership or permission, or the API key is not allowed. Codes include tenant_membership_required, permission_required and api_key_scope_required. |
| 404 Not found | No sandbox with this ID exists in the authorized workspace. |
| 409 Conflict | The operation is not allowed in the current sandbox state. See the operation notes for other possible conflict codes. |
| 429 Too many tickets | Ten unused tickets already exist for this sandbox. |
| 500 Internal error | The server could not complete the request. |
| 503 Unavailable | Sandbox service is unavailable. Exec and terminal operations can also return sandbox_exec_unavailable. |

Examples use synthetic IDs, dates and values. Read the actual response and status in your workspace.

## Ticket response fields

| Field | Description |
| --- | --- |
| `url` string Required | Absolute wss URL of this sandbox's terminal. |
| `ticket` string Required | Single-use ticket, valid for about 30 seconds. Append as a URL-encoded query parameter. |
| `expires_at` date-time Required | When the ticket expires. |

[Sandbox limits and billing](https://runzivo.dev/docs/sandboxes-limits/)

Page tools

[View as Markdown](https://runzivo.dev/docs/reference/sandboxes/terminal-ticket.md)

Ask AI about this page

[Open in ChatGPT](https://chatgpt.com/?q=Read%20this%20Runzivo%20documentation%20page%2C%20then%20help%20me%20with%20it%3A%0A%0Ahttps%3A%2F%2Frunzivo.dev%2Fdocs%2Freference%2Fsandboxes%2Fterminal-ticket.md) [Open in Claude](https://claude.ai/new?q=Read%20this%20Runzivo%20documentation%20page%2C%20then%20help%20me%20with%20it%3A%0A%0Ahttps%3A%2F%2Frunzivo.dev%2Fdocs%2Freference%2Fsandboxes%2Fterminal-ticket.md) [Open in Cursor](https://cursor.com/link/prompt?text=Read%20this%20Runzivo%20documentation%20page%2C%20then%20help%20me%20with%20it%3A%0A%0Ahttps%3A%2F%2Frunzivo.dev%2Fdocs%2Freference%2Fsandboxes%2Fterminal-ticket.md)

Claude shows a caution banner on any prefilled prompt. That is expected: review the prompt, then send it.

## Request example

Illustrative request. Set RUNZIVO_TOKEN and TENANT_ID, and SANDBOX_ID in your shell. Replace placeholders with your own values. This page does not send requests.

cURL

```
curl --request POST \
  "https://api.runzivo.dev/v1/customer/tenants/${TENANT_ID}/sandboxes/${SANDBOX_ID}/terminal-ticket" \
  --header "Authorization: Bearer ${RUNZIVO_TOKEN}"
```

## Response example

application/json · Illustrative response; values and timing vary in your workspace.

201 · application/json

```
{
  "url": "wss://api.runzivo.dev/v1/customer/tenants/<tenant-id>/sandboxes/sbx_000000000000000000000001/terminal",
  "ticket": "<single-use-ticket>",
  "expires_at": "2026-10-31T12:00:30Z"
}
```

All response examples (also available without JavaScript)

### 201 Created

Illustrative response; values and timing vary in your workspace.

application/json

```
{
  "url": "wss://api.runzivo.dev/v1/customer/tenants/<tenant-id>/sandboxes/sbx_000000000000000000000001/terminal",
  "ticket": "<single-use-ticket>",
  "expires_at": "2026-10-31T12:00:30Z"
}
```

### 401 Unauthorized

Missing or invalid bearer token. A ticketed terminal request can instead return ticket_invalid.

application/json

```
{
  "error": {
    "code": "unauthorized"
  }
}
```

### 403 Forbidden

The caller lacks workspace membership or permission, or the API key is not allowed. Codes include tenant_membership_required, permission_required and api_key_scope_required.

application/json

```
{
  "error": {
    "code": "permission_required"
  }
}
```

### 404 Not found

No sandbox with this ID exists in the authorized workspace.

application/json

```
{
  "error": {
    "code": "sandbox_not_found"
  }
}
```

### 409 Conflict

The operation is not allowed in the current sandbox state. See the operation notes for other possible conflict codes.

application/json

```
{
  "error": {
    "code": "sandbox_wrong_state"
  }
}
```

### 429 Too many tickets

Ten unused tickets already exist for this sandbox.

application/json

```
{
  "error": {
    "code": "ticket_limit_reached"
  }
}
```

### 500 Internal error

The server could not complete the request.

application/json

```
{
  "error": {
    "code": "internal_error"
  }
}
```

### 503 Unavailable

Sandbox service is unavailable. Exec and terminal operations can also return sandbox_exec_unavailable.

application/json

```
{
  "error": {
    "code": "sandboxes_unavailable"
  }
}
```
