Signing keys
Each agent identity has its own signing key, used to verify the webhooks and WebSocket upgrades for that identity's mailbox, phone number, and iMessage traffic. Verify incoming payloads for an identity's mail and phone channels with that identity's key.
Until an identity has a key, its webhooks and WebSocket connections are sent unsigned. Once a key exists, all of that identity's webhooks and WebSocket upgrades are signed automatically.
The plaintext key is returned only once when created or rotated. Store it securely — it cannot be retrieved again.
Your existing webhooks continue to verify with the same secret.
How an identity first gets its key
A brand-new agent identity has no signing key. There are two ways one comes into existence:
- Automatically, on the first subscription. The first webhook subscription you create for a keyless identity returns that identity's signing secret once, in the
signing_keyfield of the create response. Store it then — it isn't shown again. See Subscriptions. - Explicitly, via the POST route below. Call
POST /identities/{agent_handle}/signing-keyto mint a key up front (or to rotate an existing one).
Get signing key status GET
GET /identities/{agent_handle}/signing-keyReport whether this agent identity has a signing key configured. Does not return the secret.
Response (200)
| Field | Type | Description |
|---|---|---|
configured | boolean | true if this identity has a signing key. |
created_at | string | null | Timestamp the key was created or last rotated (ISO 8601); null when not configured. |
Code examples
Create or rotate signing key POST
POST /identities/{agent_handle}/signing-keyCreate a signing key for this agent identity, or rotate the existing one. On the first call a new key is generated. On subsequent calls the old key is replaced with a fresh one.
Response (201)
| Field | Type | Description |
|---|---|---|
signing_key | string | Plaintext signing key. Store this securely — it is only returned once. |
created_at | string | Timestamp of creation or rotation (ISO 8601). |
Error responses
| Status | Description |
|---|---|
503 | Webhook signing is not configured on the server. |
Code examples
Deprecated: org-level signing key
The org-level endpoints POST /signing-keys and GET /signing-keys are deprecated. Their responses carry a Link header pointing at the per-identity route above. Move to …/identities/{agent_handle}/signing-key.
While they remain available, behavior depends on the caller's auth scope:
| Endpoint | Agent-scoped API key | Admin API key, or manage from the Inkbox Console |
|---|---|---|
POST /signing-keys | Rotates that one identity's key (returns the secret once). | Returns 409 — rotate a specific identity via POST /identities/{agent_handle}/signing-key. |
GET /signing-keys | Reports that identity's status. | Reports an org-aggregate status: configured is true if any identity in the org has a key. |
Verifying webhook signatures
Once you have an identity's signing key, use it to verify incoming webhook payloads for that identity. See: