Inboxes
Your sending inboxes: connect Gmail, Microsoft or SMTP, update settings, verify, disconnect and control warmup.
Start a Gmail or Microsoft connect
/v1/inboxes/connect-sessionsinboxes.create-connect-sessionprovider is google or microsoft. purpose is primary (the caller's own mailbox, through the Kenso Workspace app; not_found without Kenso Accounts) or campaign (a shared campaign mailbox, through Kenso Mail). Open authorizationUrl before expiresAt; nothing is stored until the connect finishes. It finishes in the Kenso dashboard: after consent the provider sends the browser there, and the member who created the session (for an API key, its owner) must be signed in, in this workspace. Anyone else is refused and nothing is connected, so a key that names no member cannot finish a connect. Requires delivery edit, like the legacy authorize routes. A client seat (Delivery view, approve_own_sends) connects only its own primary inbox: purpose=campaign is 403 forbidden with own_inbox_only, and a login email off the workspace's email domain (or a workspace with none) is 409 invalid_state with email_domain_mismatch, whose message says what fixes it, because that mailbox would never be its primary inbox. A grant for any mailbox but the caller's login email waits for POST /v1/inboxes/connect-confirmations, which needs delivery edit, so a client seat connects only its login email. Declared [WorkspaceMember]; the action decides delivery edit or approve_own_sends. Optional returnTo is a dashboard path the finished connect lands on, on the dashboard's own origin, with the usual result query (gmail=connected, microsoft=error&reason=...); for Microsoft the admin-consent return lands there too. Anything but a relative path with one leading /, no //, backslash or control characters, at most 512 characters, is validation_failed on returnTo. Without it the connect returns to the app's default page.
Parameters
400 workspace_required).Request body
application/json, optional.
/42/delivery?tab=inboxes. A relative path with one leading /: no scheme, host, //, backslash or control characters, at most 512 characters. Omit it to return to the app's default page.Response 201
data is a InboxConnectSessionModel.
google or microsoft.primary (a member's own mailbox), campaign (a shared campaign mailbox), or calendar (a member's calendar alone, from POST /v1/calendar-accounts/connect-sessions, DEV-4022).curl -X POST "https://api.ken.so/v1/inboxes/connect-sessions" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"provider": "string",
"purpose": "string",
"returnTo": "string"
}'{
"success": true,
"data": {
"provider": "string",
"purpose": "string",
"appName": "string",
"clientId": "string",
"authorizationUrl": "https://example.com",
"adminUrl": "https://example.com",
"adminConsentUrl": "https://example.com",
"expiresAt": "2026-09-23T15:02:11Z"
}
}status is optional. availableForCampaignId lists Kenso-sendable inboxes that campaign can assign, replacing GET /v1/campaigns/{id}/inboxes/available. A campaign outside the workspace is not_found. isPrimary=true lists only primary inboxes (owned by a member and on the workspace's primary domain, as isPrimary on each inbox), isPrimary=false only the rest; it does not combine with availableForCampaignId. role is sending, replies or retired and lists only inboxes with that role; a replies or retired inbox only receives, so it never appears in an availableForCampaignId list and role does not combine with it either. A retired inbox carries captureUntil. Needs Delivery view.
Parameters
isPrimary on the model), false only the rest.sending, replies or retired: lists only inboxes with that role. Combines with status and isPrimary, not with availableForCampaignId.400 workspace_required).Response 200
data is a list of InboxModel. Each item has these fields. The response also carries pagination.
sending (a campaign inbox), replies: the workspace's shared replies@ inbox, the address campaign replies go to, or retired: a campaign inbox staff retired to receive-only. A replies or retired inbox only receives: it never joins a campaign pool or warmup, and Kenso keeps reading its mail.retired inbox's reply capture window ends, UTC. Nothing happens automatically then: Kenso keeps reading the inbox until staff delete it. Omitted unless the inbox is retired, and on availableForCampaignId lists.availableForCampaignId lists.google (a Kenso-managed Google mailbox), microsoft (a Kenso-managed Microsoft or Azure mailbox), google_account or microsoft_account (a member's own mailbox connected through Kenso sign-in, whose photo only its owner can change) or none. Setting a photo also needs the workspace's inbox_photos flag. Omitted on availableForCampaignId lists.pending (InboxKit queued it for a Microsoft or Azure mailbox and has not applied it yet), applied or failed (InboxKit did not apply it: no photo shows, and Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoError says why). Omitted for photos set before this tracking, when Kenso set none, and on availableForCampaignId lists.pending, when InboxKit took the photo.failed.resend, agentmail, ...) when the inbox is an identity on a sending provider connection, which sends through that provider's API. Omitted for every other inbox.ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.availableForCampaignId lists.<tenant>.onmicrosoft.com, read hourly from its domain's public DKIM record. Inboxes that share it share one tenant, the unit a Microsoft tenant ban hits. Staff only (super_admin): omitted for every other caller, and omitted until it is resolved.inbox.connection.health on GET /v1/inboxes/{inboxId}. Mapped by M:Ken.Scraper.API.Canonical.InboxMapper.ApplyHealth(Ken.Scraper.API.Canonical.InboxModel,Ken.Scraping.Application.Queries.EmailOrchestrator.InboxHealthDto).curl -X GET "https://api.ken.so/v1/inboxes" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": [
{
"id": 5530,
"email": "[email protected]",
"firstName": "Alex",
"lastName": "Rivera",
"displayName": "Alex Rivera",
"signature": "Alex Rivera\nNorthwind Outbound",
"status": "active",
"role": "sending",
"provider": "google",
"domainId": 640,
"dailySendLimit": 30,
"profilePhotoSupport": "google",
"tagIds": [],
"createdAt": "2026-08-31T10:15:00Z",
"updatedAt": "2026-10-14T09:41:27Z",
"isPrimary": false,
"usedBy": {
"campaigns": [
{
"id": 4821,
"name": "Q4 SaaS founders",
"status": "active"
}
],
"accounts": false
},
"warmup": {
"daysLeft": 0
},
"healthScore": 94,
"lastSentAt": "2026-10-14T09:12:40Z"
}
],
"pagination": {
"nextCursor": "eyJpZCI6ODE1fQ",
"hasMore": true,
"total": 1,
"isTotalCapped": true
}
}Needs Delivery edit.
Parameters
400 workspace_required).Request body
application/json, optional.
dead_simple_email or azure_smtp: its hosts, ports and TLS replace smtpHost, smtpPort, imapHost, imapPort and smtpStartTls, which may be omitted. Needs the sending_providers feature.azure_smtp): the workspace inbox Ken reads replies from. Required there, ignored otherwise.Response 201
data is a InboxModel.
sending (a campaign inbox), replies: the workspace's shared replies@ inbox, the address campaign replies go to, or retired: a campaign inbox staff retired to receive-only. A replies or retired inbox only receives: it never joins a campaign pool or warmup, and Kenso keeps reading its mail.retired inbox's reply capture window ends, UTC. Nothing happens automatically then: Kenso keeps reading the inbox until staff delete it. Omitted unless the inbox is retired, and on availableForCampaignId lists.availableForCampaignId lists.google (a Kenso-managed Google mailbox), microsoft (a Kenso-managed Microsoft or Azure mailbox), google_account or microsoft_account (a member's own mailbox connected through Kenso sign-in, whose photo only its owner can change) or none. Setting a photo also needs the workspace's inbox_photos flag. Omitted on availableForCampaignId lists.pending (InboxKit queued it for a Microsoft or Azure mailbox and has not applied it yet), applied or failed (InboxKit did not apply it: no photo shows, and Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoError says why). Omitted for photos set before this tracking, when Kenso set none, and on availableForCampaignId lists.pending, when InboxKit took the photo.failed.resend, agentmail, ...) when the inbox is an identity on a sending provider connection, which sends through that provider's API. Omitted for every other inbox.ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.availableForCampaignId lists.<tenant>.onmicrosoft.com, read hourly from its domain's public DKIM record. Inboxes that share it share one tenant, the unit a Microsoft tenant ban hits. Staff only (super_admin): omitted for every other caller, and omitted until it is resolved.inbox.connection.health on GET /v1/inboxes/{inboxId}. Mapped by M:Ken.Scraper.API.Canonical.InboxMapper.ApplyHealth(Ken.Scraper.API.Canonical.InboxModel,Ken.Scraping.Application.Queries.EmailOrchestrator.InboxHealthDto).curl -X POST "https://api.ken.so/v1/inboxes" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"username": "string",
"password": "string",
"smtpHost": "string",
"smtpPort": 1,
"imapHost": "string",
"imapPort": 1,
"smtpStartTls": true,
"ownerMemberId": 812,
"preset": "string",
"replyToInboxId": 812
}'{
"success": true,
"data": {
"id": 5530,
"email": "[email protected]",
"firstName": "Alex",
"lastName": "Rivera",
"displayName": "Alex Rivera",
"signature": "Alex Rivera\nNorthwind Outbound",
"status": "active",
"role": "sending",
"provider": "google",
"domainId": 640,
"dailySendLimit": 30,
"profilePhotoSupport": "google",
"tagIds": [],
"createdAt": "2026-08-31T10:15:00Z",
"updatedAt": "2026-10-14T09:41:27Z",
"isPrimary": false,
"usedBy": {
"campaigns": [
{
"id": 4821,
"name": "Q4 SaaS founders",
"status": "active"
}
],
"accounts": false
},
"warmup": {
"daysLeft": 0
},
"healthScore": 94,
"lastSentAt": "2026-10-14T09:12:40Z"
}
}Apply one field update to up to 1,000 inboxes
/v1/inboxes/bulk-updateinboxes.bulk-updatepaused pauses or resumes every selected inbox, as on PATCH /v1/inboxes/{inboxId}. profileImageUrl sets one photo, as on the PATCH, on up to 100 inboxes and takes no other field: updatedCount counts the inboxes InboxKit accepted, each other one is in failed with the reason. Needs Delivery edit.
Parameters
400 workspace_required).Request body
application/json, optional: object.
Response 200
data is a InboxBulkResult.
profileImageUrl, the inboxes whose photo InboxKit accepted; the rest are in Ken.Scraper.API.Canonical.InboxBulkResult.Failed.curl -X POST "https://api.ken.so/v1/inboxes/bulk-update" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{}'{
"success": true,
"data": {
"updatedCount": 1,
"failed": [
{
"id": 812,
"message": "string"
}
]
}
}Return one inbox in the current workspace
/v1/inboxes/{inboxId}inboxes.getOnly this read carries health: today's sends against the inbox's cap, its ramp, its warmup readiness and its active blocks. Only for a workspace with the agent_send feature flag on; omitted otherwise, and when it could not be read.
Parameters
400 workspace_required).Response 200
data is a InboxModel.
sending (a campaign inbox), replies: the workspace's shared replies@ inbox, the address campaign replies go to, or retired: a campaign inbox staff retired to receive-only. A replies or retired inbox only receives: it never joins a campaign pool or warmup, and Kenso keeps reading its mail.retired inbox's reply capture window ends, UTC. Nothing happens automatically then: Kenso keeps reading the inbox until staff delete it. Omitted unless the inbox is retired, and on availableForCampaignId lists.availableForCampaignId lists.google (a Kenso-managed Google mailbox), microsoft (a Kenso-managed Microsoft or Azure mailbox), google_account or microsoft_account (a member's own mailbox connected through Kenso sign-in, whose photo only its owner can change) or none. Setting a photo also needs the workspace's inbox_photos flag. Omitted on availableForCampaignId lists.pending (InboxKit queued it for a Microsoft or Azure mailbox and has not applied it yet), applied or failed (InboxKit did not apply it: no photo shows, and Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoError says why). Omitted for photos set before this tracking, when Kenso set none, and on availableForCampaignId lists.pending, when InboxKit took the photo.failed.resend, agentmail, ...) when the inbox is an identity on a sending provider connection, which sends through that provider's API. Omitted for every other inbox.ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.availableForCampaignId lists.<tenant>.onmicrosoft.com, read hourly from its domain's public DKIM record. Inboxes that share it share one tenant, the unit a Microsoft tenant ban hits. Staff only (super_admin): omitted for every other caller, and omitted until it is resolved.inbox.connection.health on GET /v1/inboxes/{inboxId}. Mapped by M:Ken.Scraper.API.Canonical.InboxMapper.ApplyHealth(Ken.Scraper.API.Canonical.InboxModel,Ken.Scraping.Application.Queries.EmailOrchestrator.InboxHealthDto).curl -X GET "https://api.ken.so/v1/inboxes/812" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"id": 5530,
"email": "[email protected]",
"firstName": "Alex",
"lastName": "Rivera",
"displayName": "Alex Rivera",
"signature": "Alex Rivera\nNorthwind Outbound",
"status": "active",
"role": "sending",
"provider": "google",
"domainId": 640,
"dailySendLimit": 30,
"profilePhotoSupport": "google",
"tagIds": [],
"createdAt": "2026-08-31T10:15:00Z",
"updatedAt": "2026-10-14T09:41:27Z",
"isPrimary": false,
"usedBy": {
"campaigns": [
{
"id": 4821,
"name": "Q4 SaaS founders",
"status": "active"
}
],
"accounts": false
},
"warmup": {
"daysLeft": 0
},
"healthScore": 94,
"lastSentAt": "2026-10-14T09:12:40Z"
}
}Absent fields stay unchanged. Null clears text fields and forwarding.
trackOpens is the owner's Track opens option and exists only on a member's own mailbox (ownerMemberId set); on a shared campaign inbox it is validation_failed, and anyone but the owner gets forbidden. paused: true pauses outreach from the inbox and sets pausedAt (kept when it is already paused): campaign steps, triggers and approved Accounts 1:1 email wait instead of sending, and new leads are planned on the campaign's other inboxes. paused: false resumes it and clears pausedAt; held sends go out on the next dispatch. Warmup, reply sync and replies a member sends keep running, and campaign assignments stay. Needs Delivery edit. profileImageUrl (https, not null) sets the sender photo: a POST /v1/inbox-photos URL as is, any other fetched once (image-from-URL quota), saved only after InboxKit accepts it. Needs the inbox_photos flag, else 400 detail code feature_disabled, and an inbox Kenso can set (profilePhotoSupportgoogle or microsoft), else 400; either way nothing is written. InboxKit timing out or failing is 503 service_unavailable: try again. The update is not atomic: trackOpens, then the text fields, then forwarding, then paused, then profileImageUrl are written in turn, so a failure part-way leaves the earlier ones applied. Each write is idempotent, so retrying the same PATCH is safe.
Parameters
400 workspace_required).Request body
application/json, optional: object.
Response 200
data is a InboxModel.
sending (a campaign inbox), replies: the workspace's shared replies@ inbox, the address campaign replies go to, or retired: a campaign inbox staff retired to receive-only. A replies or retired inbox only receives: it never joins a campaign pool or warmup, and Kenso keeps reading its mail.retired inbox's reply capture window ends, UTC. Nothing happens automatically then: Kenso keeps reading the inbox until staff delete it. Omitted unless the inbox is retired, and on availableForCampaignId lists.availableForCampaignId lists.google (a Kenso-managed Google mailbox), microsoft (a Kenso-managed Microsoft or Azure mailbox), google_account or microsoft_account (a member's own mailbox connected through Kenso sign-in, whose photo only its owner can change) or none. Setting a photo also needs the workspace's inbox_photos flag. Omitted on availableForCampaignId lists.pending (InboxKit queued it for a Microsoft or Azure mailbox and has not applied it yet), applied or failed (InboxKit did not apply it: no photo shows, and Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoError says why). Omitted for photos set before this tracking, when Kenso set none, and on availableForCampaignId lists.pending, when InboxKit took the photo.failed.resend, agentmail, ...) when the inbox is an identity on a sending provider connection, which sends through that provider's API. Omitted for every other inbox.ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.availableForCampaignId lists.<tenant>.onmicrosoft.com, read hourly from its domain's public DKIM record. Inboxes that share it share one tenant, the unit a Microsoft tenant ban hits. Staff only (super_admin): omitted for every other caller, and omitted until it is resolved.inbox.connection.health on GET /v1/inboxes/{inboxId}. Mapped by M:Ken.Scraper.API.Canonical.InboxMapper.ApplyHealth(Ken.Scraper.API.Canonical.InboxModel,Ken.Scraping.Application.Queries.EmailOrchestrator.InboxHealthDto).curl -X PATCH "https://api.ken.so/v1/inboxes/812" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{}'{
"success": true,
"data": {
"id": 5530,
"email": "[email protected]",
"firstName": "Alex",
"lastName": "Rivera",
"displayName": "Alex Rivera",
"signature": "Alex Rivera\nNorthwind Outbound",
"status": "active",
"role": "sending",
"provider": "google",
"domainId": 640,
"dailySendLimit": 30,
"profilePhotoSupport": "google",
"tagIds": [],
"createdAt": "2026-08-31T10:15:00Z",
"updatedAt": "2026-10-14T09:41:27Z",
"isPrimary": false,
"usedBy": {
"campaigns": [
{
"id": 4821,
"name": "Q4 SaaS founders",
"status": "active"
}
],
"accounts": false
},
"warmup": {
"daysLeft": 0
},
"healthScore": 94,
"lastSentAt": "2026-10-14T09:12:40Z"
}
}Re-check an inbox connection
/v1/inboxes/{inboxId}/verifyinboxes.verifyNeeds Delivery edit.
Parameters
400 workspace_required).Response 200
data is a InboxModel.
sending (a campaign inbox), replies: the workspace's shared replies@ inbox, the address campaign replies go to, or retired: a campaign inbox staff retired to receive-only. A replies or retired inbox only receives: it never joins a campaign pool or warmup, and Kenso keeps reading its mail.retired inbox's reply capture window ends, UTC. Nothing happens automatically then: Kenso keeps reading the inbox until staff delete it. Omitted unless the inbox is retired, and on availableForCampaignId lists.availableForCampaignId lists.google (a Kenso-managed Google mailbox), microsoft (a Kenso-managed Microsoft or Azure mailbox), google_account or microsoft_account (a member's own mailbox connected through Kenso sign-in, whose photo only its owner can change) or none. Setting a photo also needs the workspace's inbox_photos flag. Omitted on availableForCampaignId lists.pending (InboxKit queued it for a Microsoft or Azure mailbox and has not applied it yet), applied or failed (InboxKit did not apply it: no photo shows, and Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoError says why). Omitted for photos set before this tracking, when Kenso set none, and on availableForCampaignId lists.pending, when InboxKit took the photo.failed.resend, agentmail, ...) when the inbox is an identity on a sending provider connection, which sends through that provider's API. Omitted for every other inbox.ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.availableForCampaignId lists.<tenant>.onmicrosoft.com, read hourly from its domain's public DKIM record. Inboxes that share it share one tenant, the unit a Microsoft tenant ban hits. Staff only (super_admin): omitted for every other caller, and omitted until it is resolved.inbox.connection.health on GET /v1/inboxes/{inboxId}. Mapped by M:Ken.Scraper.API.Canonical.InboxMapper.ApplyHealth(Ken.Scraper.API.Canonical.InboxModel,Ken.Scraping.Application.Queries.EmailOrchestrator.InboxHealthDto).curl -X POST "https://api.ken.so/v1/inboxes/812/verify" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"id": 5530,
"email": "[email protected]",
"firstName": "Alex",
"lastName": "Rivera",
"displayName": "Alex Rivera",
"signature": "Alex Rivera\nNorthwind Outbound",
"status": "active",
"role": "sending",
"provider": "google",
"domainId": 640,
"dailySendLimit": 30,
"profilePhotoSupport": "google",
"tagIds": [],
"createdAt": "2026-08-31T10:15:00Z",
"updatedAt": "2026-10-14T09:41:27Z",
"isPrimary": false,
"usedBy": {
"campaigns": [
{
"id": 4821,
"name": "Q4 SaaS founders",
"status": "active"
}
],
"accounts": false
},
"warmup": {
"daysLeft": 0
},
"healthScore": 94,
"lastSentAt": "2026-10-14T09:12:40Z"
}
}Disconnect an inbox connection
/v1/inboxes/{inboxId}/disconnectinboxes.disconnectNeeds Delivery edit.
Parameters
400 workspace_required).Response 200
data is a InboxModel.
sending (a campaign inbox), replies: the workspace's shared replies@ inbox, the address campaign replies go to, or retired: a campaign inbox staff retired to receive-only. A replies or retired inbox only receives: it never joins a campaign pool or warmup, and Kenso keeps reading its mail.retired inbox's reply capture window ends, UTC. Nothing happens automatically then: Kenso keeps reading the inbox until staff delete it. Omitted unless the inbox is retired, and on availableForCampaignId lists.availableForCampaignId lists.google (a Kenso-managed Google mailbox), microsoft (a Kenso-managed Microsoft or Azure mailbox), google_account or microsoft_account (a member's own mailbox connected through Kenso sign-in, whose photo only its owner can change) or none. Setting a photo also needs the workspace's inbox_photos flag. Omitted on availableForCampaignId lists.pending (InboxKit queued it for a Microsoft or Azure mailbox and has not applied it yet), applied or failed (InboxKit did not apply it: no photo shows, and Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoError says why). Omitted for photos set before this tracking, when Kenso set none, and on availableForCampaignId lists.pending, when InboxKit took the photo.failed.resend, agentmail, ...) when the inbox is an identity on a sending provider connection, which sends through that provider's API. Omitted for every other inbox.ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.availableForCampaignId lists.<tenant>.onmicrosoft.com, read hourly from its domain's public DKIM record. Inboxes that share it share one tenant, the unit a Microsoft tenant ban hits. Staff only (super_admin): omitted for every other caller, and omitted until it is resolved.inbox.connection.health on GET /v1/inboxes/{inboxId}. Mapped by M:Ken.Scraper.API.Canonical.InboxMapper.ApplyHealth(Ken.Scraper.API.Canonical.InboxModel,Ken.Scraping.Application.Queries.EmailOrchestrator.InboxHealthDto).curl -X POST "https://api.ken.so/v1/inboxes/812/disconnect" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"id": 5530,
"email": "[email protected]",
"firstName": "Alex",
"lastName": "Rivera",
"displayName": "Alex Rivera",
"signature": "Alex Rivera\nNorthwind Outbound",
"status": "active",
"role": "sending",
"provider": "google",
"domainId": 640,
"dailySendLimit": 30,
"profilePhotoSupport": "google",
"tagIds": [],
"createdAt": "2026-08-31T10:15:00Z",
"updatedAt": "2026-10-14T09:41:27Z",
"isPrimary": false,
"usedBy": {
"campaigns": [
{
"id": 4821,
"name": "Q4 SaaS founders",
"status": "active"
}
],
"accounts": false
},
"warmup": {
"daysLeft": 0
},
"healthScore": 94,
"lastSentAt": "2026-10-14T09:12:40Z"
}
}Return warmup state for one inbox
/v1/inboxes/{inboxId}/warmupinboxes.get-warmupstatus and enabled come from the live warmup provider's own status, picked in the order pause and resume act on. status is pending while bought warmup waits to activate, and paused when it is paused. An Azure inbox with no warmup subscription is failed, because Kenso cannot enroll Azure. readiness is the cold-send warmup gate's verdict from provider warmup snapshots: ready, bypassed, unconfirmed, too_young, provider_stale, or unavailable. enrollmentFailure (staff only) is why the last pre-warmup provider enrollment failed, its consecutive attempts and the next retry time. Needs Delivery view.
Parameters
400 workspace_required).Response 200
data is a InboxWarmupModel.
curl -X GET "https://api.ken.so/v1/inboxes/812/warmup" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"status": "string",
"enabled": true,
"startedAt": "2026-09-23T15:02:11Z",
"completedAt": "2026-09-23T15:02:11Z",
"readiness": {
"outcome": "string",
"isReady": true,
"isHeld": true,
"isEnforced": true,
"firstWarmupSendDate": "string",
"lastWarmupSendDate": "string",
"daysInWarmup": 1,
"minimumWarmupDays": 1,
"hasMinWeekOverride": true,
"hasOutreachBypass": true
},
"enrollmentFailure": {
"provider": "string",
"reason": "string",
"status": "string",
"failureCount": 1,
"retryAt": "2026-09-23T15:02:11Z",
"isStopped": true
}
}
}Pause or resume warmup for one inbox
/v1/inboxes/{inboxId}/warmupinboxes.update-warmupenabled: false pauses. enabled: true resumes. Needs Delivery edit. Neither enrolls a mailbox that has no warmup subscription; staff enroll through POST /v1/admin/inboxes/warmup/enable.
Parameters
400 workspace_required).Request body
application/json, optional: object.
Response 200
data is a InboxWarmupModel.
curl -X PATCH "https://api.ken.so/v1/inboxes/812/warmup" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{}'{
"success": true,
"data": {
"status": "string",
"enabled": true,
"startedAt": "2026-09-23T15:02:11Z",
"completedAt": "2026-09-23T15:02:11Z",
"readiness": {
"outcome": "string",
"isReady": true,
"isHeld": true,
"isEnforced": true,
"firstWarmupSendDate": "string",
"lastWarmupSendDate": "string",
"daysInWarmup": 1,
"minimumWarmupDays": 1,
"hasMinWeekOverride": true,
"hasOutreachBypass": true
},
"enrollmentFailure": {
"provider": "string",
"reason": "string",
"status": "string",
"failureCount": 1,
"retryAt": "2026-09-23T15:02:11Z",
"isStopped": true
}
}
}Change an inbox's username, the part of its address before the @
/v1/inboxes/{inboxId}/renameinboxes.renameOnly for InboxKit mailboxes (inboxes Kenso bought for you); the domain stays the same. Send the new username as localPart (jane.doe, not the whole address). InboxKit renames the mailbox first; Kenso then changes the inbox's email, and, when the inbox already has a sending connection, reconnects it under the new address. reconnected says whether that happened, and warnings lists any follow-up step that did not finish (the rename itself still succeeded). Renaming to the current username returns the inbox unchanged. Errors: 400 validation_failed on localPart (detail code invalid, or provider_rejected when InboxKit refused it; the message is InboxKit's); 409 invalid_state (not_inboxkit) for an inbox that is not an InboxKit mailbox; 409 conflict (address_in_use) when another live inbox has the new address; 503 when InboxKit is not available. Needs Delivery edit access (admins and editors by default). An inbox of another workspace is 404.
Parameters
400 workspace_required).Request body
application/json, optional.
@ (jane.doe, not [email protected]). The domain stays.Response 200
data is a InboxRenameModel.
curl -X POST "https://api.ken.so/v1/inboxes/812/rename" \
-H "Authorization: Bearer $KEN_API_KEY" \
-H "Ken-Version: 2026-11-02" \
-H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"localPart": "string"
}'{
"success": true,
"data": {
"inbox": {
"id": 5530,
"email": "[email protected]",
"firstName": "Alex",
"lastName": "Rivera",
"displayName": "Alex Rivera",
"signature": "Alex Rivera\nNorthwind Outbound",
"status": "active",
"role": "sending",
"provider": "google",
"domainId": 640,
"dailySendLimit": 30,
"profilePhotoSupport": "google",
"tagIds": [],
"createdAt": "2026-08-31T10:15:00Z",
"updatedAt": "2026-10-14T09:41:27Z",
"isPrimary": false,
"usedBy": {
"campaigns": [
{
"id": 4821,
"name": "Q4 SaaS founders",
"status": "active"
}
],
"accounts": false
},
"warmup": {
"daysLeft": 0
},
"healthScore": 94,
"lastSentAt": "2026-10-14T09:12:40Z"
},
"reconnected": true,
"warnings": [
"string"
]
}
}