consent_request.status_changed & client_id_request.status_changed🔗 For the shared HTTP contract, headers, signature verification, and retry logic, see the Webhook Integration & Signature Verification page.
consent_request.status_changed and client_id_request.status_changed are the two halves of the OAuth onboarding flow for new mailboxes. They share the same status enum, the same lifecycle, and are typically handled by the same piece of your code. Documenting them together makes the flow clearer.| Event | What it tracks | Platforms |
|---|---|---|
consent_request.status_changed | The customer opening and completing an OAuth consent URL to authorize InboxKit to access their workspace | Google Workspace & Microsoft 365 |
client_id_request.status_changed | The customer's tenant granting InboxKit's app access — a Client ID added in Google Admin Console, or tenant-wide admin consent on Microsoft | Google Workspace & Microsoft 365 |
queued → pending → processing → completed
↘ failed
↘ errored
↘ cancelled| Status | What it means |
|---|---|
queued | Request created, waiting to be picked up by the worker. |
pending | Worker has picked it up; the URL / instructions are ready for the customer. Surface this to your user. |
processing | InboxKit is verifying completion (polling Google/Microsoft APIs). |
completed | ✅ Successfully finished. Onboarding can proceed. |
failed | The request failed for a reason we can explain (e.g. permissions). Check status_text / status_reason. |
errored | The request errored unexpectedly. Check status_text / status_reason. |
cancelled | The customer or an admin cancelled the request. |
POST /your-path HTTP/1.1
Content-Type: application/json
User-Agent: InboxKit-Webhook/1.0
X-InboxKit-Event: consent_request.status_changed # or client_id_request.status_changed
X-InboxKit-Timestamp: 2024-01-10T17:05:00.000Z
X-InboxKit-Signature: sha256=<hex>consent_request.status_changedconsent_request. This event fires whenever that request's status changes — from the moment it's queued, through pending (the customer has a URL to open), to completed/failed.{
"event": "consent_request.status_changed",
"timestamp": "<ISO 8601 UTC>",
"team_id": "<your team uid>",
"team_name": "<your team name>",
"data": {
"consent_request": { /* see fields below */ },
"metadata": { /* see fields below */ }
}
}data.consent_request fieldsconsent_request.status_changed webhook is listed below.| Field | Type | Nullable | Description |
|---|---|---|---|
uid | string | no | Unique, stable identifier for this consent request. Use as idempotency key. |
status | enum | no | New status. See the shared lifecycle table above. |
previous_status | string | null | yes | Previous status before this transition. |
consent_url | string | no | The URL the customer needs to open to grant consent. Valid while status is pending. |
status_text | string | no (may be empty) | Human-readable short status message. |
status_reason | string | no (may be empty) | Failure detail. Often empty, and not a stable enum — the text varies. Use status for control flow and status_text for display. |
retry_count | integer | no | How many times InboxKit has retried this request. |
max_retries | integer | no | Retry cap before the request goes terminal. |
completed_at | ISO 8601 | null | yes | When the request reached a terminal state (completed, failed, errored, cancelled). |
data.metadata fields| Field | Type | Description |
|---|---|---|
updated_at | ISO 8601 | When the consent request document was last updated. |
workspace_id | string | Internal workspace identifier. |
workspace_uid | string | null | Workspace the consent request belongs to. This is the same uid that List Workspaces returns and that you send in X-Workspace-Id, so use it to match the event to a workspace on your side. |
mailbox_id | string | Internal identifier of the mailbox the consent request is for. |
mailbox_uid | string | null | Mailbox the consent request is for. Same uid that List Mailboxes returns, and the same value you get as data.mailbox.uid on a mailbox.status_changed event. |
status: "pending" with a consent_url, surface that URL to your end user immediately — that's the signal that they need to click through the Google / Microsoft consent screen. A typical pattern is:data.consent_request.consent_url.status: "completed" event arrives for the same uid, hide the banner and move on to the next onboarding step.status: "failed" / errored, show status_text to the user so they know what went wrong.client_id_request.status_changedclient_id_request tracks that setup, and this event fires whenever its status changes.processing for several minutes before reaching a terminal state.{
"event": "client_id_request.status_changed",
"timestamp": "<ISO 8601 UTC>",
"team_id": "<your team uid>",
"team_name": "<your team name>",
"data": {
"client_id_request": { /* see fields below */ },
"metadata": { /* see fields below */ }
}
}data.client_id_request fieldsclient_id_request.status_changed webhook is listed below.| Field | Type | Nullable | Description |
|---|---|---|---|
uid | string | no | Unique, stable identifier for this client-id request. Use as idempotency key. |
status | enum | no | New status. See the shared lifecycle table above. |
previous_status | string | null | yes | Previous status before this transition. |
domain_name | string | no | The domain the grant applies to. |
client_id | string | no | The application ID being granted. On Google this is an OAuth Client ID (e.g. 1234567890-abcdefgh.apps.googleusercontent.com); on Microsoft/Azure it is a GUID (e.g. 7ad5103e-8eea-415b-bd29-4b4da5399494). |
status_text | string | no (may be empty) | Human-readable short status message. |
status_reason | string | no (may be empty) | Failure detail. On Google this is a short code (e.g. client_id_not_found); on Microsoft/Azure it is free text and often empty, so do not branch on it there — use status for control flow and status_text for display. |
retry_count | integer | no | How many times InboxKit has retried this request. |
max_retries | integer | no | Retry cap before the request goes terminal. |
completed_at | ISO 8601 | null | yes | When the request reached a terminal state. |
data.metadata fields| Field | Type | Description |
|---|---|---|
updated_at | ISO 8601 | When the client-id request document was last updated. |
workspace_id | string | Internal workspace identifier. |
workspace_uid | string | null | Workspace the request belongs to. This is the same uid that List Workspaces returns and that you send in X-Workspace-Id, so use it to match the event to a workspace on your side. |
Telling the platforms apart. The payload does not currently include a platformfield. Until it does, use the shape ofclient_id: a GUID is Microsoft/Azure, anything ending in.apps.googleusercontent.comis Google.
status becomes pending and you have a client_id, surface instructions to the customer along the lines of:"Please add this OAuth Client ID <client_id>to Security → API controls → Domain-wide delegation in your Google Workspace Admin Console."
completed event to proceed.completed or failed. Do not show the Google Admin Console instructions here; there is no equivalent step for the customer to perform.failed, read status_text for the reason. These failures are usually resolved on the InboxKit side, so surface them internally rather than to the end customer.curl --location 'https://api.inboxkit.com/webhook' \
--header 'X-InboxKit-Signature: sha256=b0344c61d8db38e0f469e85fc6e8c055e0742e8d9a9c5a9e8e4d3f7c5a8b9c0d' \
--header 'X-InboxKit-Event: domain.status_changed' \
--header 'X-InboxKit-Timestamp: 2024-01-10T15:30:45.123Z' \
--header 'User-Agent: InboxKit-Webhook/1.0' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"event": "consent_request.status_changed",
"timestamp": "2024-01-10T17:05:00.000Z",
"team_id": "ABC-123-DEF-TEAM",
"team_name": "Marketing Team",
"data": {
"consent_request": {
"uid": "ABC-123-DEF-CONSENT-REQUEST",
"status": "completed",
"previous_status": "pending",
"consent_url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&scope=...",
"status_text": "Consent granted",
"status_reason": "",
"retry_count": 0,
"max_retries": 3,
"completed_at": "2024-01-10T17:05:00.000Z"
},
"metadata": {
"updated_at": "2024-01-10T17:05:00.000Z",
"workspace_id": "ABC-123-DEF-WORKSPACE",
"workspace_uid": "ABC-123-DEF-WORKSPACE-UID",
"mailbox_id": "ABC-123-DEF-MAILBOX-ID",
"mailbox_uid": "ABC-123-DEF-MAILBOX-UID"
}
}
}'{
"received": true,
"message": "Webhook processed successfully"
}