Manage Tunnels
CRUD plus a 24-hour soft-delete grace window for tunnel resources. See the Tunnels API overview for naming rules, lifecycle states, and TLS modes.
Create tunnel POST
POST /tunnelsCreate a new tunnel. The response includes a connect_secret shown once — store it securely.
tls_mode: "edge"(default): the tunnel isactiveimmediately and routable at{tunnel_name}.inkboxwire.com.tls_mode: "passthrough": the tunnel starts inawaiting_cert. You must then submit a CSR via/sign-csrto transition toactive.
Rate-limited to 10 successful creates per organization per day.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
tunnel_name | string | Yes | Subdomain label. 3–63 chars, lowercase a–z, 0–9, hyphens; must start and end with alphanumeric; no consecutive hyphens. Globally unique within the environment. |
description | string | null | No | Free-form description (max 1000 chars). For your own reference. |
tls_mode | string | No | "edge" (default) or "passthrough". Immutable after creation. |
Request example
Response (201)
Error responses
| Status | Description |
|---|---|
| 409 | tunnel_name is already taken or reserved |
| 422 | tunnel_name violates naming rules, or description exceeds 1000 chars |
| 429 | Daily create rate limit exceeded |
Code examples
List tunnels GET
GET /tunnelsList all tunnels in the caller's organization (excludes deleted). Each entry includes a live currently_connected flag.
Response (200)
Code examples
Get tunnel GET
GET /tunnels/{tunnel_id}Fetch a single tunnel by ID. Includes a live currently_connected flag.
Path parameters
| Parameter | Type | Description |
|---|---|---|
tunnel_id | UUID | Tunnel ID |
Code examples
Update tunnel PATCH
PATCH /tunnels/{tunnel_id}Update the tunnel's description. tunnel_name and tls_mode are immutable — create a new tunnel if you need a different name or mode.
Path parameters
| Parameter | Type | Description |
|---|---|---|
tunnel_id | UUID | Tunnel ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
description | string | No | New description (max 1000 chars). Omit to leave unchanged. |
Code examples
Delete tunnel DELETE
DELETE /tunnels/{tunnel_id}Move a tunnel into a 24-hour delete grace window. Inbound traffic stops immediately and status flips to delete_pending. The tunnel name stays reserved for your organization for 24 hours; after that, the tunnel is deleted and the name is released.
To undo within the grace window, call POST /tunnels/{id}/restore. Idempotent — calling delete on a delete_pending tunnel is a no-op.
Path parameters
| Parameter | Type | Description |
|---|---|---|
tunnel_id | UUID | Tunnel ID |
Response (200)
Returns the updated Tunnel object. status is delete_pending and restore_deadline_at is set to 24 hours from now.
Code examples
Restore tunnel POST
POST /tunnels/{tunnel_id}/restoreUndo a delete_pending deletion during the 24-hour grace window.
edgetunnels return toactive.passthroughtunnels return toactiveif a still-valid signed cert is on file; otherwiseawaiting_cert.
Path parameters
| Parameter | Type | Description |
|---|---|---|
tunnel_id | UUID | Tunnel ID |
Error responses
| Status | Description |
|---|---|
| 409 | Tunnel is not in delete_pending state (e.g. already finalized as deleted, or grace window expired) |
Code examples
Force-delete tunnel DELETE
DELETE /tunnels/{tunnel_id}/forceSkip the 24-hour grace window and finalize a delete_pending tunnel immediately. The name is released for re-use right away.
Auth: API key or Clerk JWT only. The grace window exists to undo accidental deletes; force-finalize bypasses that net.
Path parameters
| Parameter | Type | Description |
|---|---|---|
tunnel_id | UUID | Tunnel ID |
Error responses
| Status | Description |
|---|---|
| 403 | Caller is not an admin (scoped agent keys cannot force-delete) |
| 409 | Tunnel is not in delete_pending state — call regular DELETE first |
Code examples
Tunnel object
| Field | Type | Description |
|---|---|---|
id | UUID | Unique tunnel identifier |
organization_id | string | Owning organization |
tunnel_name | string | Subdomain label. Hostname is {tunnel_name}.inkboxwire.com. Immutable. |
description | string | null | Optional free-form description |
tls_mode | string | "edge" or "passthrough". Immutable. |
cert_pem | string | null | Signed cert PEM (passthrough only, after first /sign-csr) |
cert_fingerprint_sha256 | string | null | SHA-256 fingerprint of cert_pem, useful for monitoring rotations |
cert_expires_at | string | null | ISO 8601 expiry of cert_pem. Renew before this date. |
status | string | awaiting_cert, active, delete_pending, or deleted |
last_connected_at | string | null | ISO 8601 timestamp of the most recent agent connection |
last_connected_ip_addr | string | null | Client IP recorded at the most recent agent connection |
restore_deadline_at | string | null | Set only while status="delete_pending". After this UTC timestamp, restore returns 409 and the tunnel finalizes to deleted. |
currently_connected | boolean | true if at least one agent connection is currently registered |
created_at | string | ISO 8601 |
updated_at | string | ISO 8601 |