Skip to content

Register an inbound HMAC-signed webhook

POST
/v1/webhooks

Register an inbound webhook. Accepts a client-supplied idempotency key (Idempotency-Key header or client_id body field): a retry with the same key replays the original registration; the same key with a different body is a 409. New keys should grant webhook:write; mailbox:read remains accepted for older keys. Connection mutations always require webhook:write. The registration retains its resource boundary after the connection expires. An explicit inbox binds its stable ID. Without an inbox filter, selected-inbox connections bind their selected IDs and broader connections bind the current project or organization.

org_id
string

Select an organization within the connection grant.

project_id
string

Narrow to a project within the connection grant.

Idempotency-Key
string

Optional client-supplied key making a CREATE exactly-once. A retry with the same key returns the ORIGINAL response (same status + body) instead of creating a duplicate; the same key with a different request body returns 409. The body field client_id is honored as an alias when this header is absent. The key is scoped per tenant (and per agent on the agent plane), so keys never collide across callers.

object
url
required
string format: uri
events
Array<string>
Allowed values: message.received
event_types

AgentMail-compatible alias for events.

Array<string>
Allowed values: message.received
inbox

Scope to one mailbox; omit for all.

string
address

Legacy alias for inbox.

string
client_id

Optional idempotency key (alias for the Idempotency-Key header). A retry with the same key replays the original webhook registration.

string

Registered. secret is shown once.

A webhook registration. secret is present only on the create response (shown once); list/get redact it. The durable resource_scope defines the delivery boundary. inbox is an additional address filter; null removes that filter without widening selected stable inbox IDs. Registrations survive the creating connection’s expiry and must be deleted separately.

object
id
string
url
string
events
Array<string>
Allowed values: message.received
inbox
string
nullable
agent_id

Agent identity recorded at creation.

string
resource_scope

Agent-owned inboxes for legacy keys; stable selected inbox IDs, project, or organization for connections. Project and organization scopes include future inboxes.

string
Allowed values: agent inboxes project organization
inbox_ids

Stable inbox IDs for an inboxes-scoped registration.

Array<string>
<= 100 items
created_by_connection_id

Creating connection ID when applicable.

string
secret

HMAC signing secret. Create response only.

string
secret_prefix
string
active
boolean
created_at
string format: date-time

Invalid request.

The canonical error envelope. error is a stable machine code.

object
error
required

Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).

string
Example
forbidden
message

Human-readable detail (never leaks internals).

string
Example
missing required scope
reason

Machine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.

string
used

Consumed plus reserved units.

integer format: int64
delta

Requested additional units.

integer format: int64
limit
integer format: int64
remaining
integer format: int64
consumed
integer format: int64
reserved
integer format: int64
next_reset_at

Next UTC usage-period boundary; pending reservations survive this boundary.

string format: date-time
upgrade_required
boolean

Missing or invalid credential.

The canonical error envelope. error is a stable machine code.

object
error
required

Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).

string
Example
forbidden
message

Human-readable detail (never leaks internals).

string
Example
missing required scope
reason

Machine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.

string
used

Consumed plus reserved units.

integer format: int64
delta

Requested additional units.

integer format: int64
limit
integer format: int64
remaining
integer format: int64
consumed
integer format: int64
reserved
integer format: int64
next_reset_at

Next UTC usage-period boundary; pending reservations survive this boundary.

string format: date-time
upgrade_required
boolean

The supplied idempotency key was already used with a different request body (error = idempotency_conflict).

The canonical error envelope. error is a stable machine code.

object
error
required

Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).

string
Example
forbidden
message

Human-readable detail (never leaks internals).

string
Example
missing required scope
reason

Machine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.

string
used

Consumed plus reserved units.

integer format: int64
delta

Requested additional units.

integer format: int64
limit
integer format: int64
remaining
integer format: int64
consumed
integer format: int64
reserved
integer format: int64
next_reset_at

Next UTC usage-period boundary; pending reservations survive this boundary.

string format: date-time
upgrade_required
boolean