{"openapi":"3.1.0","info":{"title":"InboxCNX API","version":"0.1.0","description":"Read and act on your users’ mailboxes through one API: connect a mailbox, then query its messages and threads, act on messages and receive webhooks.\n\n**Preview.** The API is under active development. Endpoints and schemas may still change without a version bump.\n\n**Authentication.** Every `/v1/*` request carries `Authorization: Bearer <credential>`. The credential is either an Application API key (`icnx_…`, created in the dashboard, server-side only) or a grant token (`icnxg_…`, minted with `POST /v1/grants/{id}/token`, scoped to one mailbox).\n\n**Errors.** Every error response has the shape `{ \"error\": { \"code\": \"…\", \"message\": \"…\" } }`. Branch on `code`, not on `message`. A `429 rate_limited` comes with a `Retry-After` header.\n\n[OpenAPI spec (JSON)](https://api.inboxcnx.com/openapi.json)"},"servers":[{"url":"https://api.inboxcnx.com"}],"security":[{"apiKey":[]},{"grantToken":[]}],"tags":[{"name":"Identity","description":"Check which application and scopes a credential carries. The first call to make with a new key."},{"name":"Connections","description":"Connect an end user’s mailbox through the provider’s OAuth consent and list the connected mailboxes with their grants."},{"name":"Grants","description":"A grant is one end user’s access to one connected mailbox. Mint a grant token, set its profile, folders and labels or revoke it."},{"name":"Backfills","description":"Import the mail a grant’s mailbox held before it was connected: estimate the cost, start, follow and cancel a backfill, and list the running ones."},{"name":"Messages","description":"Read the stored mail of your grants, download attachments and raw sources, and change mail at the provider. In a Whitelabel application, mail is readable only with a grant token: an API key gets `403 grant_token_required`."},{"name":"Threads","description":"Read stored mail grouped into conversations. In a Whitelabel application, mail is readable only with a grant token: an API key gets `403 grant_token_required`."},{"name":"Application","description":"Settings of the calling application: folder filter, return URLs and pause."},{"name":"Profiles","description":"Profiles are the price packages of an application: retention and monthly limits. Every grant belongs to one."},{"name":"Status","description":"Integration health across the organization’s applications."},{"name":"Usage","description":"Billable usage per grant and month."},{"name":"Webhook Endpoints","description":"Register endpoints that receive signed webhook events, and inspect, count and replay their deliveries."}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An application API key, `icnx_…`. Created in the dashboard with the scopes the application needs. Server-side only: never ship it to a browser or an app."},"grantToken":{"type":"http","scheme":"bearer","description":"A grant token, `icnxg_…`, minted with `POST /v1/grants/{id}/token`. Valid for 5 minutes and confined to one end user’s mailbox. It carries only the mail scopes (`read:messages`, `modify:messages`, `delete:messages`, `report:spam`) its API key holds. In a Whitelabel application, mail is readable only with a grant token: an API key gets `403 grant_token_required`."}},"schemas":{"MessageReceivedEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["message.received"]},"data":{"type":"object","properties":{"message":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerMessageId":{"type":"string"},"providerThreadId":{"type":["string","null"]},"source":{"type":"string","enum":["gmail","m365","imap"]},"receivedAt":{"type":"string"},"sentAt":{"type":["string","null"]},"subject":{"type":["string","null"]},"from":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"sender":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"to":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"cc":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"bcc":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"replyTo":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"messageId":{"type":["array","null"],"items":{"type":"string"}},"inReplyTo":{"type":["array","null"],"items":{"type":"string"}},"references":{"type":["array","null"],"items":{"type":"string"}},"size":{"type":"integer","minimum":0},"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"language":{"type":["string","null"]},"preview":{"type":["string","null"],"maxLength":256},"hasAttachment":{"type":"boolean"},"body":{"type":"object","properties":{"text":{"type":["string","null"]},"html":{"type":["string","null"]}},"required":["text","html"]},"attachments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"contentType":{"type":["string","null"]},"size":{"type":["integer","null"],"minimum":0},"disposition":{"type":["string","null"]},"cid":{"type":["string","null"]},"downloadUrl":{"type":["string","null"]}},"required":["id","name","contentType","size","disposition","cid","downloadUrl"]}},"raw":{"type":"object","properties":{"downloadUrl":{"type":["string","null"]}},"required":["downloadUrl"]},"enrichment":{"type":["object","null"],"properties":{"application":{"type":"object","additionalProperties":{}}}},"lifecycle":{"type":"object","properties":{"providerReceivedAt":{"type":"string"},"detectedAt":{"type":["string","null"]},"fetchedAt":{"type":["string","null"]},"processedAt":{"type":["string","null"]},"storedAt":{"type":["string","null"]},"webhookEnqueuedAt":{"type":["string","null"]},"webhookDeliveredAt":{"type":["string","null"]}},"required":["providerReceivedAt","detectedAt","fetchedAt","processedAt","storedAt","webhookEnqueuedAt","webhookDeliveredAt"]},"stateAt":{"type":["string","null"]},"deletedAt":{"type":["string","null"]}},"required":["id","providerMessageId","providerThreadId","source","receivedAt","sentAt","subject","from","sender","to","cc","bcc","replyTo","messageId","inReplyTo","references","size","keywords","labels","language","preview","hasAttachment","body","attachments","raw","enrichment"]},"origin":{"type":"string","enum":["live","backfill","catch_up"]}},"required":["message"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"MessageUpdatedEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["message.updated"]},"data":{"type":"object","properties":{"message":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerMessageId":{"type":"string"},"providerThreadId":{"type":["string","null"]},"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"stateAt":{"type":"string"}},"required":["id","providerMessageId","providerThreadId","keywords","labels","stateAt"]},"previous":{"type":"object","properties":{"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]}}}},"required":["message","previous"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"MessageDeletedEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["message.deleted"]},"data":{"type":"object","properties":{"message":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerMessageId":{"type":"string"}},"required":["id","providerMessageId"]}},"required":["message"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"MessageEnrichResponse":{"type":"object","properties":{"enrichment":{"type":["object","null"],"additionalProperties":{},"description":"Stored on the mail as `enrichment.application`. A JSON object of at most 16 KB serialized and 8 levels deep. Keys `__proto__`, `constructor` and `prototype` are refused, as are strings and keys with `\\u0000` or invalid Unicode. Absent or `null`: nothing to add."}},"example":{"enrichment":{"crmId":"42","category":"support"}}},"MessageEnrichEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["message.enrich"]},"data":{"type":"object","properties":{"message":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerMessageId":{"type":"string"},"providerThreadId":{"type":["string","null"]},"source":{"type":"string","enum":["gmail","m365","imap"]},"receivedAt":{"type":"string"},"sentAt":{"type":["string","null"]},"subject":{"type":["string","null"]},"from":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"sender":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"to":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"cc":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"bcc":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"replyTo":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"messageId":{"type":["array","null"],"items":{"type":"string"}},"inReplyTo":{"type":["array","null"],"items":{"type":"string"}},"references":{"type":["array","null"],"items":{"type":"string"}},"size":{"type":"integer","minimum":0},"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"language":{"type":["string","null"]},"preview":{"type":["string","null"],"maxLength":256},"hasAttachment":{"type":"boolean"},"body":{"type":"object","properties":{"text":{"type":["string","null"]},"html":{"type":["string","null"]}},"required":["text","html"]},"attachments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"contentType":{"type":["string","null"]},"size":{"type":["integer","null"],"minimum":0},"disposition":{"type":["string","null"]},"cid":{"type":["string","null"]},"downloadUrl":{"type":["string","null"]}},"required":["id","name","contentType","size","disposition","cid","downloadUrl"]}},"raw":{"type":"object","properties":{"downloadUrl":{"type":["string","null"]}},"required":["downloadUrl"]},"enrichment":{"type":["object","null"],"properties":{"application":{"type":"object","additionalProperties":{}}}},"lifecycle":{"type":"object","properties":{"providerReceivedAt":{"type":"string"},"detectedAt":{"type":["string","null"]},"fetchedAt":{"type":["string","null"]},"processedAt":{"type":["string","null"]},"storedAt":{"type":["string","null"]},"webhookEnqueuedAt":{"type":["string","null"]},"webhookDeliveredAt":{"type":["string","null"]}},"required":["providerReceivedAt","detectedAt","fetchedAt","processedAt","storedAt","webhookEnqueuedAt","webhookDeliveredAt"]},"stateAt":{"type":["string","null"]},"deletedAt":{"type":["string","null"]}},"required":["id","providerMessageId","providerThreadId","source","receivedAt","sentAt","subject","from","sender","to","cc","bcc","replyTo","messageId","inReplyTo","references","size","keywords","labels","language","preview","hasAttachment","body","attachments","raw","enrichment"]}},"required":["message"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"UsagePeriodClosedEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["usage.period.closed"]},"data":{"type":"object","properties":{"period":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"applicationId":{"type":"string","format":"uuid"},"totals":{"type":"object","properties":{"activeGrantsPeak":{"type":"integer","minimum":0},"mails":{"type":"integer","minimum":0},"backfillMails":{"type":"integer","minimum":0},"gbMonths":{"type":"number","minimum":0}},"required":["activeGrantsPeak","mails","backfillMails","gbMonths"]}},"required":["period","applicationId","totals"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"GrantRevokedEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["grant.revoked"]},"data":{"type":"object","properties":{"revokedAt":{"type":"string"},"reason":{"type":"string","enum":["requested","connection_error_timeout"]}},"required":["revokedAt","reason"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"ConnectionErrorEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["connection.error"]},"data":{"type":"object","properties":{"connection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"provider":{"type":"string","enum":["gmail","m365","imap"]},"accountEmail":{"type":"string"}},"required":["id","provider","accountEmail"]},"reason":{"type":"string","enum":["reauth_required","mailbox_unavailable"]},"since":{"type":"string"}},"required":["connection","reason","since"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"ConnectionRestoredEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["connection.restored"]},"data":{"type":"object","properties":{"connection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"provider":{"type":"string","enum":["gmail","m365","imap"]},"accountEmail":{"type":"string"}},"required":["id","provider","accountEmail"]},"since":{"type":"string"},"restoredAt":{"type":"string"}},"required":["connection","since","restoredAt"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"GrantRevocationScheduledEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["grant.revocation_scheduled"]},"data":{"type":"object","properties":{"connection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"provider":{"type":"string","enum":["gmail","m365","imap"]},"accountEmail":{"type":"string"}},"required":["id","provider","accountEmail"]},"reason":{"type":"string","enum":["reauth_required","mailbox_unavailable"]},"since":{"type":"string"},"revokesAt":{"type":"string"}},"required":["connection","reason","since","revokesAt"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"GrantCapReachedEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["grant.cap_reached"]},"data":{"type":"object","properties":{"cap":{"type":"string","enum":["messages","storage"]},"limit":{"type":"integer"},"period":{"type":"string"},"profileKey":{"type":"string"}},"required":["cap","limit","period","profileKey"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"GrantCreatedEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["grant.created"]},"data":{"type":"object","properties":{"connection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"provider":{"type":"string","enum":["gmail","m365","imap"]},"accountEmail":{"type":"string"}},"required":["id","provider","accountEmail"]},"profileKey":{"type":"string"}},"required":["connection","profileKey"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"GrantBackfillCompletedEvent":{"type":"object","properties":{"id":{"type":"string","minLength":1},"createdAt":{"type":"string"},"applicationId":{"type":"string","format":"uuid"},"grantId":{"type":["string","null"],"format":"uuid"},"externalUserId":{"type":["string","null"]},"type":{"type":"string","enum":["grant.backfill_completed"]},"data":{"type":"object","properties":{"runId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["done","cancelled"]},"since":{"type":["string","null"]},"until":{"type":"string"},"listed":{"type":"integer","minimum":0},"published":{"type":"integer","minimum":0}},"required":["runId","status","since","until","listed","published"]}},"required":["id","createdAt","applicationId","grantId","externalUserId","type","data"]},"V1MeResponse":{"type":"object","properties":{"organizationId":{"type":"string"},"applicationId":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"grantId":{"type":"string"}},"required":["organizationId","applicationId","scopes"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]},"MessageSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerMessageId":{"type":"string"},"providerThreadId":{"type":["string","null"]},"source":{"type":"string","enum":["gmail","m365","imap"]},"receivedAt":{"type":"string"},"sentAt":{"type":["string","null"]},"subject":{"type":["string","null"]},"from":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"sender":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"to":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"cc":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"bcc":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"replyTo":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"messageId":{"type":["array","null"],"items":{"type":"string"}},"inReplyTo":{"type":["array","null"],"items":{"type":"string"}},"references":{"type":["array","null"],"items":{"type":"string"}},"size":{"type":"integer","minimum":0},"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"language":{"type":["string","null"]},"preview":{"type":["string","null"],"maxLength":256},"hasAttachment":{"type":"boolean"},"raw":{"type":"object","properties":{"downloadUrl":{"type":["string","null"]}},"required":["downloadUrl"]},"enrichment":{"type":["object","null"],"properties":{"application":{"type":"object","additionalProperties":{}}}},"stateAt":{"type":["string","null"]},"deletedAt":{"type":["string","null"]},"grantId":{"type":"string"}},"required":["id","providerMessageId","providerThreadId","source","receivedAt","sentAt","subject","from","sender","to","cc","bcc","replyTo","messageId","inReplyTo","references","size","keywords","labels","language","preview","hasAttachment","raw","enrichment","stateAt","deletedAt","grantId"]},"MessageFilterNode":{"anyOf":[{"type":"object","properties":{"operator":{"type":"string","enum":["AND","OR","NOT"],"description":"How to combine `conditions`. `AND` matches only if every condition matches; `OR` matches if any condition matches; `NOT` matches only if none of the conditions match."},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/MessageFilterNode"},"minItems":1,"description":"One or more further filter values to combine. Each entry is either a plain condition object or another operator node, so filters can be nested to build complex combinations (up to a maximum depth, see the endpoint description)."}},"required":["operator","conditions"]},{"type":"object","properties":{"q":{"type":"string","minLength":1,"description":"Full-text search across subject, body, and every address field (from/to/cc/bcc). Matches inflected word forms in the message's own language, not only the exact word typed.","example":"invoice"},"from":{"type":"string","description":"Exact sender address match (not a substring search). Matches only if this exact address appears in From.","example":"alice@example.com"},"to":{"type":"string","description":"Exact recipient address match (not a substring search). Matches only if this exact address appears in To.","example":"bob@example.com"},"after":{"type":"string","format":"date-time","description":"Only messages received at or after this instant (inclusive).","example":"2026-08-01T00:00:00Z"},"before":{"type":"string","format":"date-time","description":"Only messages received strictly before this instant.","example":"2026-09-01T00:00:00Z"},"minSize":{"type":["integer","null"],"minimum":0,"description":"Only messages whose total size in bytes is at least this value.","example":1024},"maxSize":{"type":["integer","null"],"minimum":0,"description":"Only messages whose total size in bytes is at most this value.","example":10485760},"hasAttachment":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"description":"Only messages that do (`true`) or do not (`false`) carry at least one attachment.","example":true},"keyword":{"type":"string","description":"Only messages carrying this JMAP keyword, e.g. `$flagged` or `$seen`.","example":"$flagged"},"notKeyword":{"type":"string","description":"Only messages that do NOT carry this JMAP keyword.","example":"$seen"},"label":{"type":"string","description":"Only messages carrying this label: either a system role (e.g. `inbox`, `sent`) or a source-specific custom label (e.g. a Gmail label).","example":"inbox"},"notLabel":{"type":"string","description":"Only messages that do NOT carry this label, e.g. `trash` to leave out trashed mail.","example":"trash"},"providerThreadId":{"type":"string","description":"Only messages belonging to this source provider's own thread id (Gmail/M365/IMAP thread id).","example":"18c9a2f1b3d4e5f6"},"threadId":{"type":"string","format":"uuid","description":"Only messages belonging to this InboxCNX thread id, as returned by `GET /v1/threads`."},"grantId":{"type":"string","format":"uuid","description":"Only messages ingested through this connection grant."},"payloadContains":{"type":"object","additionalProperties":{},"description":"Only messages whose source-specific `payload` object contains this shape. Every field given here must be present in `payload`, matching at any nesting depth; extra fields elsewhere in `payload` do not disqualify a match. This checks containment only: ranges (greater/less than, between) and substring matches against nested values are not supported.","example":{"sourceMeta":{"priority":"high"}}},"enrichmentContains":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"string"}],"description":"Only messages whose `enrichment` object contains this shape, e.g. `{\"application\": {\"crmId\": \"42\"}}` for what your enrichment endpoint returned. Same containment semantics as `payloadContains`. In a query string, pass it JSON-encoded.","example":{"application":{"crmId":"42"}}}}}],"description":"The filter tree to evaluate. Omit entirely to match every message the caller can see."},"Message":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerMessageId":{"type":"string"},"providerThreadId":{"type":["string","null"]},"source":{"type":"string","enum":["gmail","m365","imap"]},"receivedAt":{"type":"string"},"sentAt":{"type":["string","null"]},"subject":{"type":["string","null"]},"from":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"sender":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"to":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"cc":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"bcc":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"replyTo":{"type":["array","null"],"items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"messageId":{"type":["array","null"],"items":{"type":"string"}},"inReplyTo":{"type":["array","null"],"items":{"type":"string"}},"references":{"type":["array","null"],"items":{"type":"string"}},"size":{"type":"integer","minimum":0},"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"language":{"type":["string","null"]},"preview":{"type":["string","null"],"maxLength":256},"hasAttachment":{"type":"boolean"},"raw":{"type":"object","properties":{"downloadUrl":{"type":["string","null"]}},"required":["downloadUrl"]},"enrichment":{"type":["object","null"],"properties":{"application":{"type":"object","additionalProperties":{}}}},"stateAt":{"type":["string","null"]},"deletedAt":{"type":["string","null"]},"grantId":{"type":"string"},"body":{"type":"object","properties":{"text":{"type":["string","null"]},"html":{"type":["string","null"]}},"required":["text","html"]},"attachments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"contentType":{"type":["string","null"]},"size":{"type":["integer","null"]},"disposition":{"type":["string","null"]},"cid":{"type":["string","null"]},"downloadUrl":{"type":["string","null"]}},"required":["id","name","contentType","size","disposition","cid","downloadUrl"]}},"lifecycle":{"type":"object","properties":{"providerReceivedAt":{"type":"string"},"detectedAt":{"type":["string","null"]},"fetchedAt":{"type":["string","null"]},"processedAt":{"type":["string","null"]},"storedAt":{"type":["string","null"]},"webhookEnqueuedAt":{"type":["string","null"]},"webhookDeliveredAt":{"type":["string","null"]}},"required":["providerReceivedAt","detectedAt","fetchedAt","processedAt","storedAt","webhookEnqueuedAt","webhookDeliveredAt"]}},"required":["id","providerMessageId","providerThreadId","source","receivedAt","sentAt","subject","from","sender","to","cc","bcc","replyTo","messageId","inReplyTo","references","size","keywords","labels","language","preview","hasAttachment","raw","enrichment","stateAt","deletedAt","grantId","body","attachments","lifecycle"]},"MessageState":{"type":"object","properties":{"id":{"type":"string"},"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"stateAt":{"type":["string","null"]}},"required":["id","keywords","labels","stateAt"]},"ThreadFilterNode":{"anyOf":[{"type":"object","properties":{"operator":{"type":"string","enum":["AND","OR","NOT"],"description":"How to combine `conditions`. `AND` matches only if every condition matches; `OR` matches if any condition matches; `NOT` matches only if none of the conditions match."},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/ThreadFilterNode"},"minItems":1,"description":"One or more further filter values to combine. Each entry is either a plain condition object or another operator node, so filters can be nested to build complex combinations (up to a maximum depth, see the endpoint description)."}},"required":["operator","conditions"]},{"type":"object","properties":{"participant":{"type":"string","description":"Only threads with this exact address among their participants (senders and recipients).","example":"alice@example.com"},"hasAttachment":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"description":"Only threads that do (`true`) or do not (`false`) contain at least one message with an attachment.","example":true},"source":{"type":"string","enum":["gmail","m365","imap"],"description":"Only threads from this mail provider.","example":"gmail"},"providerThreadId":{"type":"string","description":"Only the thread matching this source provider's own thread id (Gmail/M365/IMAP thread id).","example":"18c9a2f1b3d4e5f6"},"after":{"type":"string","format":"date-time","description":"Only threads whose most recent message was received at or after this instant (inclusive).","example":"2026-08-01T00:00:00Z"},"before":{"type":"string","format":"date-time","description":"Only threads whose most recent message was received strictly before this instant.","example":"2026-09-01T00:00:00Z"},"grantId":{"type":"string","format":"uuid","description":"Only threads ingested through this connection grant."},"label":{"type":"string","description":"Only threads in which at least one message carries this label (a system role or a custom label).","example":"inbox"},"notLabel":{"type":"string","description":"Only threads in which at least one message does NOT carry this label. `notLabel=trash` leaves out threads whose every message is in the trash.","example":"trash"}}}],"description":"The filter to evaluate. Omit entirely to match every thread the caller can see."}},"parameters":{}},"paths":{"/v1/me":{"get":{"operationId":"getMe","tags":["Identity"],"summary":"Get the current credential","description":"Returns the organization, application and scopes of the credential that makes the call, so you can check a new key or token before using it. A grant token also returns its `grantId`.\n\nNo scope required.","responses":{"200":{"description":"The calling credential’s organization, application and scopes","content":{"application/json":{"example":{"organizationId":"0f6b2c1e-8d4a-4e7b-9c3f-2a1b0c9d8e7f","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","scopes":["read:messages","write:webhooks"]},"schema":{"$ref":"#/components/schemas/V1MeResponse"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/connections":{"get":{"operationId":"listConnections","tags":["Connections"],"summary":"List connected mailboxes","description":"Lists the connected mailboxes with the caller’s grants on each, newest first, so you can see which mailbox is healthy and which end user has to reconnect. Keyset pagination.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","enum":["initiated","active","error","deleted"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["gmail","m365","imap"]},"required":false,"name":"provider","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"externalUserId","in":"query"},{"schema":{"type":"string","description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another."},"required":false,"description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another.","name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Page size, between 1 and 200. Default 50."},"required":false,"description":"Page size, between 1 and 200. Default 50.","name":"limit","in":"query"},{"schema":{"type":"string","enum":["total"],"description":"`total` adds the number of matching results, counted up to 10000."},"required":false,"description":"`total` adds the number of matching results, counted up to 10000.","name":"include","in":"query"}],"responses":{"200":{"description":"A page of connections, each with the caller’s grants nested","content":{"application/json":{"example":{"data":[{"id":"5e8d2a10-3c4b-4f6e-9a7d-1b2c3d4e5f60","provider":"gmail","accountEmail":"owner@example.com","syncStatus":"active","health":{"state":"ok","reason":null,"since":null},"missingAccess":[],"lastSyncedAt":"2026-10-23T07:58:12.000Z","createdAt":"2026-10-01T06:00:00.000Z","grants":[{"id":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","status":"active","externalUserId":"crm-user-42","paused":false,"blocked":false,"subscribedRoles":null,"subscribedLabels":[],"effectiveRoles":["inbox","sent"],"createdAt":"2026-10-01T06:00:00.000Z"}]}],"nextCursor":null,"prevCursor":null},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"provider":{"type":"string","enum":["gmail","m365","imap"]},"accountEmail":{"type":"string"},"syncStatus":{"type":"string","enum":["initiated","active","error","deleted"]},"health":{"type":["object","null"],"properties":{"state":{"type":"string","enum":["ok","degraded","down","error"]},"reason":{"type":["string","null"],"enum":["reauth_required","mailbox_unavailable","subscription_expiring","subscription_expired",null]},"since":{"type":["string","null"]}},"required":["state","reason","since"],"description":"`ok`, or what is wrong: `error` needs the mailbox owner (`reauth_required`: connect it again through `POST /v1/connections/initiate`; `mailbox_unavailable`: the mail provider refuses access, e.g. mail is disabled for the account), `down` and `degraded` are ours to fix. `since` is when the state began, where known. Null for a deleted connection, and for one whose grants are all revoked: it is no longer read for this application."},"missingAccess":{"type":"array","items":{"type":"string","enum":["change_mail","send_mail"]},"description":"What this application asks of a mailbox beyond reading that the end user has not consented to: `change_mail` (flags, labels, moves), `send_mail`. The mailbox was connected before the access was requested, or the end user left it out at consent. Reading is unaffected. Connect it again through `POST /v1/connections/initiate` to ask for it. Empty when the consent is current, and for a connection this application no longer reads."},"lastSyncedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"grants":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","active","revoked"]},"externalUserId":{"type":["string","null"]},"paused":{"type":"boolean"},"blocked":{"type":"boolean"},"subscribedRoles":{"type":["array","null"],"items":{"type":"string"},"description":"The grant’s own folders, or `null` when it follows the application’s."},"subscribedLabels":{"type":"array","items":{"type":"string"}},"effectiveRoles":{"type":"array","items":{"type":"string"},"description":"The folders that apply: `subscribedRoles`, else the application’s."},"createdAt":{"type":"string"}},"required":["id","status","externalUserId","paused","blocked","subscribedRoles","subscribedLabels","effectiveRoles","createdAt"]}}},"required":["id","provider","accountEmail","syncStatus","health","missingAccess","lastSyncedAt","createdAt","grants"]}},"nextCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the next page. Null on the last page."},"prevCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the previous page. Null on the first page."},"total":{"type":"object","properties":{"count":{"type":"integer","minimum":0},"exact":{"type":"boolean"}},"required":["count","exact"],"description":"Present only when requested with `include`. `exact` is false once the count reaches 10000 (or the depth cap of a relevance search); `count` is then that cap."}},"required":["data","nextCursor","prevCursor"]}}}},"400":{"description":"Invalid query or malformed cursor","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/webhook-event-types":{"get":{"operationId":"listWebhookEventTypes","tags":["Webhook Endpoints"],"summary":"List webhook event types","description":"Lists every event type a webhook endpoint can subscribe to, with what it means, so a client never keeps its own copy of the catalogue.\n\nRequires the `write:webhooks` scope.","security":[{"apiKey":[]}],"responses":{"200":{"description":"The catalogue, one entry per type","content":{"application/json":{"example":{"data":[{"type":"message.deleted","description":"The provider deleted a delivered mail."}]},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"description":{"type":"string"}},"required":["type","description"]}}},"required":["data"]}}}},"403":{"description":"The credential lacks the `write:webhooks` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/webhook-endpoints":{"post":{"operationId":"createWebhookEndpoint","tags":["Webhook Endpoints"],"summary":"Create a webhook endpoint","description":"Adds a URL that receives the subscribed webhook events of the caller application, signed with a secret returned only in this response. An application has at most 10 endpoints, and at most one of them subscribes to `message.enrich`. Events of a newly subscribed type that no endpoint has received yet, from the last 7 days, are delivered at once.\n\nRequires the `write:webhooks` scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"example":{"url":"https://hooks.example.com/inboxcnx","events":["message.received","grant.created"],"description":"Production receiver"},"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["message.received","message.updated","message.deleted","message.enrich","connection.error","connection.restored","grant.created","grant.cap_reached","grant.backfill_completed","grant.revocation_scheduled","grant.revoked","usage.period.closed"]},"minItems":1},"description":{"type":["string","null"],"maxLength":200}},"required":["url","events"]}}}},"responses":{"201":{"description":"The endpoint, with its signing secret (returned only here)","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","description","events","createdAt","updatedAt"]}}}},"400":{"description":"Invalid body, or `invalid_webhook_target`: the URL must be `https` and must not point at a private address or an internal hostname","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:webhooks` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"The caller’s application no longer exists","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"The endpoint limit is reached, another endpoint already takes `message.enrich`, or the organization is still being set up; retry in a few minutes","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"get":{"operationId":"listWebhookEndpoints","tags":["Webhook Endpoints"],"summary":"List webhook endpoints","description":"Lists the caller application’s webhook endpoints, oldest first, with the per-application limit. Signing secrets are never returned.\n\nRequires the `write:webhooks` scope.","security":[{"apiKey":[]}],"responses":{"200":{"description":"The live endpoints, oldest first, and the per-application limit","content":{"application/json":{"example":{"data":[{"id":"3f9a1c7e-2b4d-4e8f-a6c0-9d1e2f3a4b5c","url":"https://hooks.example.com/inboxcnx","description":"Production receiver","events":["message.received","grant.created"],"createdAt":"2026-10-20T09:15:00.000Z","updatedAt":"2026-10-20T09:15:00.000Z"}],"limit":10},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","description","events","createdAt","updatedAt"]}},"limit":{"type":"integer"}},"required":["data","limit"]}}}},"403":{"description":"The credential lacks the `write:webhooks` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/webhook-endpoints/{id}":{"get":{"operationId":"getWebhookEndpoint","tags":["Webhook Endpoints"],"summary":"Get a webhook endpoint","description":"Returns one webhook endpoint of the caller application with its URL and subscribed events. The signing secret is never returned.\n\nRequires the `write:webhooks` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The endpoint","content":{"application/json":{"example":{"id":"3f9a1c7e-2b4d-4e8f-a6c0-9d1e2f3a4b5c","url":"https://hooks.example.com/inboxcnx","description":"Production receiver","events":["message.received","grant.created"],"createdAt":"2026-10-20T09:15:00.000Z","updatedAt":"2026-10-20T09:15:00.000Z"},"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","description","events","createdAt","updatedAt"]}}}},"403":{"description":"The credential lacks the `write:webhooks` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such endpoint for the caller’s application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"operationId":"updateWebhookEndpoint","tags":["Webhook Endpoints"],"summary":"Update a webhook endpoint","description":"Changes a webhook endpoint’s URL, subscribed events or description. Removing an event type cancels the endpoint’s open deliveries of that type. Adding one delivers the events of that type that no endpoint has received yet, from the last 7 days, at once.\n\nRequires the `write:webhooks` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"example":{"events":["message.received","message.updated","grant.created"]},"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["message.received","message.updated","message.deleted","message.enrich","connection.error","connection.restored","grant.created","grant.cap_reached","grant.backfill_completed","grant.revocation_scheduled","grant.revoked","usage.period.closed"]},"minItems":1},"description":{"type":["string","null"],"maxLength":200}}}}}},"responses":{"200":{"description":"The updated endpoint","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","description","events","createdAt","updatedAt"]}}}},"400":{"description":"Invalid body, or `invalid_webhook_target`: the URL must be `https` and must not point at a private address or an internal hostname","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:webhooks` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such endpoint for the caller’s application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Another endpoint already takes `message.enrich`","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"operationId":"deleteWebhookEndpoint","tags":["Webhook Endpoints"],"summary":"Delete a webhook endpoint","description":"Deletes a webhook endpoint so it receives no further events. Its open deliveries are cancelled.\n\nRequires the `write:webhooks` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Deleted"},"403":{"description":"The credential lacks the `write:webhooks` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such endpoint for the caller’s application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/webhook-endpoints/{id}/rotate-secret":{"post":{"operationId":"rotateWebhookSecret","tags":["Webhook Endpoints"],"summary":"Rotate a webhook secret","description":"Replaces a webhook endpoint’s signing secret, for a leaked secret or a scheduled rotation. Returns the new secret once. The body is optional: `{ \"gracePeriodHours\": 0..168 }`, default 24. During the grace period every request carries two signatures, one per secret, so a receiver can switch without losing a request. `0` replaces the secret at once. Rotating again ends the earlier grace period.\n\nRequires the `write:webhooks` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The endpoint, with its new signing secret (returned only here)","content":{"application/json":{"example":{"id":"3f9a1c7e-2b4d-4e8f-a6c0-9d1e2f3a4b5c","url":"https://hooks.example.com/inboxcnx","description":"Production receiver","events":["message.received","grant.created"],"createdAt":"2026-10-20T09:15:00.000Z","updatedAt":"2026-10-23T08:00:00.000Z","secret":"whsec_<shown once, store it now>"},"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","description","events","createdAt","updatedAt"]}}}},"400":{"description":"`gracePeriodHours` out of range","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:webhooks` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such endpoint for the caller’s application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`tenant_key_pending`: the organization is still being set up; retry in a few minutes","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/deliveries":{"get":{"operationId":"listDeliveries","tags":["Webhook Endpoints"],"summary":"List webhook deliveries","description":"Lists the webhook deliveries of the caller application, newest first, so you can see what reached each endpoint and why a delivery failed. Filter by status, endpoint, event id and creation time. Keyset pagination. A grant token sees the deliveries of its own grant.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","enum":["pending","failed","success","dlq","cancelled"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"endpointId","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"eventId","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"before","in":"query"},{"schema":{"type":"string","description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another."},"required":false,"description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another.","name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Page size, between 1 and 200. Default 50."},"required":false,"description":"Page size, between 1 and 200. Default 50.","name":"limit","in":"query"},{"schema":{"type":"string","enum":["total"],"description":"`total` adds the number of matching results, counted up to 10000."},"required":false,"description":"`total` adds the number of matching results, counted up to 10000.","name":"include","in":"query"}],"responses":{"200":{"description":"A page of deliveries","content":{"application/json":{"example":{"data":[{"id":"6d4e2f1a-9b8c-4d7e-a5f6-0c1b2a3d4e5f","endpointId":"3f9a1c7e-2b4d-4e8f-a6c0-9d1e2f3a4b5c","eventId":"grant.created:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","eventType":"grant.created","status":"failed","targetUrl":"https://hooks.example.com/inboxcnx","attemptCount":2,"responseStatus":503,"lastError":"HTTP 503","createdAt":"2026-10-23T08:00:00.000Z","updatedAt":"2026-10-23T08:00:31.000Z","deliveredAt":null,"nextAttemptAt":"2026-10-23T08:02:31.000Z"}],"nextCursor":null,"prevCursor":null},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"endpointId":{"type":"string"},"eventId":{"type":"string"},"eventType":{"type":"string"},"status":{"type":"string","enum":["pending","failed","success","dlq","cancelled"]},"targetUrl":{"type":["string","null"]},"attemptCount":{"type":"integer"},"responseStatus":{"type":["integer","null"]},"lastError":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"deliveredAt":{"type":["string","null"]},"nextAttemptAt":{"type":["string","null"]}},"required":["id","endpointId","eventId","eventType","status","targetUrl","attemptCount","responseStatus","lastError","createdAt","updatedAt","deliveredAt","nextAttemptAt"]}},"nextCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the next page. Null on the last page."},"prevCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the previous page. Null on the first page."},"total":{"type":"object","properties":{"count":{"type":"integer","minimum":0},"exact":{"type":"boolean"}},"required":["count","exact"],"description":"Present only when requested with `include`. `exact` is false once the count reaches 10000 (or the depth cap of a relevance search); `count` is then that cap."}},"required":["data","nextCursor","prevCursor"]}}}},"400":{"description":"Invalid query or malformed cursor","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/deliveries/stats":{"get":{"operationId":"getDeliveryStats","tags":["Webhook Endpoints"],"summary":"Get delivery statistics","description":"Counts webhook deliveries by status over time, per endpoint and per event type, with delivery latency, to chart how well your receivers keep up. Counts the deliveries created in `[after, before)`, by default the last seven days and at most 92 days, optionally of one status or endpoint. The series is hourly up to two days and daily beyond.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","format":"date-time"},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"before","in":"query"},{"schema":{"type":"string","enum":["pending","failed","success","dlq","cancelled"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"endpointId","in":"query"}],"responses":{"200":{"description":"Delivery counts for the range","content":{"application/json":{"example":{"after":"2026-10-22T08:00:00.000Z","before":"2026-10-23T08:00:00.000Z","bucket":"hour","totals":{"total":120,"pending":1,"failed":2,"success":116,"dlq":1,"cancelled":0},"latency":{"p50Ms":180,"p95Ms":950},"series":[{"start":"2026-10-22T08:00:00.000Z","total":5,"pending":0,"failed":0,"success":5,"dlq":0,"cancelled":0}],"byEndpoint":[{"endpointId":"3f9a1c7e-2b4d-4e8f-a6c0-9d1e2f3a4b5c","url":"https://hooks.example.com/inboxcnx","deleted":false,"latency":{"p50Ms":180,"p95Ms":950},"total":120,"pending":1,"failed":2,"success":116,"dlq":1,"cancelled":0}],"byEventType":[{"eventType":"message.received","total":120,"pending":1,"failed":2,"success":116,"dlq":1,"cancelled":0}],"endpoints":[{"endpointId":"3f9a1c7e-2b4d-4e8f-a6c0-9d1e2f3a4b5c","url":"https://hooks.example.com/inboxcnx","deleted":false}]},"schema":{"type":"object","properties":{"after":{"type":"string"},"before":{"type":"string"},"bucket":{"type":"string","enum":["hour","day"]},"totals":{"type":"object","properties":{"total":{"type":"integer"},"pending":{"type":"integer"},"failed":{"type":"integer"},"success":{"type":"integer"},"dlq":{"type":"integer"},"cancelled":{"type":"integer"}},"required":["total","pending","failed","success","dlq","cancelled"]},"latency":{"type":["object","null"],"properties":{"p50Ms":{"type":"number"},"p95Ms":{"type":"number"}},"required":["p50Ms","p95Ms"]},"series":{"type":"array","items":{"type":"object","properties":{"total":{"type":"integer"},"pending":{"type":"integer"},"failed":{"type":"integer"},"success":{"type":"integer"},"dlq":{"type":"integer"},"cancelled":{"type":"integer"},"start":{"type":"string"}},"required":["total","pending","failed","success","dlq","cancelled","start"]}},"byEndpoint":{"type":"array","items":{"type":"object","properties":{"total":{"type":"integer"},"pending":{"type":"integer"},"failed":{"type":"integer"},"success":{"type":"integer"},"dlq":{"type":"integer"},"cancelled":{"type":"integer"},"endpointId":{"type":"string"},"url":{"type":"string"},"deleted":{"type":"boolean"},"latency":{"type":["object","null"],"properties":{"p50Ms":{"type":"number"},"p95Ms":{"type":"number"}},"required":["p50Ms","p95Ms"]}},"required":["total","pending","failed","success","dlq","cancelled","endpointId","url","deleted","latency"]}},"byEventType":{"type":"array","items":{"type":"object","properties":{"total":{"type":"integer"},"pending":{"type":"integer"},"failed":{"type":"integer"},"success":{"type":"integer"},"dlq":{"type":"integer"},"cancelled":{"type":"integer"},"eventType":{"type":"string"}},"required":["total","pending","failed","success","dlq","cancelled","eventType"]}},"endpoints":{"type":"array","items":{"type":"object","properties":{"endpointId":{"type":"string"},"url":{"type":"string"},"deleted":{"type":"boolean"}},"required":["endpointId","url","deleted"]}}},"required":["after","before","bucket","totals","latency","series","byEndpoint","byEventType","endpoints"]}}}},"400":{"description":"A reversed range, or one longer than the maximum","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/deliveries/{id}/replay":{"post":{"operationId":"replayDelivery","tags":["Webhook Endpoints"],"summary":"Replay a delivery","description":"Queues a dead-lettered or cancelled delivery again, to resend an event once the receiver is fixed. The endpoint must still be live and subscribed to the event type. A `message.enrich` call cannot be replayed.\n\nRequires the `write:webhooks` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The delivery is queued again and attempted within about a minute","content":{"application/json":{"example":{"id":"6d4e2f1a-9b8c-4d7e-a5f6-0c1b2a3d4e5f","status":"pending"},"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","failed","success","dlq","cancelled"]}},"required":["id","status"]}}}},"403":{"description":"The credential lacks the `write:webhooks` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such delivery for the caller’s organization; the delivery history is kept for 30 days","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Only a `dlq` or `cancelled` delivery can be replayed, never a `message.enrich` call, and only to a live endpoint still subscribed to its event type","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"410":{"description":"The event’s payload is deleted: once every delivery of the event has ended, or 7 days after the event","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/application":{"patch":{"operationId":"updateApplication","tags":["Application"],"summary":"Update the application","description":"Changes the caller application’s folder filter, the return URLs of the connect flow, or pauses processing for all its grants. A changed folder filter applies to new mail only and backfills nothing. While paused, mail that arrives is skipped, not queued.\n\nRequires the `write:application` scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"example":{"subscribedRoles":["inbox","sent"],"returnUrls":["https://app.example.com/inbox/connected"]},"schema":{"type":"object","properties":{"subscribedRoles":{"type":"array","items":{"type":"string","enum":["inbox","sent","archive","drafts","junk","trash"]},"minItems":1},"paused":{"type":"boolean"},"returnUrls":{"type":"array","items":{"type":"string","maxLength":2048},"maxItems":10,"description":"Replaces the URLs `POST /v1/connections/initiate` accepts as `returnUrl`. Each must use https (http only on localhost) and carry no query or fragment; at most 10."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The updated application","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["direct","whitelabel"]},"defaultRetentionDays":{"type":"number"},"subscribedRoles":{"type":"array","items":{"type":"string"}},"returnUrls":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"terminatedAt":{"type":["string","null"]},"paused":{"type":"boolean"},"blocked":{"type":"boolean"}},"required":["id","name","mode","defaultRetentionDays","subscribedRoles","returnUrls","createdAt","updatedAt","terminatedAt","paused","blocked"]}}}},"400":{"description":"Invalid body","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:application` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"The caller’s application no longer exists","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"The application is terminated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/profiles":{"get":{"operationId":"listProfiles","tags":["Profiles"],"summary":"List profiles","description":"Lists the caller application’s profiles, the default first, with their retention, monthly limits and grant count.\n\nRequires the `write:application` scope.","security":[{"apiKey":[]}],"responses":{"200":{"description":"The profiles","content":{"application/json":{"example":{"data":[{"key":"pro","retentionDays":90,"deletedRetentionDays":7,"maxMessagesPerMonth":10000,"maxStoredBytesPerMonth":5368709120,"isDefault":false,"archivedAt":null,"grantCount":12,"createdAt":"2026-10-01T10:00:00.000Z","updatedAt":"2026-10-01T10:00:00.000Z"}]},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"retentionDays":{"type":"integer","minimum":0,"maximum":36500},"deletedRetentionDays":{"type":["integer","null"],"minimum":0,"maximum":36500},"maxMessagesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":2147483647},"maxStoredBytesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":9007199254740991},"isDefault":{"type":"boolean"},"archivedAt":{"type":["string","null"]},"grantCount":{"type":"integer"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["key","retentionDays","deletedRetentionDays","maxMessagesPerMonth","maxStoredBytesPerMonth","isDefault","archivedAt","grantCount","createdAt","updatedAt"]}}},"required":["data"]}}}},"403":{"description":"The credential lacks the `write:application` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"operationId":"createProfile","tags":["Profiles"],"summary":"Create a profile","description":"Creates a profile, a price package of the application that sets how long mail is stored and how much a grant may receive per month. The `key` is the name your code uses to assign grants to it.\n\nRequires the `write:application` scope.","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"example":{"key":"pro","retentionDays":90,"deletedRetentionDays":7,"maxMessagesPerMonth":10000,"maxStoredBytesPerMonth":5368709120},"schema":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"retentionDays":{"type":"integer","minimum":0,"maximum":36500},"deletedRetentionDays":{"type":["integer","null"],"minimum":0,"maximum":36500},"maxMessagesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":2147483647},"maxStoredBytesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":9007199254740991},"isDefault":{"type":"boolean"}},"required":["key"]}}}},"responses":{"201":{"description":"The created profile","content":{"application/json":{"example":{"key":"pro","retentionDays":90,"deletedRetentionDays":7,"maxMessagesPerMonth":10000,"maxStoredBytesPerMonth":5368709120,"isDefault":false,"archivedAt":null,"grantCount":12,"createdAt":"2026-10-01T10:00:00.000Z","updatedAt":"2026-10-01T10:00:00.000Z"},"schema":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"retentionDays":{"type":"integer","minimum":0,"maximum":36500},"deletedRetentionDays":{"type":["integer","null"],"minimum":0,"maximum":36500},"maxMessagesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":2147483647},"maxStoredBytesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":9007199254740991},"isDefault":{"type":"boolean"},"archivedAt":{"type":["string","null"]},"grantCount":{"type":"integer"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["key","retentionDays","deletedRetentionDays","maxMessagesPerMonth","maxStoredBytesPerMonth","isDefault","archivedAt","grantCount","createdAt","updatedAt"]}}}},"400":{"description":"Invalid body","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:application` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"The key is taken","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/profiles/{key}":{"get":{"operationId":"getProfile","tags":["Profiles"],"summary":"Get a profile","description":"Returns one profile by its key, with its retention, monthly limits and the number of grants on it.\n\nRequires the `write:application` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"required":true,"name":"key","in":"path"}],"responses":{"200":{"description":"The profile","content":{"application/json":{"example":{"key":"pro","retentionDays":90,"deletedRetentionDays":7,"maxMessagesPerMonth":10000,"maxStoredBytesPerMonth":5368709120,"isDefault":false,"archivedAt":null,"grantCount":12,"createdAt":"2026-10-01T10:00:00.000Z","updatedAt":"2026-10-01T10:00:00.000Z"},"schema":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"retentionDays":{"type":"integer","minimum":0,"maximum":36500},"deletedRetentionDays":{"type":["integer","null"],"minimum":0,"maximum":36500},"maxMessagesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":2147483647},"maxStoredBytesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":9007199254740991},"isDefault":{"type":"boolean"},"archivedAt":{"type":["string","null"]},"grantCount":{"type":"integer"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["key","retentionDays","deletedRetentionDays","maxMessagesPerMonth","maxStoredBytesPerMonth","isDefault","archivedAt","grantCount","createdAt","updatedAt"]}}}},"403":{"description":"The credential lacks the `write:application` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such profile","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"operationId":"updateProfile","tags":["Profiles"],"summary":"Update a profile","description":"Changes a profile’s retention or monthly limits, archives it, or makes it the default for new grants. Lowering `retentionDays` or `deletedRetentionDays` deletes the stored mail of every grant on the profile past the new value, once a 7-day hold has passed: raising it again within the hold deletes nothing. `retentionDays` can rise only up to the retention every grant on the profile consented to. The monthly limits can change at any time and apply to each grant separately. The default profile cannot be archived.\n\nRequires the `write:application` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"required":true,"name":"key","in":"path"}],"requestBody":{"content":{"application/json":{"example":{"retentionDays":30,"maxMessagesPerMonth":null},"schema":{"type":"object","properties":{"retentionDays":{"type":"integer","minimum":0,"maximum":36500},"deletedRetentionDays":{"type":["integer","null"],"minimum":0,"maximum":36500},"maxMessagesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":2147483647},"maxStoredBytesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":9007199254740991},"archived":{"type":"boolean"},"isDefault":{"type":"boolean","enum":[true]}}}}}},"responses":{"200":{"description":"The updated profile","content":{"application/json":{"example":{"key":"pro","retentionDays":90,"deletedRetentionDays":7,"maxMessagesPerMonth":10000,"maxStoredBytesPerMonth":5368709120,"isDefault":false,"archivedAt":null,"grantCount":12,"createdAt":"2026-10-01T10:00:00.000Z","updatedAt":"2026-10-01T10:00:00.000Z"},"schema":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"retentionDays":{"type":"integer","minimum":0,"maximum":36500},"deletedRetentionDays":{"type":["integer","null"],"minimum":0,"maximum":36500},"maxMessagesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":2147483647},"maxStoredBytesPerMonth":{"type":["integer","null"],"exclusiveMinimum":0,"maximum":9007199254740991},"isDefault":{"type":"boolean"},"archivedAt":{"type":["string","null"]},"grantCount":{"type":"integer"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["key","retentionDays","deletedRetentionDays","maxMessagesPerMonth","maxStoredBytesPerMonth","isDefault","archivedAt","grantCount","createdAt","updatedAt"]}}}},"400":{"description":"Invalid body","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:application` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such profile","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"The retention exceeds a grant’s consent, the default cannot be archived, or an archived profile cannot become the default","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"operationId":"deleteProfile","tags":["Profiles"],"summary":"Delete a profile","description":"Deletes a profile that no grant references. The default profile cannot be deleted; archive a profile that grants still use.\n\nRequires the `write:application` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"required":true,"name":"key","in":"path"}],"responses":{"204":{"description":"Deleted"},"403":{"description":"The credential lacks the `write:application` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such profile","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"The profile is the default or is referenced by grants","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages":{"get":{"operationId":"listMessages","tags":["Messages"],"summary":"List messages","description":"Lists the stored mail of your grants, newest first, filtered by sender, date, folder, search text and more. Returns messages matching every given query parameter (all parameters are combined with AND). Omit every parameter to list all messages the caller can see.\n\nResults are paginated: pass the previous response's `nextCursor` or `prevCursor` back as `cursor` to fetch the next or previous page; `null` means there is none. `include=total` adds the number of matches. See the pagination guide.\n\nTo combine filters with OR or NOT, or to nest conditions, use `POST /v1/messages/query` instead: it accepts the same fields inside a filter tree.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","minLength":1,"description":"Full-text search across subject, body, and every address field (from/to/cc/bcc). Matches inflected word forms in the message's own language, not only the exact word typed.","example":"invoice"},"required":false,"description":"Full-text search across subject, body, and every address field (from/to/cc/bcc). Matches inflected word forms in the message's own language, not only the exact word typed.","name":"q","in":"query"},{"schema":{"type":"string","description":"Exact sender address match (not a substring search). Matches only if this exact address appears in From.","example":"alice@example.com"},"required":false,"description":"Exact sender address match (not a substring search). Matches only if this exact address appears in From.","name":"from","in":"query"},{"schema":{"type":"string","description":"Exact recipient address match (not a substring search). Matches only if this exact address appears in To.","example":"bob@example.com"},"required":false,"description":"Exact recipient address match (not a substring search). Matches only if this exact address appears in To.","name":"to","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Only messages received at or after this instant (inclusive).","example":"2026-08-01T00:00:00Z"},"required":false,"description":"Only messages received at or after this instant (inclusive).","name":"after","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Only messages received strictly before this instant.","example":"2026-09-01T00:00:00Z"},"required":false,"description":"Only messages received strictly before this instant.","name":"before","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"description":"Only messages whose total size in bytes is at least this value.","example":1024},"required":false,"description":"Only messages whose total size in bytes is at least this value.","name":"minSize","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"description":"Only messages whose total size in bytes is at most this value.","example":10485760},"required":false,"description":"Only messages whose total size in bytes is at most this value.","name":"maxSize","in":"query"},{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"description":"Only messages that do (`true`) or do not (`false`) carry at least one attachment.","example":true},"required":false,"description":"Only messages that do (`true`) or do not (`false`) carry at least one attachment.","name":"hasAttachment","in":"query"},{"schema":{"type":"string","description":"Only messages carrying this JMAP keyword, e.g. `$flagged` or `$seen`.","example":"$flagged"},"required":false,"description":"Only messages carrying this JMAP keyword, e.g. `$flagged` or `$seen`.","name":"keyword","in":"query"},{"schema":{"type":"string","description":"Only messages that do NOT carry this JMAP keyword.","example":"$seen"},"required":false,"description":"Only messages that do NOT carry this JMAP keyword.","name":"notKeyword","in":"query"},{"schema":{"type":"string","description":"Only messages carrying this label: either a system role (e.g. `inbox`, `sent`) or a source-specific custom label (e.g. a Gmail label).","example":"inbox"},"required":false,"description":"Only messages carrying this label: either a system role (e.g. `inbox`, `sent`) or a source-specific custom label (e.g. a Gmail label).","name":"label","in":"query"},{"schema":{"type":"string","description":"Only messages that do NOT carry this label, e.g. `trash` to leave out trashed mail.","example":"trash"},"required":false,"description":"Only messages that do NOT carry this label, e.g. `trash` to leave out trashed mail.","name":"notLabel","in":"query"},{"schema":{"type":"string","description":"Only messages belonging to this source provider's own thread id (Gmail/M365/IMAP thread id).","example":"18c9a2f1b3d4e5f6"},"required":false,"description":"Only messages belonging to this source provider's own thread id (Gmail/M365/IMAP thread id).","name":"providerThreadId","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Only messages belonging to this InboxCNX thread id, as returned by `GET /v1/threads`."},"required":false,"description":"Only messages belonging to this InboxCNX thread id, as returned by `GET /v1/threads`.","name":"threadId","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Only messages ingested through this connection grant."},"required":false,"description":"Only messages ingested through this connection grant.","name":"grantId","in":"query"},{"schema":{"type":"object","additionalProperties":{},"description":"Only messages whose source-specific `payload` object contains this shape. Every field given here must be present in `payload`, matching at any nesting depth; extra fields elsewhere in `payload` do not disqualify a match. This checks containment only: ranges (greater/less than, between) and substring matches against nested values are not supported.","example":{"sourceMeta":{"priority":"high"}}},"required":false,"description":"Only messages whose source-specific `payload` object contains this shape. Every field given here must be present in `payload`, matching at any nesting depth; extra fields elsewhere in `payload` do not disqualify a match. This checks containment only: ranges (greater/less than, between) and substring matches against nested values are not supported.","name":"payloadContains","in":"query"},{"schema":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"string"}],"description":"Only messages whose `enrichment` object contains this shape, e.g. `{\"application\": {\"crmId\": \"42\"}}` for what your enrichment endpoint returned. Same containment semantics as `payloadContains`. In a query string, pass it JSON-encoded.","example":{"application":{"crmId":"42"}}},"required":false,"description":"Only messages whose `enrichment` object contains this shape, e.g. `{\"application\": {\"crmId\": \"42\"}}` for what your enrichment endpoint returned. Same containment semantics as `payloadContains`. In a query string, pass it JSON-encoded.","name":"enrichmentContains","in":"query"},{"schema":{"type":"string","enum":["receivedAt","sentAt","relevance"],"description":"Sort axis. `relevance` requires `q` and is reachable to at most 1000 results. Narrow the query instead of paging further. Default: `receivedAt`."},"required":false,"description":"Sort axis. `relevance` requires `q` and is reachable to at most 1000 results. Narrow the query instead of paging further. Default: `receivedAt`.","name":"sort","in":"query"},{"schema":{"type":"string","enum":["asc","desc"],"description":"Sort direction. Default: `desc` (newest, or best match, first)."},"required":false,"description":"Sort direction. Default: `desc` (newest, or best match, first).","name":"order","in":"query"},{"schema":{"type":"string","description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another."},"required":false,"description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another.","name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Page size, between 1 and 200. Default 50."},"required":false,"description":"Page size, between 1 and 200. Default 50.","name":"limit","in":"query"},{"schema":{"type":"string","enum":["total"],"description":"`total` adds the number of matching results, counted up to 10000."},"required":false,"description":"`total` adds the number of matching results, counted up to 10000.","name":"include","in":"query"}],"responses":{"200":{"description":"A page of message summaries, without `body` and `attachments`","content":{"application/json":{"example":{"data":[{"id":"c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","providerMessageId":"18f2c4a9b7d01e3f","providerThreadId":"18f2b1c0a9e8d7f6","source":"gmail","receivedAt":"2026-10-23T07:58:12.000Z","sentAt":"2026-10-23T07:58:09.000Z","subject":"Invoice 2026-1042","from":[{"name":"Acme Accounts","email":"accounts@example.com"}],"sender":null,"to":[{"name":null,"email":"owner@example.com"}],"cc":null,"bcc":null,"replyTo":null,"messageId":["<20261023075809.4711@example.com>"],"inReplyTo":null,"references":null,"size":48213,"keywords":{"$seen":false},"labels":{"system":["inbox"],"custom":[]},"language":"en","preview":"Please find attached the invoice for October.","hasAttachment":true,"raw":{"downloadUrl":"https://api.inboxcnx.com/v1/raw/c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34"},"enrichment":null,"stateAt":"2026-10-23T07:58:12.000Z","deletedAt":null}],"nextCursor":"eyJ2IjoiMjAyNi0xMC0yM1QwNzo1ODoxMi4wMDBaIn0","prevCursor":null},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MessageSummary"}},"nextCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the next page. Null on the last page."},"prevCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the previous page. Null on the first page."},"total":{"type":"object","properties":{"count":{"type":"integer","minimum":0},"exact":{"type":"boolean"}},"required":["count","exact"],"description":"Present only when requested with `include`. `exact` is false once the count reaches 10000 (or the depth cap of a relevance search); `count` is then that cap."}},"required":["data","nextCursor","prevCursor"]}}}},"400":{"description":"Invalid query, malformed cursor, or a page beyond the relevance depth limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"The query exceeded the read timeout","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/query":{"post":{"operationId":"queryMessages","tags":["Messages"],"summary":"Query messages","description":"Finds stored mail with a filter tree that combines conditions with AND, OR and NOT, for searches a flat query string cannot express. Conditions nest to any depth. Every condition field a plain `GET /v1/messages` accepts is also valid inside a filter tree.\n\nA condition object (for example `{ \"from\": \"alice@example.com\" }`) matches messages satisfying all of its fields. Wrap conditions in an operator node to combine them explicitly:\n\n```json\n{\n  \"operator\": \"OR\",\n  \"conditions\": [\n    {\n      \"q\": \"invoice\"\n    },\n    {\n      \"from\": \"accounts@example.com\"\n    }\n  ]\n}\n```\n\nThis matches messages where the search text matches \"invoice\" OR the sender is accounts@example.com.\n\nOmit `filter` entirely to match every message the caller can see. The filter tree is limited to 6 levels of nesting and 40 conditions in total; a tree that exceeds either limit is rejected with `filter_depth_exceeded` or `filter_condition_count_exceeded`.\n\nResults are paginated the same way as `GET /v1/messages`; `include: [\"total\"]` adds the number of matches.\n\nRequires the `read:messages` scope.","requestBody":{"content":{"application/json":{"example":{"filter":{"operator":"OR","conditions":[{"q":"invoice"},{"from":"accounts@example.com"}]},"sort":[{"property":"receivedAt","isAscending":false}],"limit":25},"schema":{"type":"object","properties":{"filter":{"$ref":"#/components/schemas/MessageFilterNode"},"sort":{"type":"array","items":{"type":"object","properties":{"property":{"type":"string","enum":["receivedAt","sentAt"]},"isAscending":{"type":"boolean"}},"required":["property","isAscending"]},"maxItems":1,"description":"How to sort the results, as an array with exactly one entry: `[{ property, isAscending }]`. A longer array is rejected. Omit to sort by `receivedAt` descending (newest first). Relevance sorting is not available here; use `sort=relevance` on `GET /v1/messages` instead.","example":[{"property":"receivedAt","isAscending":false}]},"cursor":{"type":"string","description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another."},"limit":{"type":"integer","minimum":1,"maximum":200,"description":"Page size, between 1 and 200. Default 50."},"include":{"type":"array","items":{"type":"string","enum":["total"]},"description":"`total` adds the number of matching results, counted up to 10000."}}}}}},"responses":{"200":{"description":"A page of message summaries, without `body` and `attachments`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MessageSummary"}},"nextCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the next page. Null on the last page."},"prevCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the previous page. Null on the first page."},"total":{"type":"object","properties":{"count":{"type":"integer","minimum":0},"exact":{"type":"boolean"}},"required":["count","exact"],"description":"Present only when requested with `include`. `exact` is false once the count reaches 10000 (or the depth cap of a relevance search); `count` is then that cap."}},"required":["data","nextCursor","prevCursor"]}}}},"400":{"description":"Invalid filter tree, malformed cursor, or a tree past the depth/count limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"The query exceeded the read timeout","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/{id}":{"get":{"operationId":"getMessage","tags":["Messages"],"summary":"Get a message","description":"Returns one stored message with its body, attachment metadata and download URLs, to display or process the full mail. `body.html` is returned exactly as the sender wrote it: not sanitised, remote content not stripped. Render it only in an isolated context (a sandboxed `<iframe>` without `allow-scripts`/`allow-same-origin`, on its own origin or under a restrictive CSP), and block remote images until the reader opts in, or tracking pixels report the read to the sender.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The full `message-v1` object","content":{"application/json":{"example":{"id":"c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","providerMessageId":"18f2c4a9b7d01e3f","providerThreadId":"18f2b1c0a9e8d7f6","source":"gmail","receivedAt":"2026-10-23T07:58:12.000Z","sentAt":"2026-10-23T07:58:09.000Z","subject":"Invoice 2026-1042","from":[{"name":"Acme Accounts","email":"accounts@example.com"}],"sender":null,"to":[{"name":null,"email":"owner@example.com"}],"cc":null,"bcc":null,"replyTo":null,"messageId":["<20261023075809.4711@example.com>"],"inReplyTo":null,"references":null,"size":48213,"keywords":{"$seen":false},"labels":{"system":["inbox"],"custom":[]},"language":"en","preview":"Please find attached the invoice for October.","hasAttachment":true,"raw":{"downloadUrl":"https://api.inboxcnx.com/v1/raw/c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34"},"enrichment":null,"stateAt":"2026-10-23T07:58:12.000Z","deletedAt":null,"body":{"text":"Please find attached the invoice for October.","html":"<p>Please find attached the invoice for October.</p>"},"attachments":[{"id":"e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b","name":"invoice-2026-1042.pdf","contentType":"application/pdf","size":41872,"disposition":"attachment","cid":null,"downloadUrl":"https://api.inboxcnx.com/v1/attachments/e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b"}],"lifecycle":{"providerReceivedAt":"2026-10-23T07:58:10.000Z","detectedAt":"2026-10-23T07:58:11.000Z","fetchedAt":"2026-10-23T07:58:11.400Z","processedAt":"2026-10-23T07:58:11.900Z","storedAt":"2026-10-23T07:58:12.000Z","webhookEnqueuedAt":"2026-10-23T07:58:12.100Z","webhookDeliveredAt":"2026-10-23T07:58:12.600Z"}},"schema":{"$ref":"#/components/schemas/Message"}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such message for the caller’s organization and application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"operationId":"updateMessage","tags":["Messages"],"summary":"Update a message","description":"Changes a message’s read state, flags, archive and labels in the end user’s mailbox, to act on mail from your application. Runs against the mailbox at the provider, never only on the stored copy. The answer and a `GET` right after show the new state. `message.updated` follows for every grant on the mailbox once the provider reports the change.\n\n`keywords` sets or clears `$seen`, `$flagged`, `$important`. `labels.add` / `labels.remove` take the roles `inbox` and `archive` and the mailbox’s custom label ids. Trash and spam have their own endpoints. `sent`, `drafts`, `trash`, `junk` and `$junk` are refused.\n\nRequires the `modify:messages` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"example":{"keywords":{"$seen":true},"labels":{"add":["archive","Label_12"]}},"schema":{"type":"object","properties":{"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"add":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256},"maxItems":100},"remove":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256},"maxItems":100}},"additionalProperties":false}},"additionalProperties":false}}}},"responses":{"200":{"description":"The message’s new state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageState"}}}},"400":{"description":"Invalid body. `unknown_labels`: the mailbox has no label with these ids","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `modify:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`message_not_found`: no such message. `provider_message_not_found`: the provider no longer has it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/attachments/{id}":{"get":{"operationId":"downloadAttachment","tags":["Messages"],"summary":"Download an attachment","description":"Streams the bytes of one attachment of a stored message, to save or process the file. Take the URL from `attachments[].downloadUrl` on a message rather than building it. The content type is the one the sender declared.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The bytes, streamed as a download (`Content-Disposition: attachment`)","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"The credential lacks the `read:messages` scope, the Application requires a grant token (`grant_token_required`), or the credential is blocked","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`blob_not_found`: no such blob for the caller, or its bytes are gone","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"`blob_too_large`: the blob exceeds the download limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/raw/{id}":{"get":{"operationId":"downloadRawMessage","tags":["Messages"],"summary":"Download a raw message","description":"Streams the raw RFC 822 source of a stored message, to archive it or parse parts the API does not expose. Take the URL from `raw.downloadUrl` on a message rather than building it. `id` is the message id.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The bytes, streamed as a download (`Content-Disposition: attachment`)","content":{"message/rfc822":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"The credential lacks the `read:messages` scope, the Application requires a grant token (`grant_token_required`), or the credential is blocked","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`blob_not_found`: no such blob for the caller, or its bytes are gone","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"413":{"description":"`blob_too_large`: the blob exceeds the download limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/batch":{"post":{"operationId":"batchUpdateMessages","tags":["Messages"],"summary":"Update messages in bulk","description":"Changes the read state, flags, archive and labels of up to 100 messages of one grant in one call, for bulk actions such as mark all as read. Same rules as `PATCH /v1/messages/{id}`. An unknown id refuses the whole request before any change. `failed` lists the messages the provider refused while it took the others.\n\nRequires the `modify:messages` scope.","requestBody":{"content":{"application/json":{"example":{"ids":["c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","f0e1d2c3-b4a5-4968-8776-5a4b3c2d1e0f"],"keywords":{"$seen":true}},"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100},"keywords":{"type":"object","additionalProperties":{"type":"boolean"}},"labels":{"type":"object","properties":{"add":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256},"maxItems":100},"remove":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256},"maxItems":100}},"additionalProperties":false}},"required":["ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"How many changed","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"},"failed":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"}},"required":["id","code"]}}},"required":["updated","failed"]}}}},"400":{"description":"Invalid body. `mixed_grants`: the ids belong to more than one grant. `unknown_labels`: the mailbox has no label with these ids","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `modify:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`messages_not_found`: `ids` lists the unknown ones. `provider_message_not_found`: the provider no longer has one of them","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/batch/trash":{"post":{"operationId":"batchTrashMessages","tags":["Messages"],"summary":"Trash messages in bulk","description":"Trash messages in bulk at the provider: up to 100 messages of one grant per call, each as `POST /v1/messages/{id}/trash` handles one. Moves a message to the trash at the provider, to delete it the way the end user’s mail client would. The provider empties its trash on its own schedule (Gmail after 30 days). The stored copy stays, and `untrash` brings it back.\n\nRequires the `delete:messages` scope.","requestBody":{"content":{"application/json":{"example":{"ids":["c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","f0e1d2c3-b4a5-4968-8776-5a4b3c2d1e0f"]},"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100}},"required":["ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"How many moved","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"},"failed":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"}},"required":["id","code"]}}},"required":["updated","failed"]}}}},"400":{"description":"Invalid body. `mixed_grants`: the ids belong to more than one grant","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `delete:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`messages_not_found`: `ids` lists the unknown ones. `provider_message_not_found`: the provider no longer has one of them","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/batch/untrash":{"post":{"operationId":"batchUntrashMessages","tags":["Messages"],"summary":"Restore trashed messages in bulk","description":"Restore trashed messages in bulk at the provider: up to 100 messages of one grant per call, each as `POST /v1/messages/{id}/untrash` handles one. Moves a message out of the trash at the provider, to undo a delete. The message lands in `inbox`, whatever folder it came from.\n\nRequires the `delete:messages` scope.","requestBody":{"content":{"application/json":{"example":{"ids":["c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","f0e1d2c3-b4a5-4968-8776-5a4b3c2d1e0f"]},"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100}},"required":["ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"How many moved","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"},"failed":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"}},"required":["id","code"]}}},"required":["updated","failed"]}}}},"400":{"description":"Invalid body. `mixed_grants`: the ids belong to more than one grant","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `delete:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`messages_not_found`: `ids` lists the unknown ones. `provider_message_not_found`: the provider no longer has one of them","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/batch/report-spam":{"post":{"operationId":"batchReportSpamMessages","tags":["Messages"],"summary":"Report messages as spam","description":"Report messages as spam at the provider: up to 100 messages of one grant per call, each as `POST /v1/messages/{id}/report-spam` handles one. Reports a message as spam to the provider and moves it to the spam folder, which also trains the provider’s filter. The provider empties its spam folder on its own schedule (Gmail after 30 days). The stored copy stays.\n\nRequires the `report:spam` scope.","requestBody":{"content":{"application/json":{"example":{"ids":["c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","f0e1d2c3-b4a5-4968-8776-5a4b3c2d1e0f"]},"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100}},"required":["ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"How many moved","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"},"failed":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"}},"required":["id","code"]}}},"required":["updated","failed"]}}}},"400":{"description":"Invalid body. `mixed_grants`: the ids belong to more than one grant","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `report:spam` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`messages_not_found`: `ids` lists the unknown ones. `provider_message_not_found`: the provider no longer has one of them","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/batch/not-spam":{"post":{"operationId":"batchMarkNotSpamMessages","tags":["Messages"],"summary":"Mark messages as not spam","description":"Mark messages as not spam at the provider: up to 100 messages of one grant per call, each as `POST /v1/messages/{id}/not-spam` handles one. Moves a message out of the spam folder at the provider, to rescue mail the filter caught by mistake. The message lands in `inbox`.\n\nRequires the `report:spam` scope.","requestBody":{"content":{"application/json":{"example":{"ids":["c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","f0e1d2c3-b4a5-4968-8776-5a4b3c2d1e0f"]},"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100}},"required":["ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"How many moved","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"},"failed":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"}},"required":["id","code"]}}},"required":["updated","failed"]}}}},"400":{"description":"Invalid body. `mixed_grants`: the ids belong to more than one grant","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `report:spam` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`messages_not_found`: `ids` lists the unknown ones. `provider_message_not_found`: the provider no longer has one of them","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/{id}/trash":{"post":{"operationId":"trashMessage","tags":["Messages"],"summary":"Trash a message","description":"Moves a message to the trash at the provider, to delete it the way the end user’s mail client would. The provider empties its trash on its own schedule (Gmail after 30 days). The stored copy stays, and `untrash` brings it back.\n\nRequires the `delete:messages` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The message’s new state","content":{"application/json":{"example":{"id":"c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","keywords":{"$seen":true},"labels":{"system":["trash"],"custom":[]},"stateAt":"2026-10-23T08:00:00.000Z"},"schema":{"$ref":"#/components/schemas/MessageState"}}}},"400":{"description":"The id is not a UUID","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `delete:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`message_not_found`: no such message. `provider_message_not_found`: the provider no longer has it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/{id}/untrash":{"post":{"operationId":"untrashMessage","tags":["Messages"],"summary":"Restore a trashed message","description":"Moves a message out of the trash at the provider, to undo a delete. The message lands in `inbox`, whatever folder it came from.\n\nRequires the `delete:messages` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The message’s new state","content":{"application/json":{"example":{"id":"c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","keywords":{"$seen":true},"labels":{"system":["inbox"],"custom":[]},"stateAt":"2026-10-23T08:00:00.000Z"},"schema":{"$ref":"#/components/schemas/MessageState"}}}},"400":{"description":"The id is not a UUID","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `delete:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`message_not_found`: no such message. `provider_message_not_found`: the provider no longer has it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/{id}/report-spam":{"post":{"operationId":"reportSpamMessage","tags":["Messages"],"summary":"Report a message as spam","description":"Reports a message as spam to the provider and moves it to the spam folder, which also trains the provider’s filter. The provider empties its spam folder on its own schedule (Gmail after 30 days). The stored copy stays.\n\nRequires the `report:spam` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The message’s new state","content":{"application/json":{"example":{"id":"c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","keywords":{"$seen":true},"labels":{"system":["junk"],"custom":[]},"stateAt":"2026-10-23T08:00:00.000Z"},"schema":{"$ref":"#/components/schemas/MessageState"}}}},"400":{"description":"The id is not a UUID","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `report:spam` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`message_not_found`: no such message. `provider_message_not_found`: the provider no longer has it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/messages/{id}/not-spam":{"post":{"operationId":"markNotSpamMessage","tags":["Messages"],"summary":"Mark a message not spam","description":"Moves a message out of the spam folder at the provider, to rescue mail the filter caught by mistake. The message lands in `inbox`.\n\nRequires the `report:spam` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The message’s new state","content":{"application/json":{"example":{"id":"c4a7e2b9-1d3f-4e6a-8b0c-5f2d9e7a1b34","keywords":{"$seen":true},"labels":{"system":["inbox"],"custom":[]},"stateAt":"2026-10-23T08:00:00.000Z"},"schema":{"$ref":"#/components/schemas/MessageState"}}}},"400":{"description":"The id is not a UUID","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `report:spam` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"`message_not_found`: no such message. `provider_message_not_found`: the provider no longer has it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`message_deleted`: the mail is deleted at the provider. `connection_unreadable`: the mailbox cannot be reached and may need a reconnect. `connection_scope_missing`: the end user did not grant the scope the action needs, named in `scope`. A reconnect grants it","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"`provider_unavailable`: the provider is down or rate-limits the mailbox. Retry after `Retry-After` seconds","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/threads":{"get":{"operationId":"listThreads","tags":["Threads"],"summary":"List threads","description":"Lists the conversations in your grants’ stored mail, most recently active first, to show an inbox by thread. Returns threads matching every given query parameter (all parameters are combined with AND). Omit every parameter to list all threads the caller can see.\n\nSorted by most recently active thread first (`order=desc`, the default) or last (`order=asc`). Results are paginated: pass the previous response's `nextCursor` or `prevCursor` back as `cursor` to fetch the next or previous page; `null` means there is none. `include=total` adds the number of matches. See the pagination guide.\n\nTo combine filters with OR or NOT, or to nest conditions, use `POST /v1/threads/query` instead: it accepts the same fields inside a filter tree.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","description":"Only threads with this exact address among their participants (senders and recipients).","example":"alice@example.com"},"required":false,"description":"Only threads with this exact address among their participants (senders and recipients).","name":"participant","in":"query"},{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"description":"Only threads that do (`true`) or do not (`false`) contain at least one message with an attachment.","example":true},"required":false,"description":"Only threads that do (`true`) or do not (`false`) contain at least one message with an attachment.","name":"hasAttachment","in":"query"},{"schema":{"type":"string","enum":["gmail","m365","imap"],"description":"Only threads from this mail provider.","example":"gmail"},"required":false,"description":"Only threads from this mail provider.","name":"source","in":"query"},{"schema":{"type":"string","description":"Only the thread matching this source provider's own thread id (Gmail/M365/IMAP thread id).","example":"18c9a2f1b3d4e5f6"},"required":false,"description":"Only the thread matching this source provider's own thread id (Gmail/M365/IMAP thread id).","name":"providerThreadId","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Only threads whose most recent message was received at or after this instant (inclusive).","example":"2026-08-01T00:00:00Z"},"required":false,"description":"Only threads whose most recent message was received at or after this instant (inclusive).","name":"after","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Only threads whose most recent message was received strictly before this instant.","example":"2026-09-01T00:00:00Z"},"required":false,"description":"Only threads whose most recent message was received strictly before this instant.","name":"before","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Only threads ingested through this connection grant."},"required":false,"description":"Only threads ingested through this connection grant.","name":"grantId","in":"query"},{"schema":{"type":"string","description":"Only threads in which at least one message carries this label (a system role or a custom label).","example":"inbox"},"required":false,"description":"Only threads in which at least one message carries this label (a system role or a custom label).","name":"label","in":"query"},{"schema":{"type":"string","description":"Only threads in which at least one message does NOT carry this label. `notLabel=trash` leaves out threads whose every message is in the trash.","example":"trash"},"required":false,"description":"Only threads in which at least one message does NOT carry this label. `notLabel=trash` leaves out threads whose every message is in the trash.","name":"notLabel","in":"query"},{"schema":{"type":"string","enum":["asc","desc"],"description":"Sort direction by most recent message. Default: `desc` (most recently active thread first)."},"required":false,"description":"Sort direction by most recent message. Default: `desc` (most recently active thread first).","name":"order","in":"query"},{"schema":{"type":"string","description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another."},"required":false,"description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another.","name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Page size, between 1 and 200. Default 50."},"required":false,"description":"Page size, between 1 and 200. Default 50.","name":"limit","in":"query"},{"schema":{"type":"string","enum":["total"],"description":"`total` adds the number of matching results, counted up to 10000."},"required":false,"description":"`total` adds the number of matching results, counted up to 10000.","name":"include","in":"query"}],"responses":{"200":{"description":"A page of threads, newest conversation first","content":{"application/json":{"example":{"data":[{"id":"2d8f6a1c-7b3e-4c9d-a5f0-1e2b3c4d5e6f","providerThreadId":"18f2b1c0a9e8d7f6","source":"gmail","subject":"Invoice 2026-1042","participants":[{"name":"Acme Accounts","email":"accounts@example.com"},{"name":null,"email":"owner@example.com"}],"messageCount":3,"hasAttachment":true,"firstMessageAt":"2026-10-21T14:02:00.000Z","lastMessageAt":"2026-10-23T07:58:12.000Z","lastInboundAt":"2026-10-23T07:58:12.000Z","lastOutboundAt":"2026-10-22T09:15:40.000Z","labels":{"system":["inbox","sent"],"custom":[]},"keywords":{"any":{"$seen":true,"$flagged":true},"all":{"$seen":false}}}],"nextCursor":"eyJ2IjoiMjAyNi0xMC0yM1QwNzo1ODoxMi4wMDBaIn0","prevCursor":null},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerThreadId":{"type":["string","null"]},"source":{"type":"string","enum":["gmail","m365","imap"]},"subject":{"type":["string","null"]},"participants":{"type":"array","items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"messageCount":{"type":"integer","minimum":0},"hasAttachment":{"type":"boolean"},"firstMessageAt":{"type":"string"},"lastMessageAt":{"type":"string"},"lastInboundAt":{"type":["string","null"]},"lastOutboundAt":{"type":["string","null"]},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"keywords":{"type":"object","properties":{"any":{"type":"object","additionalProperties":{"type":"boolean"}},"all":{"type":"object","additionalProperties":{"type":"boolean"}}},"required":["any","all"]}},"required":["id","providerThreadId","source","subject","participants","messageCount","hasAttachment","firstMessageAt","lastMessageAt","lastInboundAt","lastOutboundAt","labels","keywords"]}},"nextCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the next page. Null on the last page."},"prevCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the previous page. Null on the first page."},"total":{"type":"object","properties":{"count":{"type":"integer","minimum":0},"exact":{"type":"boolean"}},"required":["count","exact"],"description":"Present only when requested with `include`. `exact` is false once the count reaches 10000 (or the depth cap of a relevance search); `count` is then that cap."}},"required":["data","nextCursor","prevCursor"]}}}},"400":{"description":"Invalid query or malformed cursor","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"The query exceeded the read timeout","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/threads/query":{"post":{"operationId":"queryThreads","tags":["Threads"],"summary":"Query threads","description":"Finds conversations with a filter tree that combines conditions with AND, OR and NOT, for searches a flat query string cannot express. Conditions nest to any depth. Every condition field a plain `GET /v1/threads` accepts is also valid inside a filter tree.\n\nA condition object (for example `{ \"participant\": \"alice@example.com\" }`) matches threads satisfying all of its fields. Wrap conditions in an operator node to combine them explicitly:\n\n```json\n{\n  \"operator\": \"OR\",\n  \"conditions\": [\n    {\n      \"participant\": \"alice@example.com\"\n    },\n    {\n      \"hasAttachment\": true\n    }\n  ]\n}\n```\n\nThis matches threads where Alice is a participant OR the thread has an attachment.\n\nOmit `filter` entirely to match every thread the caller can see. The filter tree is limited to 6 levels of nesting and 40 conditions in total; a tree that exceeds either limit is rejected with `filter_depth_exceeded` or `filter_condition_count_exceeded`.\n\nResults are paginated the same way as `GET /v1/threads`; `include: [\"total\"]` adds the number of matches.\n\nRequires the `read:messages` scope.","requestBody":{"content":{"application/json":{"example":{"filter":{"operator":"OR","conditions":[{"participant":"alice@example.com"},{"hasAttachment":true}]},"sort":[{"property":"lastMessageAt","isAscending":false}],"limit":25},"schema":{"type":"object","properties":{"filter":{"$ref":"#/components/schemas/ThreadFilterNode"},"sort":{"type":"array","items":{"type":"object","properties":{"property":{"type":"string","enum":["lastMessageAt"]},"isAscending":{"type":"boolean"}},"required":["property","isAscending"]},"maxItems":1,"description":"How to sort the results, as an array with exactly one entry: `[{ property, isAscending }]`. A longer array is rejected. Omit to sort by most recently active thread first.","example":[{"property":"lastMessageAt","isAscending":false}]},"cursor":{"type":"string","description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another."},"limit":{"type":"integer","minimum":1,"maximum":200,"description":"Page size, between 1 and 200. Default 50."},"include":{"type":"array","items":{"type":"string","enum":["total"]},"description":"`total` adds the number of matching results, counted up to 10000."}}}}}},"responses":{"200":{"description":"A page of threads, newest conversation first","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerThreadId":{"type":["string","null"]},"source":{"type":"string","enum":["gmail","m365","imap"]},"subject":{"type":["string","null"]},"participants":{"type":"array","items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"messageCount":{"type":"integer","minimum":0},"hasAttachment":{"type":"boolean"},"firstMessageAt":{"type":"string"},"lastMessageAt":{"type":"string"},"lastInboundAt":{"type":["string","null"]},"lastOutboundAt":{"type":["string","null"]},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"keywords":{"type":"object","properties":{"any":{"type":"object","additionalProperties":{"type":"boolean"}},"all":{"type":"object","additionalProperties":{"type":"boolean"}}},"required":["any","all"]}},"required":["id","providerThreadId","source","subject","participants","messageCount","hasAttachment","firstMessageAt","lastMessageAt","lastInboundAt","lastOutboundAt","labels","keywords"]}},"nextCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the next page. Null on the last page."},"prevCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the previous page. Null on the first page."},"total":{"type":"object","properties":{"count":{"type":"integer","minimum":0},"exact":{"type":"boolean"}},"required":["count","exact"],"description":"Present only when requested with `include`. `exact` is false once the count reaches 10000 (or the depth cap of a relevance search); `count` is then that cap."}},"required":["data","nextCursor","prevCursor"]}}}},"400":{"description":"Invalid filter tree, malformed cursor, or a tree past the depth/count limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"The query exceeded the read timeout","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/threads/{id}":{"get":{"operationId":"getThread","tags":["Threads"],"summary":"Get a thread","description":"Returns one conversation with its participants, message count, folders and flags, to show a thread before loading its messages.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The `thread-v1` object. If the requested id was merged away, the survivor’s data is returned with the survivor’s `id`.","content":{"application/json":{"example":{"id":"2d8f6a1c-7b3e-4c9d-a5f0-1e2b3c4d5e6f","providerThreadId":"18f2b1c0a9e8d7f6","source":"gmail","subject":"Invoice 2026-1042","participants":[{"name":"Acme Accounts","email":"accounts@example.com"},{"name":null,"email":"owner@example.com"}],"messageCount":3,"hasAttachment":true,"firstMessageAt":"2026-10-21T14:02:00.000Z","lastMessageAt":"2026-10-23T07:58:12.000Z","lastInboundAt":"2026-10-23T07:58:12.000Z","lastOutboundAt":"2026-10-22T09:15:40.000Z","labels":{"system":["inbox","sent"],"custom":[]},"keywords":{"any":{"$seen":true,"$flagged":true},"all":{"$seen":false}}},"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"providerThreadId":{"type":["string","null"]},"source":{"type":"string","enum":["gmail","m365","imap"]},"subject":{"type":["string","null"]},"participants":{"type":"array","items":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":"string"}},"required":["name","email"]}},"messageCount":{"type":"integer","minimum":0},"hasAttachment":{"type":"boolean"},"firstMessageAt":{"type":"string"},"lastMessageAt":{"type":"string"},"lastInboundAt":{"type":["string","null"]},"lastOutboundAt":{"type":["string","null"]},"labels":{"type":"object","properties":{"system":{"type":"array","items":{"type":"string","enum":["inbox","archive","drafts","sent","trash","junk","all","flagged","important"]}},"custom":{"type":"array","items":{"type":"string"}}},"required":["system","custom"]},"keywords":{"type":"object","properties":{"any":{"type":"object","additionalProperties":{"type":"boolean"}},"all":{"type":"object","additionalProperties":{"type":"boolean"}}},"required":["any","all"]}},"required":["id","providerThreadId","source","subject","participants","messageCount","hasAttachment","firstMessageAt","lastMessageAt","lastInboundAt","lastOutboundAt","labels","keywords"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such thread for the caller’s organization and application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"The query exceeded the read timeout","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/grants/{id}/token":{"post":{"operationId":"createGrantToken","tags":["Grants"],"summary":"Mint a grant token","description":"Exchanges an API key for a grant token: a credential valid for 5 minutes and confined to one end user’s mailbox, which you can hand to a client that must not hold the API key. It carries those of the mail scopes (`read:messages`, `modify:messages`, `delete:messages`, `report:spam`) that the API key holds. A grant token cannot mint another one.\n\nRequires the `read:messages` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"201":{"description":"The grant-scoped token; it is returned here and nowhere else","content":{"application/json":{"example":{"token":"icnxg_eyJvcmciOiIwZjZi…","expiresAt":"2026-10-23T08:05:00.000Z","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","scopes":["read:messages"]},"schema":{"type":"object","properties":{"token":{"type":"string"},"expiresAt":{"type":"string"},"grantId":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}},"required":["token","expiresAt","grantId","scopes"]}}}},"403":{"description":"The credential lacks `read:messages`, or is a grant token (`grant_token_chaining`)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such grant for the caller’s organization and application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"The grant is not active","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/grants/{id}/labels":{"get":{"operationId":"listGrantLabels","tags":["Grants"],"summary":"List folders and labels","description":"Lists the folders and the mailbox’s labels of a grant, with the ones it subscribes, so you can build a folder and label picker with one call. `system` holds the folders (`labels.system` on `message-v1`): those available, the application’s default, the grant’s `override` (`null` when it follows the default) and the `effective` ones. `custom` holds the mailbox’s own labels and category tabs, read live from the provider (`labels.custom` on `message-v1`), as a tree through `parentId`, with `subscribed` per label. A subscribed id the mailbox no longer has is listed with `missing: true`. A grant-scoped token reads its own grant.\n\nRequires the `read:messages` scope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The folders and labels","content":{"application/json":{"example":{"system":{"available":["inbox","sent","archive","drafts","junk","trash"],"applicationDefault":["inbox","sent"],"override":["inbox"],"effective":["inbox"]},"custom":[{"id":"Label_7","name":"Clients","path":"Clients","parentId":null,"type":"user","subscribed":false,"missing":false},{"id":"Label_12","name":"Acme","path":"Clients/Acme","parentId":"Label_7","type":"user","subscribed":true,"missing":false}]},"schema":{"type":"object","properties":{"system":{"type":"object","properties":{"available":{"type":"array","items":{"type":"string"}},"applicationDefault":{"type":"array","items":{"type":"string"}},"override":{"type":["array","null"],"items":{"type":"string"}},"effective":{"type":"array","items":{"type":"string"}}},"required":["available","applicationDefault","override","effective"]},"custom":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"The last segment of `path`."},"path":{"type":"string","description":"The full name, nested by `/`, e.g. `Clients/Acme`."},"parentId":{"type":["string","null"]},"type":{"type":"string","enum":["user","category"]},"subscribed":{"type":"boolean"},"missing":{"type":"boolean","description":"A subscribed id the mailbox no longer has. `name` and `path` are the id."}},"required":["id","name","path","parentId","type","subscribed","missing"]}}},"required":["system","custom"]}}}},"403":{"description":"The credential lacks the `read:messages` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such grant for the caller’s credential","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`grant_revoked`: the grant is revoked. `connection_unreadable`: the mailbox cannot be asked for its labels","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/grants/{id}":{"patch":{"operationId":"updateGrant","tags":["Grants"],"summary":"Update a grant","description":"Changes a grant’s settings: moves it to another profile, pauses or resumes it, or sets the folders and labels whose mail it processes.\n\nA profile with a higher retention than the grant’s consent covers needs `consent`. A lower retention, or a lower `deletedRetentionDays`, deletes the grant’s stored mail past it once a 7-day hold has passed; switching back within the hold deletes nothing. A paused grant skips all mail until it is unpaused. A mail is processed when it lies in one of the grant’s folders or carries one of its labels; a label covers only itself, not its sub-labels. Folders and labels together need at least one entry. A narrower filter deletes nothing: stored mail stays until the retention deletes it, and mail already delivered keeps receiving `message.updated`. A wider one fetches no older mail on its own; start a backfill for that. With `subscribedLabels`, the labels are checked against the mailbox. The response never reveals the profile to a grant token: the route needs `write:connections`.\n\nRequires the `write:connections` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"example":{"subscribedRoles":["inbox"],"subscribedLabels":["Label_12"]},"schema":{"type":"object","properties":{"profile":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,31}$"},"consent":{"type":"object","properties":{"grantedAt":{"type":["string","null"],"format":"date-time"},"textVersion":{"type":"string","minLength":1,"maxLength":64}},"required":["grantedAt","textVersion"]},"paused":{"type":"boolean"},"subscribedRoles":{"type":["array","null"],"items":{"type":"string","enum":["inbox","sent","archive","drafts","junk","trash"]},"description":"The grant’s own folders, replacing the application’s `subscribedRoles`. `null` follows the application’s again, `[]` subscribes no folder, so only `subscribedLabels` pick mail."},"subscribedLabels":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256},"maxItems":100,"description":"Label ids of the mailbox, as `GET /v1/grants/{id}/labels` lists them. Replaces the grant’s labels."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The grant’s settings","content":{"application/json":{"schema":{"type":"object","properties":{"grantId":{"type":"string"},"profile":{"type":"string"},"paused":{"type":"boolean"},"blocked":{"type":"boolean"},"subscribedRoles":{"type":["array","null"],"items":{"type":"string"},"description":"The grant’s own folders, or `null` when it follows the application’s."},"subscribedLabels":{"type":"array","items":{"type":"string"}},"effectiveRoles":{"type":"array","items":{"type":"string"},"description":"The folders that apply: `subscribedRoles`, else the application’s."}},"required":["grantId","profile","paused","blocked","subscribedRoles","subscribedLabels","effectiveRoles"]}}}},"400":{"description":"Invalid body. `empty_filter`: no folder and no label. `unknown_labels`: `labels` lists the ids the mailbox does not have","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:connections` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such grant or profile","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"The grant is revoked, the profile is archived, or consent is required. `connection_unreadable`: the mailbox cannot be asked for its labels","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"operationId":"revokeGrant","tags":["Grants"],"summary":"Revoke a grant","description":"Revokes a grant and deletes its stored mail, for an end user who disconnects or leaves. From the response on, no route serves the grant’s mail and no new mail of it is processed; a grant token of it answers `409 grant_revoked`. Its stored mail, threads and the grant itself are deleted within 24 hours, with no grace period: export what you need first. With the grant of the last Application on the mailbox, InboxCNX also revokes its access at the provider. Subscribed endpoints receive `grant.revoked`. A repeated call answers the same; once the grant is deleted it answers 404. To stop processing but keep the stored mail, pause the grant with `PATCH /v1/grants/{id}` instead.\n\nRequires the `write:connections` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"202":{"description":"The grant is revoked; its stored mail is deleted within 24 hours","content":{"application/json":{"example":{"id":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","status":"revoked","revokedAt":"2026-10-23T08:00:00.000Z"},"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["revoked"]},"revokedAt":{"type":"string"}},"required":["id","status","revokedAt"]}}}},"403":{"description":"The credential lacks the `write:connections` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such grant for the caller’s organization and application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/grants/{id}/backfill":{"post":{"operationId":"startBackfill","tags":["Backfills"],"summary":"Start a history backfill","description":"Starts a history backfill that delivers a grant’s older mail, for an end user who wants mail from before the connect. At most one history backfill runs per grant. It delivers every mail of the range that matches the grant’s folders and labels (`effectiveRoles`, `subscribedLabels`), or the part of them given as `roles` and `labels`, as `message.received` with `data.origin: \"backfill\"`, and stores only mail within the grant’s retention. Mail the grant already received is not delivered or billed again, so overlapping ranges cost nothing twice. Backfill mail counts against the allowance like live mail, but never against the Profile’s limits, which cap new mail only. The run waits while the grant is paused or blocked, or its mailbox needs a reconnect, and continues on its own. Subscribed endpoints receive `grant.backfill_completed` when it ends. The range is `{ \"since\": \"<ISO date>\" }`, `{ \"days\": n }` or `{ \"all\": true }` and ends at the time of the request. `roles` and `labels` narrow the run to part of the grant’s filter, e.g. one label just added; giving one of them counts the other as empty. Without them the run follows the grant’s filter as it stands while it runs.\n\nRequires the `write:connections` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"example":{"days":30},"schema":{"anyOf":[{"type":"object","properties":{"since":{"type":"string","format":"date-time"},"roles":{"type":"array","items":{"type":"string","enum":["inbox","sent","archive","drafts","junk","trash"]}},"labels":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256},"maxItems":100}},"required":["since"],"additionalProperties":false},{"type":"object","properties":{"days":{"type":"integer","minimum":1,"maximum":36500},"roles":{"type":"array","items":{"type":"string","enum":["inbox","sent","archive","drafts","junk","trash"]}},"labels":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256},"maxItems":100}},"required":["days"],"additionalProperties":false},{"type":"object","properties":{"all":{"type":"boolean","enum":[true]},"roles":{"type":"array","items":{"type":"string","enum":["inbox","sent","archive","drafts","junk","trash"]}},"labels":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256},"maxItems":100}},"required":["all"],"additionalProperties":false}]}}}},"responses":{"201":{"description":"The run, started","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"grantId":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["history","catch_up"]},"since":{"type":["string","null"]},"until":{"type":["string","null"]},"roles":{"type":["array","null"],"items":{"type":"string"}},"labels":{"type":["array","null"],"items":{"type":"string"}},"status":{"type":"string","enum":["running","done","cancelled"]},"waitingReason":{"type":["string","null"]},"listed":{"type":"integer","minimum":0},"published":{"type":"integer","minimum":0},"estimatedMessages":{"type":["integer","null"],"minimum":0},"createdAt":{"type":"string"},"finishedAt":{"type":["string","null"]}},"required":["id","grantId","kind","since","until","roles","labels","status","waitingReason","listed","published","estimatedMessages","createdAt","finishedAt"]}}}},"400":{"description":"Invalid range. `invalid_subset`: `roles` or `labels` name something outside the grant’s filter, or nothing","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:connections` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such grant for the caller’s organization and application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`backfill_running`: a history backfill is already running. `grant_not_processed`: the grant is revoked, paused or blocked, or its mailbox needs a reconnect","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"get":{"operationId":"getBackfill","tags":["Backfills"],"summary":"Get a grant’s backfill","description":"Returns the grant’s running history backfill, else its latest one, so you can show its progress. `done` means every page of the range was listed and every missing mail handed to processing; the last `message.received` may follow seconds later. `waitingReason` says why a running backfill does not move.\n\nRequires the `write:connections` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The run","content":{"application/json":{"example":{"id":"7c1d9e2a-0b3f-4a5c-8d6e-2f1a0b9c8d7e","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","kind":"history","since":"2026-09-20T10:00:00.000Z","until":"2026-10-20T10:00:00.000Z","roles":null,"labels":null,"status":"running","waitingReason":null,"listed":1200,"published":950,"estimatedMessages":2410,"createdAt":"2026-10-20T10:00:00.000Z","finishedAt":null},"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"grantId":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["history","catch_up"]},"since":{"type":["string","null"]},"until":{"type":["string","null"]},"roles":{"type":["array","null"],"items":{"type":"string"}},"labels":{"type":["array","null"],"items":{"type":"string"}},"status":{"type":"string","enum":["running","done","cancelled"]},"waitingReason":{"type":["string","null"]},"listed":{"type":"integer","minimum":0},"published":{"type":"integer","minimum":0},"estimatedMessages":{"type":["integer","null"],"minimum":0},"createdAt":{"type":"string"},"finishedAt":{"type":["string","null"]}},"required":["id","grantId","kind","since","until","roles","labels","status","waitingReason","listed","published","estimatedMessages","createdAt","finishedAt"]}}}},"403":{"description":"The credential lacks the `write:connections` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No history backfill for this grant","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"operationId":"cancelBackfill","tags":["Backfills"],"summary":"Cancel a history backfill","description":"Cancels the grant’s running history backfill. Mail already handed to processing is still delivered. Subscribed endpoints receive `grant.backfill_completed` with `status: \"cancelled\"`. A new backfill over the same range delivers only what is missing.\n\nRequires the `write:connections` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Cancelled"},"403":{"description":"The credential lacks the `write:connections` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No running history backfill for this grant","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/grants/{id}/backfill-estimate":{"get":{"operationId":"estimateBackfill","tags":["Backfills"],"summary":"Estimate a history backfill","description":"Counts the mail and the minutes a history backfill of a range would take, so the end user can pick a range before starting one.\n\nPass exactly one of `since`, `days` or `all=true`, and optionally `until` (default now) to count a window, e.g. to add up nested ranges without counting twice. `messages` is the mail in the range that matches the grant’s folders and labels, or the part given as `roles` and `labels` (comma-separated), counted id by id. A mail in a folder and a label, or in two labels, counts once for each, so with labels `messages` is an upper bound. A call counts at most `pages` pages of 500 (default and maximum 20, 10,000 mails). When it stops early, `exact` is false, `messages` is a lower bound, and `nextPageToken` goes on: pass it as `pageToken` with the same range and subset and add the counts up. It counts mail the grant already received, so it overestimates a range that overlaps an earlier backfill or live mail. `estimatedMinutes` assumes the full backfill rate of the mailbox. `retentionDays` is the grant’s retention: mail of the range older than that is delivered, not stored.\n\nRequires the `write:connections` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"since","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":36500},"required":false,"name":"days","in":"query"},{"schema":{"type":"string","enum":["true"]},"required":false,"name":"all","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"until","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":20},"required":false,"name":"pages","in":"query"},{"schema":{"type":"string","maxLength":2048},"required":false,"name":"pageToken","in":"query"},{"schema":{"type":"string"},"required":false,"name":"roles","in":"query"},{"schema":{"type":"string"},"required":false,"name":"labels","in":"query"}],"responses":{"200":{"description":"The estimate","content":{"application/json":{"example":{"messages":2410,"exact":true,"estimatedMinutes":27,"retentionDays":30},"schema":{"type":"object","properties":{"messages":{"type":"integer","minimum":0},"exact":{"type":"boolean"},"estimatedMinutes":{"type":"integer","minimum":0},"nextPageToken":{"type":"string"},"retentionDays":{"type":"integer","minimum":0}},"required":["messages","exact","estimatedMinutes","retentionDays"]}}}},"400":{"description":"Invalid range. `invalid_subset`: `roles` or `labels` name something outside the grant’s filter, or nothing. `invalid_page_token`: not a `nextPageToken` of this estimate","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:connections` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"No such grant for the caller’s organization and application","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"`grant_not_processed`: the grant is revoked, paused or blocked, or its mailbox needs a reconnect","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"The provider did not answer","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/backfills":{"get":{"operationId":"listBackfills","tags":["Backfills"],"summary":"List running backfills","description":"Lists the running backfills of all the application’s grants, newest first, so an embedding app can show an import in progress for every grant with one call. Keyset pagination.\n\n`kind: \"history\"` is a backfill the Application started. `kind: \"catch_up\"` is one InboxCNX started to deliver mail a grant missed while it was held back (a message limit, a pause or a block). It has no estimate and cannot be cancelled.\n\nRequires the `write:connections` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another."},"required":false,"description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another.","name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Page size, between 1 and 200. Default 50."},"required":false,"description":"Page size, between 1 and 200. Default 50.","name":"limit","in":"query"},{"schema":{"type":"string","enum":["total"],"description":"`total` adds the number of matching results, counted up to 10000."},"required":false,"description":"`total` adds the number of matching results, counted up to 10000.","name":"include","in":"query"}],"responses":{"200":{"description":"A page of running backfills","content":{"application/json":{"example":{"data":[{"id":"7c1d9e2a-0b3f-4a5c-8d6e-2f1a0b9c8d7e","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","kind":"history","since":"2026-09-20T10:00:00.000Z","until":"2026-10-20T10:00:00.000Z","roles":null,"labels":null,"status":"running","waitingReason":null,"listed":1200,"published":950,"estimatedMessages":2410,"createdAt":"2026-10-20T10:00:00.000Z","finishedAt":null}],"nextCursor":null,"prevCursor":null},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"grantId":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["history","catch_up"]},"since":{"type":["string","null"]},"until":{"type":["string","null"]},"roles":{"type":["array","null"],"items":{"type":"string"}},"labels":{"type":["array","null"],"items":{"type":"string"}},"status":{"type":"string","enum":["running","done","cancelled"]},"waitingReason":{"type":["string","null"]},"listed":{"type":"integer","minimum":0},"published":{"type":"integer","minimum":0},"estimatedMessages":{"type":["integer","null"],"minimum":0},"createdAt":{"type":"string"},"finishedAt":{"type":["string","null"]}},"required":["id","grantId","kind","since","until","roles","labels","status","waitingReason","listed","published","estimatedMessages","createdAt","finishedAt"]}},"nextCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the next page. Null on the last page."},"prevCursor":{"type":["string","null"],"description":"Pass back as `cursor` for the previous page. Null on the first page."},"total":{"type":"object","properties":{"count":{"type":"integer","minimum":0},"exact":{"type":"boolean"}},"required":["count","exact"],"description":"Present only when requested with `include`. `exact` is false once the count reaches 10000 (or the depth cap of a relevance search); `count` is then that cap."}},"required":["data","nextCursor","prevCursor"]}}}},"400":{"description":"Malformed cursor","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `write:connections` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/status":{"get":{"operationId":"getStatus","tags":["Status"],"summary":"Get integration health","security":[{"apiKey":[]}],"description":"Returns the integration health of every application in the caller’s organization, so you can spot a broken mailbox or failing webhooks early. Reports, per application, how many mailbox connections and grants exist and in which state, when each last synced, and how the last 24 hours of webhook deliveries went.\n\nUnlike every other `/v1` endpoint this one is **organization-wide**: a key of one application sees the ids and health of the others, so one key covers them all. It reports ids and counts only: never mailbox addresses, end-user ids, webhook targets or message contents.\n\nNo scope required. A grant token gets `403 grant_scoped_credential`.","parameters":[{"schema":{"type":"string","format":"uuid","description":"Narrow the answer to one application. An id belonging to another organization is invisible and yields nothing."},"required":false,"description":"Narrow the answer to one application. An id belonging to another organization is invisible and yields nothing.","name":"applicationId","in":"query"}],"responses":{"200":{"description":"One entry per live application, oldest first","content":{"application/json":{"example":{"data":[{"id":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","mode":"direct","webhookConfigured":true,"connections":{"total":3,"byStatus":{"initiated":0,"active":2,"error":1,"deleted":0},"health":{"ok":2,"degraded":0,"down":0,"error":1}},"grants":{"total":3,"byStatus":{"pending":0,"active":3,"revoked":0}},"lastSyncedAt":"2026-10-23T07:58:12.000Z","deliveries24h":{"total":412,"failed":2}}]},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"mode":{"type":"string","enum":["direct","whitelabel"]},"webhookConfigured":{"type":"boolean"},"connections":{"type":"object","properties":{"total":{"type":"integer"},"byStatus":{"type":"object","properties":{"initiated":{"type":"integer"},"active":{"type":"integer"},"error":{"type":"integer"},"deleted":{"type":"integer"}},"required":["initiated","active","error","deleted"]},"health":{"type":"object","properties":{"ok":{"type":"integer"},"degraded":{"type":"integer"},"down":{"type":"integer"},"error":{"type":"integer"}},"required":["ok","degraded","down","error"]}},"required":["total","byStatus","health"]},"grants":{"type":"object","properties":{"total":{"type":"integer"},"byStatus":{"type":"object","properties":{"pending":{"type":"integer"},"active":{"type":"integer"},"revoked":{"type":"integer"}},"required":["pending","active","revoked"]}},"required":["total","byStatus"]},"lastSyncedAt":{"type":["string","null"]},"deliveries24h":{"type":"object","properties":{"total":{"type":"integer"},"failed":{"type":"integer"}},"required":["total","failed"]}},"required":["id","mode","webhookConfigured","connections","grants","lastSyncedAt","deliveries24h"]}}},"required":["data"]}}}},"403":{"description":"The credential is grant-scoped and may not read organization-wide health","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/usage":{"get":{"operationId":"getUsage","tags":["Usage"],"summary":"Get monthly usage","description":"Returns the caller application’s billable usage for one month, per grant and profile, so you can bill your own users. One row per grant and profile, with the Application’s totals. A grant moved to another profile during the month has a row per profile. Summed over all rows, `mails`, `backfillMails` and `gbMonths` equal the totals. Once `closed` is true the month is invoiced and its numbers never change. For the running month `projection` extends the live mails’ daily rate over the month and adds `backfillMails` once, so a one-off backfill is not projected onto the month.\n\nRequires the `read:usage` scope.","security":[{"apiKey":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$","description":"The month, `YYYY-MM`. Default: the running month."},"required":false,"description":"The month, `YYYY-MM`. Default: the running month.","name":"period","in":"query"},{"schema":{"type":"string","description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another."},"required":false,"description":"Opaque pagination cursor: a previous response's `nextCursor` or `prevCursor`, passed back verbatim. A cursor issued under one sort order is rejected if reused with another.","name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Page size, between 1 and 200. Default 50."},"required":false,"description":"Page size, between 1 and 200. Default 50.","name":"limit","in":"query"}],"responses":{"200":{"description":"A page of usage rows","content":{"application/json":{"example":{"period":"2026-10","from":"2026-10-01T00:00:00.000Z","to":"2026-11-01T00:00:00.000Z","closed":false,"totals":{"activeGrantsPeak":12,"mails":4180,"backfillMails":900,"gbMonths":3.2},"projection":{"projectedGbMonths":4.1,"allowanceGbMonths":10,"overageGbMonths":0,"mails":4180,"allowanceMails":50000,"projectedMails":6200,"overageMails":0,"storageOverageAmount":"0.00","mailOverageAmount":"0.00"},"data":[{"grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","externalUserId":"crm-user-42","profileKey":"default","activeDays":23,"mails":410,"backfillMails":90,"gbMonths":0.3}],"nextCursor":null,"prevCursor":null},"schema":{"type":"object","properties":{"period":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"from":{"type":"string"},"to":{"type":"string"},"closed":{"type":"boolean"},"totals":{"type":"object","properties":{"activeGrantsPeak":{"type":"integer","minimum":0},"mails":{"type":"integer","minimum":0},"backfillMails":{"type":"integer","minimum":0},"gbMonths":{"type":"number","minimum":0}},"required":["activeGrantsPeak","mails","backfillMails","gbMonths"]},"projection":{"type":["object","null"],"properties":{"projectedGbMonths":{"type":"number","minimum":0},"allowanceGbMonths":{"type":"number","minimum":0},"overageGbMonths":{"type":"number","minimum":0},"mails":{"type":"integer","minimum":0},"allowanceMails":{"type":"integer","minimum":0},"projectedMails":{"type":"integer","minimum":0},"overageMails":{"type":"integer","minimum":0},"storageOverageAmount":{"type":"string"},"mailOverageAmount":{"type":"string"}},"required":["projectedGbMonths","allowanceGbMonths","overageGbMonths","mails","allowanceMails","projectedMails","overageMails","storageOverageAmount","mailOverageAmount"]},"data":{"type":"array","items":{"type":"object","properties":{"grantId":{"type":"string","format":"uuid"},"externalUserId":{"type":["string","null"]},"profileKey":{"type":["string","null"]},"activeDays":{"type":"integer","minimum":0},"mails":{"type":"integer","minimum":0},"backfillMails":{"type":"integer","minimum":0},"gbMonths":{"type":"number","minimum":0}},"required":["grantId","externalUserId","profileKey","activeDays","mails","backfillMails","gbMonths"]}},"nextCursor":{"type":["string","null"]},"prevCursor":{"type":["string","null"]}},"required":["period","from","to","closed","totals","projection","data","nextCursor","prevCursor"]}}}},"400":{"description":"Invalid query or malformed cursor","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"The credential lacks the `read:usage` scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"Usage could not be read","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Usage is not configured","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}}},"webhooks":{"message.received":{"post":{"operationId":"message-received","summary":"message.received","description":"A mail entered the application’s scope for the first time, including one released later from a folder the application does not subscribe to.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageReceivedEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"message.updated":{"post":{"operationId":"message-updated","summary":"message.updated","description":"The provider changed the state of a delivered mail: its folders, labels or flags. Carries the full new state and the previous value of each changed field.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageUpdatedEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"message.deleted":{"post":{"operationId":"message-deleted","summary":"message.deleted","description":"The provider deleted a delivered mail.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageDeletedEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"message.enrich":{"post":{"operationId":"message-enrich","summary":"message.enrich","description":"Called synchronously before a new mail is stored and delivered; the response enriches it. At most one endpoint per application.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageEnrichEvent"}}}},"responses":{"200":{"description":"The enrichment to store on the mail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageEnrichResponse"}}}},"204":{"description":"Nothing to add."},"default":{"description":"One attempt, no retry. Within 5 seconds, body read included; at most 32 KB of the body are read. On any failure the mail is processed and delivered without enrichment."}}}},"usage.period.closed":{"post":{"operationId":"usage-period-closed","summary":"usage.period.closed","description":"A month is invoiced and its usage numbers are final. Carries the application’s totals; the rows per grant come from `GET /v1/usage?period=…`.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"example":{"id":"usage.period.closed:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4:2026-10","type":"usage.period.closed","createdAt":"2026-10-23T08:00:00.000Z","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","grantId":null,"externalUserId":null,"data":{"period":"2026-10","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","totals":{"activeGrantsPeak":12,"mails":4180,"backfillMails":900,"gbMonths":3.2}}},"schema":{"$ref":"#/components/schemas/UsagePeriodClosedEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"grant.revoked":{"post":{"operationId":"grant-revoked","summary":"grant.revoked","description":"A grant was revoked: by the application (`reason: requested`), or by us after its mailbox stayed in error for 30 days (`reason: connection_error_timeout`). No route serves its mail any more, and its stored mail is deleted within 24 hours.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"example":{"id":"grant.revoked:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4:2026-10","type":"grant.revoked","createdAt":"2026-10-23T08:00:00.000Z","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","externalUserId":"crm-user-42","data":{"revokedAt":"2026-10-23T08:00:00.000Z","reason":"requested"}},"schema":{"$ref":"#/components/schemas/GrantRevokedEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"connection.error":{"post":{"operationId":"connection-error","summary":"connection.error","description":"The mailbox of a grant stopped working. `data.reason` says what repairs it: `reauth_required` (the owner connects it again) or `mailbox_unavailable` (the provider refuses access to the account). Sent once per outage and grant.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"example":{"id":"connection.error:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4:2026-10","type":"connection.error","createdAt":"2026-10-23T08:00:00.000Z","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","externalUserId":"crm-user-42","data":{"connection":{"id":"5e8d2a10-3c4b-4f6e-9a7d-1b2c3d4e5f60","provider":"gmail","accountEmail":"owner@example.com"},"reason":"reauth_required","since":"2026-10-01T06:00:00.000Z"}},"schema":{"$ref":"#/components/schemas/ConnectionErrorEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"connection.restored":{"post":{"operationId":"connection-restored","summary":"connection.restored","description":"The mailbox of a grant works again after a `connection.error`. Mail received during the outage follows as `message.received`. A pending revocation is off.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"example":{"id":"connection.restored:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4:2026-10","type":"connection.restored","createdAt":"2026-10-23T08:00:00.000Z","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","externalUserId":"crm-user-42","data":{"connection":{"id":"5e8d2a10-3c4b-4f6e-9a7d-1b2c3d4e5f60","provider":"gmail","accountEmail":"owner@example.com"},"since":"2026-10-01T06:00:00.000Z","restoredAt":"2026-10-02T09:30:00.000Z"}},"schema":{"$ref":"#/components/schemas/ConnectionRestoredEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"grant.revocation_scheduled":{"post":{"operationId":"grant-revocation-scheduled","summary":"grant.revocation_scheduled","description":"The mailbox of a grant has been in error for 23 days. Unless it is connected again, the grant is revoked at `data.revokesAt`, 30 days after the outage began.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"example":{"id":"grant.revocation_scheduled:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4:2026-10","type":"grant.revocation_scheduled","createdAt":"2026-10-23T08:00:00.000Z","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","externalUserId":"crm-user-42","data":{"connection":{"id":"5e8d2a10-3c4b-4f6e-9a7d-1b2c3d4e5f60","provider":"gmail","accountEmail":"owner@example.com"},"reason":"reauth_required","since":"2026-10-01T06:00:00.000Z","revokesAt":"2026-10-31T06:00:00.000Z"}},"schema":{"$ref":"#/components/schemas/GrantRevocationScheduledEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"grant.cap_reached":{"post":{"operationId":"grant-cap-reached","summary":"grant.cap_reached","description":"A grant reached a monthly limit of its profile. `messages`: no further mail is delivered this month. `storage`: the first mail this month that was not stored; smaller mails may still fit. Sent once per grant, month and limit.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"example":{"id":"grant.cap_reached:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4:2026-10","type":"grant.cap_reached","createdAt":"2026-10-23T08:00:00.000Z","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","externalUserId":"crm-user-42","data":{"cap":"messages","limit":10000,"period":"2026-10","profileKey":"default"}},"schema":{"$ref":"#/components/schemas/GrantCapReachedEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"grant.created":{"post":{"operationId":"grant-created","summary":"grant.created","description":"A new grant exists: an end user finished the connect flow, or `POST /v1/connections/{id}/grants` added one. Not sent for a reconnect of an existing grant (that is `connection.restored`).","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"example":{"id":"grant.created:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4:2026-10","type":"grant.created","createdAt":"2026-10-23T08:00:00.000Z","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","externalUserId":"crm-user-42","data":{"connection":{"id":"5e8d2a10-3c4b-4f6e-9a7d-1b2c3d4e5f60","provider":"gmail","accountEmail":"owner@example.com"},"profileKey":"default"}},"schema":{"$ref":"#/components/schemas/GrantCreatedEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}},"grant.backfill_completed":{"post":{"operationId":"grant-backfill-completed","summary":"grant.backfill_completed","description":"A history backfill of a grant ended: every mail in its range was handed to delivery (`status: done`), or it was cancelled. The last `message.received` of the run may follow seconds later.","parameters":[{"schema":{"type":"string","description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","example":"t=1761206400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"},"required":true,"description":"`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The MAC covers `<t>.<raw body>` with the endpoint’s signing secret. During a secret rotation a second `v1` carries the previous secret’s MAC. Reject a `t` older than 5 minutes.","name":"x-inboxcnx-signature","in":"header"},{"schema":{"type":"string","description":"The envelope’s `id`. Stable across retries: dedupe on it."},"required":true,"description":"The envelope’s `id`. Stable across retries: dedupe on it.","name":"x-inboxcnx-event-id","in":"header"}],"requestBody":{"content":{"application/json":{"example":{"id":"grant.backfill_completed:9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4:2026-10","type":"grant.backfill_completed","createdAt":"2026-10-23T08:00:00.000Z","applicationId":"a3c1e8f2-4b7d-4e9a-9f10-6d2b8c5e7a41","grantId":"9b2f0c4e-6a1d-4f3b-8c55-0d7e2a91b3c4","externalUserId":"crm-user-42","data":{"runId":"7c1d9e2a-0b3f-4a5c-8d6e-2f1a0b9c8d7e","status":"done","since":"2026-09-20T10:00:00.000Z","until":"2026-10-20T10:00:00.000Z","listed":2410,"published":1980}},"schema":{"$ref":"#/components/schemas/GrantBackfillCompletedEvent"}}}},"responses":{"2XX":{"description":"Delivered. The body is ignored."},"default":{"description":"A `408`, `429`, `5xx`, a timeout or a network error is retried with backoff. Any other status, and a redirect (never followed), ends the delivery as failed."}}}}}}