Mail Contact Rules
Per-identity allow/block rules for inbound email. Mail rules attach to the agent identity itself and are addressed by agent_handle, mirroring iMessage contact rules. The identity's mail_filter_mode field decides how the rule list is interpreted:
mail_filter_mode: "whitelist"— only senders matching anallowrule can deliver mail to the agentmail_filter_mode: "blacklist"— every sender can deliver except those matching ablockrule
Set mail_filter_mode on the identity via PATCH /identities/{agent_handle} — see Manage identities. The rules below are interpreted against that mode.
Deprecation. The previous mailbox-addressed routes (
/mailboxes/{email_address}/contact-rules) are deprecated. They still work and return the same fields they did before. Migrate to the identity-keyed routes documented here.
Rules match on either a full email address (match_type: "exact_email") or a bare domain (match_type: "domain"). A rule with status: "paused" has no effect but still reserves its target slot, so you can stage policy changes without losing the uniqueness claim. Creating a duplicate (match_type, match_target) returns 409.
When a sender is blocked, inbound mail is stored but never delivered to the agent, and no message.received webhook fires.
Auth. List, get, and create accept admin API keys and claimed agent keys; unclaimed (mid-signup) agent keys are rejected. PATCH, DELETE, and the org-wide list require an admin-scoped API key, or you can manage them as a user in the Inkbox Console.
List contact rules GET
GET /identities/{agent_handle}/mail-contact-rulesList mail contact rules for an agent identity, newest first. Returns both active and paused rules.
An identity-scoped API key may only address its own identity's agent_handle — any other handle returns 403 (this applies to list, get, and create alike).
Path parameters
| Parameter | Type | Description |
|---|---|---|
agent_handle | string | The identity's handle, with or without the leading @ |
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
action | string | — | Filter by "allow" or "block" |
match_type | string | — | Filter by "exact_email" or "domain" |
limit | integer | 50 | Max rules (1–200) |
offset | integer | 0 | Offset for pagination |
Response (200)
Code examples
Create contact rule POST
POST /identities/{agent_handle}/mail-contact-rulesCreate an allow or block rule on an agent identity. New rules always start with status: "active" — to pause a rule use Update contact rule.
Path parameters
| Parameter | Type | Description |
|---|---|---|
agent_handle | string | The identity's handle |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | "allow" or "block" |
match_type | string | Yes | "exact_email" (full address) or "domain" (bare domain like gmail.com) |
match_target | string | Yes | Value to match against. For exact_email: a full address with one @ and at least one dot after it. For domain: a lowercase ASCII bare domain (no leading *@, no leading @, no trailing .). Max 320 chars. |
Request example
Response (201)
Returns the created rule. See Contact rule object.
Error responses
| Status | Description |
|---|---|
| 403 | Identity-scoped key addressed a different identity's handle |
| 404 | Identity not found, or not visible to the caller |
| 409 | rule_already_exists — a rule with the same (match_type, match_target) already exists on this identity; the response includes existing_rule_id |
| 422 | match_target invalid for the given match_type (e.g. glob pattern, non-ASCII domain, missing dot) |
Code examples
Get contact rule GET
GET /identities/{agent_handle}/mail-contact-rules/{rule_id}Fetch a single contact rule by ID.
Path parameters
| Parameter | Type | Description |
|---|---|---|
agent_handle | string | The identity's handle |
rule_id | UUID | Rule ID |
Response (200)
Returns the rule. See Contact rule object.
Error responses
| Status | Description |
|---|---|
| 403 | Identity-scoped key addressed a different identity's handle |
| 404 | Rule not found, or it belongs to a different identity |
Code examples
Update contact rule PATCH
PATCH /identities/{agent_handle}/mail-contact-rules/{rule_id}Change a rule's action or status. Requires an admin API key, or manage rules from the Inkbox Console.
match_type and match_target are immutable — delete the rule and create a new one to change the target.
Path parameters
| Parameter | Type | Description |
|---|---|---|
agent_handle | string | The identity's handle |
rule_id | UUID | Rule ID |
Request body
At least one field is required; fields you omit are left unchanged.
| Field | Type | Required | Description |
|---|---|---|---|
action | string | No | "allow" or "block" |
status | string | No | "active" or "paused" (only these two values are accepted on PATCH; use DELETE to remove a rule) |
Sending null for either field is a client error (422) — omit the field to leave it unchanged.
Request example
Response (200)
Returns the updated rule.
Error responses
| Status | Description |
|---|---|
| 403 | Caller is not admin-scoped |
| 404 | Rule not found, or it belongs to a different identity |
| 422 | Empty body, or a field explicitly set to null |
Code examples
Delete contact rule DELETE
DELETE /identities/{agent_handle}/mail-contact-rules/{rule_id}Delete a contact rule. Returns 204 No Content on success. Requires an admin API key, or manage rules from the Inkbox Console.
Path parameters
| Parameter | Type | Description |
|---|---|---|
agent_handle | string | The identity's handle |
rule_id | UUID | Rule ID |
Error responses
| Status | Description |
|---|---|
| 403 | Caller is not admin-scoped |
| 404 | Rule not found, or it belongs to a different identity |
Code examples
List org mail contact rules GET
GET /mail/contact-rulesOrg-wide aggregate list of mail contact rules across every identity the caller can see. Intended for admin dashboards that render rules org-wide without fanning out one per-identity request per identity. Requires an admin API key, or browse rules in the Inkbox Console.
Results are ordered created_at descending, with id as a stable tiebreaker so pagination stays consistent when rules from different identities share a microsecond.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
agent_identity_id | UUID | — | Narrow to one identity by ID; omit to list across every identity in the org |
action | string | — | Filter by "allow" or "block" |
match_type | string | — | Filter by "exact_email" or "domain" |
limit | integer | 50 | Max rules (1–200) |
offset | integer | 0 | Offset for pagination |
Response (200)
Returns an array of contact rule objects — same shape as the per-identity list.
Code examples
Contact rule object
| Field | Type | Description |
|---|---|---|
id | UUID | Unique rule identifier |
agent_identity_id | UUID | The identity this rule protects |
action | string | "allow" or "block" |
match_type | string | "exact_email" or "domain" |
match_target | string | Canonicalized match value |
status | string | "active" or "paused" |
created_at | string | Creation timestamp (ISO 8601) |
updated_at | string | Last-updated timestamp (ISO 8601) |
Additional resources
- Email guide — Filtering inbound mail — narrative walk-through of whitelist/blacklist semantics
- Manage identities — set
mail_filter_mode - iMessage contact rules — the per-identity equivalent for iMessage
- Phone contact rules — the phone-side equivalent for calls and texts