Skip to main content
Agent identities are the unit of presence on Inkbox. Each identity owns exactly one mailbox and one tunnel; you can optionally attach a phone number, a dedicated iMessage line, and vault-secret access. Handles are globally unique across all Inkbox customers and are normalized — a leading @ is automatically stripped, so @my-agent and my-agent are equivalent.

Create identity

Atomically provisions the identity, its mailbox, and its tunnel in a single transaction. You can optionally provision and link a phone number, claim and attach a dedicated iMessage line, and attach access to existing vault secrets in the same request. The mailbox and tunnel are always created; the nested mailbox and tunnel bodies only customize them.

Request body

mailbox fields

Sending-domain resolution. Omitting mailbox does not necessarily yield {agent_handle}@inkboxmail.com. The server resolves the sending domain in three cases: if the org has set a verified custom domain as its default, omitting the body lands the mailbox on that custom domain with a server-chosen local part; passing "sending_domain": null forces the platform domain and the local part to agent_handle; passing an explicit bare-domain string pins the mailbox to that verified custom domain (404 if the domain isn’t verified for your org).

tunnel fields

The tunnel name is always forced to agent_handle; the public hostname is e.g. my-agent.inkboxwire.com.

phone_number fields

vault_secret_ids

Use this to attach existing vault secret access to the new identity. The organization must already have an active vault. If omitted, no vault secret access is attached. Accepted forms:
  • A single stringified UUID to attach one secret
  • A list of UUIDs to attach specific secrets
  • "all" or "*" to attach all active secrets in the active vault

Request example

JSON
To claim and attach a dedicated line while creating the identity, set both fields in the same request:
JSON
Identity creation does not require the dedicated-line Idempotency-Key header.

Response (201)

Returns the full identity-detail shape with nested mailbox and tunnel objects always populated. phone_number and imessage_number are populated when those numbers were provisioned.
JSON
mailbox and tunnel are always populated for active customer identities; phone_number and imessage_number are optional. When claim_imessage_number is true, imessage_number contains the claimed line’s id, E.164 number, and response-only type. The type value remains "dedicated_outbound" for compatibility and is not a capability selector. If vault_secret_ids is omitted, no vault secret access is attached. The embedded tunnel object is a durable-config summary. Live connection state (currently_connected), connection telemetry, and cert material live on the tunnels endpoints — fetch GET /api/v1/tunnels/{tunnel_id} when you need them; it resolves connection state fresh on every read.

Mailbox local-part validation

When you provide mailbox.email_local_part, it must satisfy these rules:
  • Length: 3–64 characters
  • Characters: lowercase letters, numbers, hyphens (-), underscores (_), and dots (.)
  • Start/end: must begin and end with a letter or number
  • No consecutive dots: my..agent is rejected
  • No @: provide the handle only, not a full email address
  • Reserved names blocked: some system addresses are reserved; you’ll get a 409 if you pick one.

Handle validation

Handles are globally unique across all Inkbox customers. They must satisfy:
  • Length: 3–63 characters
  • Characters: lowercase letters (a-z), digits (0-9), and hyphens (-)
  • Start/end: must begin and end with a letter or digit
  • No consecutive hyphens
Some handles are reserved; you’ll get a 409 if you pick one.

Error responses

The 409 body uses a stable error envelope:
JSON
blocking_namespace is a programmatic discriminator with three possible values — "identities", "tunnels", or "mail" — indicating which resource produced the conflict.

Code examples


List identities

List all identities for your organization, newest first. Each row carries the same nested mailbox / tunnel / phone_number / imessage_number blocks as Get identity, so rendering an org-wide view takes one request — no per-identity follow-ups. Agent-scoped API keys receive only their own identity. Admin-scoped API keys and the Inkbox Console receive every identity in the organization.

Response (200)

JSON
The embedded tunnel block is the same durable-config summary as on Get identity — live connection state comes from GET /api/v1/tunnels/{tunnel_id}.

Code examples


Get identity

Get a single identity with its linked communication channels. Returns the identity-detail shape with nested mailbox, tunnel, and (when attached) phone_number and imessage_number objects. With an agent-scoped API key, only the caller’s own identity is reachable; any other handle returns 404.

Path parameters

Response (200)

JSON
mailbox and tunnel are always populated for active customer identities. phone_number is null when no phone number is attached. imessage_number is null when the identity uses shared service or has no dedicated line attached. Its type remains "dedicated_outbound" as a response-only compatibility field. The embedded tunnel object is a durable-config summary; fetch GET /api/v1/tunnels/{tunnel_id} for live connection state and certificate material.

Error responses

Code examples


Update identity

Update an identity’s handle, display name, description, iMessage settings, attached iMessage line, or contact-rule filter modes. Returns the full identity-detail object, including the attached imessage_number.

Path parameters

Request body

PATCH semantics

The server distinguishes three caller intents on display_name and description: agent_handle, imessage_enabled, contact_sharing_enabled, claim_imessage_number, imessage_filter_mode, mail_filter_mode, and phone_filter_mode accept only the omit half — sending null for those fields is not a clear operation. imessage_number_id is different: an explicit null detaches the dedicated line while leaving it owned by your organization. claim_imessage_number: true and imessage_number_id cannot appear in the same request. A request also cannot claim or attach a line while setting imessage_enabled: false.

Claim idempotency header

Idempotency-Key is required whenever claim_imessage_number is true:
  • Retry the same logical claim with the same key to receive its original result.
  • Reusing the key with different input returns 409.
  • Generate a new key only for a genuinely new claim.

Request example

JSON
An existing enabled identity can claim and attach a dedicated line atomically:
bash

Response (200)

Returns the full identity-detail object. When the identity has a dedicated line, its imessage_number field is:
JSON

Error responses

The 409 body for an unavailable handle uses the same envelope as create: { detail: { code: "agent_handle_unavailable", message, blocking_namespace } }. The 409 for a platform-domain rename returns a flat { detail: "Cannot rename agent_handle: ..." } body explaining that the handle is the mailbox name on the platform domain.

Code examples


Delete identity

Delete an identity. The linked mailbox and tunnel are deleted as part of the cascade. Any identity-scoped API keys tied to this identity are revoked. Any linked phone number is released back to the carrier as part of the cascade — phone numbers cannot exist without an identity. The handle, its platform email address, and its tunnel name stay reserved permanently and cannot be claimed again by any organization. Returns 204 No Content on success. If the carrier release fails, the entire delete is aborted with a 502 and the identity stays active so you can retry safely.

Path parameters

Error responses

Code examples


Identity object

signing_key_configured and signing_key_created_at are status only — the signing secret itself is never returned here. The plaintext key is shown once by the per-identity signing-key rotate endpoint.

Identity detail object

Extends the identity object with linked channel data. Returned by the list, create, get, and update endpoints. Existing imessage_number_id attachment and detachment remain available. Detaching a dedicated line leaves it owned by the organization and visible from GET /api/v1/imessage/numbers. There is no customer-facing line-release endpoint.