Kenso

Inboxes

Your sending inboxes: connect Gmail, Microsoft or SMTP, update settings, verify, disconnect and control warmup.

Deliverability11 endpointsKen-Version: 2026-11-02AuthenticationWorkspacesErrors

Start a Gmail or Microsoft connect

POST/v1/inboxes/connect-sessionsinboxes.create-connect-session

Try it on developer.ken.so

provider 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

Name
In
Type
Required
Description
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Request body

application/json, optional.

Field
Type
Required
Description
provider
string
optional
purpose
string
optional
returnTo
string
optional
Optional dashboard path the connect returns to, for example /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.

Field
Type
Description
provider
string
google or microsoft.
purpose
string
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).
appName
string
The OAuth app the user grants: "Kenso Workspace" for primary and calendar, "Kenso Mail" for campaign.
clientId
string
The OAuth app's public client id, for an admin who has to trust the app first.
authorizationUrl
string
adminUrl
string
Where an admin trusts the app: Google Admin console, or the Microsoft admin-consent URL.
adminConsentUrl
string
Microsoft only: the Entra admin-consent URL for this app.
expiresAt
string (date-time)
Request
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"
}'
Response 201
{
  "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

Name
In
Type
Required
Description
Status
In: query
string
optional
Cursor
In: query
string
optional
Limit
In: query
integer (int32)
optional
AvailableForCampaignId
In: query
integer (int64)
optional
IsPrimary
In: query
boolean
optional
true lists only primary inboxes (a member's own mailbox on the workspace's primary domain, as isPrimary on the model), false only the rest.
Role
In: query
string
optional
sending, replies or retired: lists only inboxes with that role. Combines with status and isPrimary, not with availableForCampaignId.
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Response 200

data is a list of InboxModel. Each item has these fields. The response also carries pagination.

Field
Type
Description
id
integer (int64)
email
string
firstName
string
lastName
string
displayName
string
signature
string
status
string
role
string
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.
captureUntil
string (date-time)
When a 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.
provider
string
domainId
integer (int64)
dailySendLimit
integer (int32)
forwarding
string
forwardingDestination
string
profileImageUrl
string
The mailbox photo to show: the photo Kenso set on the mailbox, else the photo InboxKit reports for it. LinkedIn CDN URLs are dropped. Omitted when there is none, and on availableForCampaignId lists.
profilePhotoSupport
string
Whether Kenso can set this mailbox's sender photo: 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.
profilePhotoStatus
string
Whether the photo Kenso set on the mailbox landed: 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.
profilePhotoStatusAt
string (date-time)
When Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatus was last set, UTC: for pending, when InboxKit took the photo.
profilePhotoError
string
Why the photo failed, only with Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatusfailed.
tagIds
array of integer (int64)
createdAt
string (date-time)
updatedAt
string (date-time)
pausedAt
string (date-time)
When a member paused outreach from this inbox, UTC. Null when it is not paused. A paused inbox holds campaign steps, triggers and approved Accounts 1:1 email; warmup and reply sync keep running. Independent of Ken.Scraper.API.Canonical.InboxModel.Status.
isKenSendable
boolean
sendingProvider
string
The sending provider slug (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.
isIngestReady
boolean
ownerMemberId
integer (int64)
The workspace member whose own mailbox this is. Omitted for a shared campaign inbox. An owned inbox never joins a campaign pool or warmup.
isPrimary
boolean
True when the inbox is owned by a member and its address sits on one of the workspace's domains: its email domain or any domain listed under Settings > Company. Derived on read, so it follows a later change to that list. Only a primary inbox sends the member's 1:1 email.
connectionApp
string
Which Kenso OAuth app the Google or Microsoft connection was granted to: ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.
trackOpens
boolean
The owner's Track opens option. Off by default. When on, replies the member sends from this mailbox in the Inbox carry one open pixel; their 1:1 Accounts email never does. Present only on a member's own mailbox (Ken.Scraper.API.Canonical.InboxModel.OwnerMemberId set); omitted for a shared campaign inbox.
usedBy
UsedByModel
What an inbox or LinkedIn account is used for: the live campaigns that send through it, and whether the 1:1 Accounts lane does.
warmup
InboxWarmupSummaryModel
sendBlock
InboxSendBlockModel
healthScore
integer (int32)
The Kenso Health Score, 0-100, from the latest InboxKit health snapshot. Omitted when InboxKit has reported no health for the inbox, and on availableForCampaignId lists.
tenantHost
string
The Microsoft 365 tenant of a Microsoft or Azure inbox, <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.
lastSentAt
string (date-time)
The inbox's last send the provider accepted, UTC. Warmup sends do not count. Omitted when it sent nothing in the last 30 days, or when that read failed.
connection
InboxConnectionModel
Health of Kenso's own connection to a mailbox, served on inbox.connection.
health
InboxHealthModel
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).
Request
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"
Response 200
{
  "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

Name
In
Type
Required
Description
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Request body

application/json, optional.

Field
Type
Required
Description
email
string
optional
username
string
optional
password
string
optional
smtpHost
string
optional
smtpPort
integer (int32)
optional
imapHost
string
optional
imapPort
integer (int32)
optional
smtpStartTls
boolean
optional
ownerMemberId
integer (int64)
optional
Make this the caller's own mailbox. Must equal the caller's member id, and the workspace needs Kenso Accounts. Omit for a shared campaign inbox.
preset
string
optional
A mailbox provider preset, for example 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.
replyToInboxId
integer (int64)
optional
With a preset that has no IMAP (azure_smtp): the workspace inbox Ken reads replies from. Required there, ignored otherwise.

Response 201

data is a InboxModel.

Field
Type
Description
id
integer (int64)
email
string
firstName
string
lastName
string
displayName
string
signature
string
status
string
role
string
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.
captureUntil
string (date-time)
When a 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.
provider
string
domainId
integer (int64)
dailySendLimit
integer (int32)
forwarding
string
forwardingDestination
string
profileImageUrl
string
The mailbox photo to show: the photo Kenso set on the mailbox, else the photo InboxKit reports for it. LinkedIn CDN URLs are dropped. Omitted when there is none, and on availableForCampaignId lists.
profilePhotoSupport
string
Whether Kenso can set this mailbox's sender photo: 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.
profilePhotoStatus
string
Whether the photo Kenso set on the mailbox landed: 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.
profilePhotoStatusAt
string (date-time)
When Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatus was last set, UTC: for pending, when InboxKit took the photo.
profilePhotoError
string
Why the photo failed, only with Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatusfailed.
tagIds
array of integer (int64)
createdAt
string (date-time)
updatedAt
string (date-time)
pausedAt
string (date-time)
When a member paused outreach from this inbox, UTC. Null when it is not paused. A paused inbox holds campaign steps, triggers and approved Accounts 1:1 email; warmup and reply sync keep running. Independent of Ken.Scraper.API.Canonical.InboxModel.Status.
isKenSendable
boolean
sendingProvider
string
The sending provider slug (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.
isIngestReady
boolean
ownerMemberId
integer (int64)
The workspace member whose own mailbox this is. Omitted for a shared campaign inbox. An owned inbox never joins a campaign pool or warmup.
isPrimary
boolean
True when the inbox is owned by a member and its address sits on one of the workspace's domains: its email domain or any domain listed under Settings > Company. Derived on read, so it follows a later change to that list. Only a primary inbox sends the member's 1:1 email.
connectionApp
string
Which Kenso OAuth app the Google or Microsoft connection was granted to: ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.
trackOpens
boolean
The owner's Track opens option. Off by default. When on, replies the member sends from this mailbox in the Inbox carry one open pixel; their 1:1 Accounts email never does. Present only on a member's own mailbox (Ken.Scraper.API.Canonical.InboxModel.OwnerMemberId set); omitted for a shared campaign inbox.
usedBy
UsedByModel
What an inbox or LinkedIn account is used for: the live campaigns that send through it, and whether the 1:1 Accounts lane does.
warmup
InboxWarmupSummaryModel
sendBlock
InboxSendBlockModel
healthScore
integer (int32)
The Kenso Health Score, 0-100, from the latest InboxKit health snapshot. Omitted when InboxKit has reported no health for the inbox, and on availableForCampaignId lists.
tenantHost
string
The Microsoft 365 tenant of a Microsoft or Azure inbox, <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.
lastSentAt
string (date-time)
The inbox's last send the provider accepted, UTC. Warmup sends do not count. Omitted when it sent nothing in the last 30 days, or when that read failed.
connection
InboxConnectionModel
Health of Kenso's own connection to a mailbox, served on inbox.connection.
health
InboxHealthModel
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).
Request
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
}'
Response 201
{
  "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"
  }
}

paused 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

Name
In
Type
Required
Description
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Request body

application/json, optional: object.

Response 200

data is a InboxBulkResult.

Field
Type
Description
updatedCount
integer (int32)
Inboxes updated. With profileImageUrl, the inboxes whose photo InboxKit accepted; the rest are in Ken.Scraper.API.Canonical.InboxBulkResult.Failed.
failed
array of InboxBulkFailure
Request
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 '{}'
Response 200
{
  "success": true,
  "data": {
    "updatedCount": 1,
    "failed": [
      {
        "id": 812,
        "message": "string"
      }
    ]
  }
}

Only 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

Name
In
Type
Required
Description
inboxId
In: path
integer (int64)
required
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Response 200

data is a InboxModel.

Field
Type
Description
id
integer (int64)
email
string
firstName
string
lastName
string
displayName
string
signature
string
status
string
role
string
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.
captureUntil
string (date-time)
When a 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.
provider
string
domainId
integer (int64)
dailySendLimit
integer (int32)
forwarding
string
forwardingDestination
string
profileImageUrl
string
The mailbox photo to show: the photo Kenso set on the mailbox, else the photo InboxKit reports for it. LinkedIn CDN URLs are dropped. Omitted when there is none, and on availableForCampaignId lists.
profilePhotoSupport
string
Whether Kenso can set this mailbox's sender photo: 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.
profilePhotoStatus
string
Whether the photo Kenso set on the mailbox landed: 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.
profilePhotoStatusAt
string (date-time)
When Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatus was last set, UTC: for pending, when InboxKit took the photo.
profilePhotoError
string
Why the photo failed, only with Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatusfailed.
tagIds
array of integer (int64)
createdAt
string (date-time)
updatedAt
string (date-time)
pausedAt
string (date-time)
When a member paused outreach from this inbox, UTC. Null when it is not paused. A paused inbox holds campaign steps, triggers and approved Accounts 1:1 email; warmup and reply sync keep running. Independent of Ken.Scraper.API.Canonical.InboxModel.Status.
isKenSendable
boolean
sendingProvider
string
The sending provider slug (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.
isIngestReady
boolean
ownerMemberId
integer (int64)
The workspace member whose own mailbox this is. Omitted for a shared campaign inbox. An owned inbox never joins a campaign pool or warmup.
isPrimary
boolean
True when the inbox is owned by a member and its address sits on one of the workspace's domains: its email domain or any domain listed under Settings > Company. Derived on read, so it follows a later change to that list. Only a primary inbox sends the member's 1:1 email.
connectionApp
string
Which Kenso OAuth app the Google or Microsoft connection was granted to: ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.
trackOpens
boolean
The owner's Track opens option. Off by default. When on, replies the member sends from this mailbox in the Inbox carry one open pixel; their 1:1 Accounts email never does. Present only on a member's own mailbox (Ken.Scraper.API.Canonical.InboxModel.OwnerMemberId set); omitted for a shared campaign inbox.
usedBy
UsedByModel
What an inbox or LinkedIn account is used for: the live campaigns that send through it, and whether the 1:1 Accounts lane does.
warmup
InboxWarmupSummaryModel
sendBlock
InboxSendBlockModel
healthScore
integer (int32)
The Kenso Health Score, 0-100, from the latest InboxKit health snapshot. Omitted when InboxKit has reported no health for the inbox, and on availableForCampaignId lists.
tenantHost
string
The Microsoft 365 tenant of a Microsoft or Azure inbox, <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.
lastSentAt
string (date-time)
The inbox's last send the provider accepted, UTC. Warmup sends do not count. Omitted when it sent nothing in the last 30 days, or when that read failed.
connection
InboxConnectionModel
Health of Kenso's own connection to a mailbox, served on inbox.connection.
health
InboxHealthModel
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).
Request
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"
Response 200
{
  "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"
  }
}

Update an inbox

PATCH/v1/inboxes/{inboxId}inboxes.update

Try it on developer.ken.so

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

Name
In
Type
Required
Description
inboxId
In: path
integer (int64)
required
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Request body

application/json, optional: object.

Response 200

data is a InboxModel.

Field
Type
Description
id
integer (int64)
email
string
firstName
string
lastName
string
displayName
string
signature
string
status
string
role
string
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.
captureUntil
string (date-time)
When a 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.
provider
string
domainId
integer (int64)
dailySendLimit
integer (int32)
forwarding
string
forwardingDestination
string
profileImageUrl
string
The mailbox photo to show: the photo Kenso set on the mailbox, else the photo InboxKit reports for it. LinkedIn CDN URLs are dropped. Omitted when there is none, and on availableForCampaignId lists.
profilePhotoSupport
string
Whether Kenso can set this mailbox's sender photo: 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.
profilePhotoStatus
string
Whether the photo Kenso set on the mailbox landed: 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.
profilePhotoStatusAt
string (date-time)
When Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatus was last set, UTC: for pending, when InboxKit took the photo.
profilePhotoError
string
Why the photo failed, only with Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatusfailed.
tagIds
array of integer (int64)
createdAt
string (date-time)
updatedAt
string (date-time)
pausedAt
string (date-time)
When a member paused outreach from this inbox, UTC. Null when it is not paused. A paused inbox holds campaign steps, triggers and approved Accounts 1:1 email; warmup and reply sync keep running. Independent of Ken.Scraper.API.Canonical.InboxModel.Status.
isKenSendable
boolean
sendingProvider
string
The sending provider slug (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.
isIngestReady
boolean
ownerMemberId
integer (int64)
The workspace member whose own mailbox this is. Omitted for a shared campaign inbox. An owned inbox never joins a campaign pool or warmup.
isPrimary
boolean
True when the inbox is owned by a member and its address sits on one of the workspace's domains: its email domain or any domain listed under Settings > Company. Derived on read, so it follows a later change to that list. Only a primary inbox sends the member's 1:1 email.
connectionApp
string
Which Kenso OAuth app the Google or Microsoft connection was granted to: ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.
trackOpens
boolean
The owner's Track opens option. Off by default. When on, replies the member sends from this mailbox in the Inbox carry one open pixel; their 1:1 Accounts email never does. Present only on a member's own mailbox (Ken.Scraper.API.Canonical.InboxModel.OwnerMemberId set); omitted for a shared campaign inbox.
usedBy
UsedByModel
What an inbox or LinkedIn account is used for: the live campaigns that send through it, and whether the 1:1 Accounts lane does.
warmup
InboxWarmupSummaryModel
sendBlock
InboxSendBlockModel
healthScore
integer (int32)
The Kenso Health Score, 0-100, from the latest InboxKit health snapshot. Omitted when InboxKit has reported no health for the inbox, and on availableForCampaignId lists.
tenantHost
string
The Microsoft 365 tenant of a Microsoft or Azure inbox, <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.
lastSentAt
string (date-time)
The inbox's last send the provider accepted, UTC. Warmup sends do not count. Omitted when it sent nothing in the last 30 days, or when that read failed.
connection
InboxConnectionModel
Health of Kenso's own connection to a mailbox, served on inbox.connection.
health
InboxHealthModel
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).
Request
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 '{}'
Response 200
{
  "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

POST/v1/inboxes/{inboxId}/verifyinboxes.verify

Try it on developer.ken.so

Needs Delivery edit.

Parameters

Name
In
Type
Required
Description
inboxId
In: path
integer (int64)
required
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Response 200

data is a InboxModel.

Field
Type
Description
id
integer (int64)
email
string
firstName
string
lastName
string
displayName
string
signature
string
status
string
role
string
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.
captureUntil
string (date-time)
When a 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.
provider
string
domainId
integer (int64)
dailySendLimit
integer (int32)
forwarding
string
forwardingDestination
string
profileImageUrl
string
The mailbox photo to show: the photo Kenso set on the mailbox, else the photo InboxKit reports for it. LinkedIn CDN URLs are dropped. Omitted when there is none, and on availableForCampaignId lists.
profilePhotoSupport
string
Whether Kenso can set this mailbox's sender photo: 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.
profilePhotoStatus
string
Whether the photo Kenso set on the mailbox landed: 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.
profilePhotoStatusAt
string (date-time)
When Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatus was last set, UTC: for pending, when InboxKit took the photo.
profilePhotoError
string
Why the photo failed, only with Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatusfailed.
tagIds
array of integer (int64)
createdAt
string (date-time)
updatedAt
string (date-time)
pausedAt
string (date-time)
When a member paused outreach from this inbox, UTC. Null when it is not paused. A paused inbox holds campaign steps, triggers and approved Accounts 1:1 email; warmup and reply sync keep running. Independent of Ken.Scraper.API.Canonical.InboxModel.Status.
isKenSendable
boolean
sendingProvider
string
The sending provider slug (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.
isIngestReady
boolean
ownerMemberId
integer (int64)
The workspace member whose own mailbox this is. Omitted for a shared campaign inbox. An owned inbox never joins a campaign pool or warmup.
isPrimary
boolean
True when the inbox is owned by a member and its address sits on one of the workspace's domains: its email domain or any domain listed under Settings > Company. Derived on read, so it follows a later change to that list. Only a primary inbox sends the member's 1:1 email.
connectionApp
string
Which Kenso OAuth app the Google or Microsoft connection was granted to: ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.
trackOpens
boolean
The owner's Track opens option. Off by default. When on, replies the member sends from this mailbox in the Inbox carry one open pixel; their 1:1 Accounts email never does. Present only on a member's own mailbox (Ken.Scraper.API.Canonical.InboxModel.OwnerMemberId set); omitted for a shared campaign inbox.
usedBy
UsedByModel
What an inbox or LinkedIn account is used for: the live campaigns that send through it, and whether the 1:1 Accounts lane does.
warmup
InboxWarmupSummaryModel
sendBlock
InboxSendBlockModel
healthScore
integer (int32)
The Kenso Health Score, 0-100, from the latest InboxKit health snapshot. Omitted when InboxKit has reported no health for the inbox, and on availableForCampaignId lists.
tenantHost
string
The Microsoft 365 tenant of a Microsoft or Azure inbox, <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.
lastSentAt
string (date-time)
The inbox's last send the provider accepted, UTC. Warmup sends do not count. Omitted when it sent nothing in the last 30 days, or when that read failed.
connection
InboxConnectionModel
Health of Kenso's own connection to a mailbox, served on inbox.connection.
health
InboxHealthModel
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).
Request
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"
Response 200
{
  "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

POST/v1/inboxes/{inboxId}/disconnectinboxes.disconnect

Try it on developer.ken.so

Needs Delivery edit.

Parameters

Name
In
Type
Required
Description
inboxId
In: path
integer (int64)
required
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Response 200

data is a InboxModel.

Field
Type
Description
id
integer (int64)
email
string
firstName
string
lastName
string
displayName
string
signature
string
status
string
role
string
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.
captureUntil
string (date-time)
When a 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.
provider
string
domainId
integer (int64)
dailySendLimit
integer (int32)
forwarding
string
forwardingDestination
string
profileImageUrl
string
The mailbox photo to show: the photo Kenso set on the mailbox, else the photo InboxKit reports for it. LinkedIn CDN URLs are dropped. Omitted when there is none, and on availableForCampaignId lists.
profilePhotoSupport
string
Whether Kenso can set this mailbox's sender photo: 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.
profilePhotoStatus
string
Whether the photo Kenso set on the mailbox landed: 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.
profilePhotoStatusAt
string (date-time)
When Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatus was last set, UTC: for pending, when InboxKit took the photo.
profilePhotoError
string
Why the photo failed, only with Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatusfailed.
tagIds
array of integer (int64)
createdAt
string (date-time)
updatedAt
string (date-time)
pausedAt
string (date-time)
When a member paused outreach from this inbox, UTC. Null when it is not paused. A paused inbox holds campaign steps, triggers and approved Accounts 1:1 email; warmup and reply sync keep running. Independent of Ken.Scraper.API.Canonical.InboxModel.Status.
isKenSendable
boolean
sendingProvider
string
The sending provider slug (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.
isIngestReady
boolean
ownerMemberId
integer (int64)
The workspace member whose own mailbox this is. Omitted for a shared campaign inbox. An owned inbox never joins a campaign pool or warmup.
isPrimary
boolean
True when the inbox is owned by a member and its address sits on one of the workspace's domains: its email domain or any domain listed under Settings > Company. Derived on read, so it follows a later change to that list. Only a primary inbox sends the member's 1:1 email.
connectionApp
string
Which Kenso OAuth app the Google or Microsoft connection was granted to: ken_mail (campaign mailboxes) or ken_workspace (a member's own mailbox). Omitted for SMTP and unconnected inboxes.
trackOpens
boolean
The owner's Track opens option. Off by default. When on, replies the member sends from this mailbox in the Inbox carry one open pixel; their 1:1 Accounts email never does. Present only on a member's own mailbox (Ken.Scraper.API.Canonical.InboxModel.OwnerMemberId set); omitted for a shared campaign inbox.
usedBy
UsedByModel
What an inbox or LinkedIn account is used for: the live campaigns that send through it, and whether the 1:1 Accounts lane does.
warmup
InboxWarmupSummaryModel
sendBlock
InboxSendBlockModel
healthScore
integer (int32)
The Kenso Health Score, 0-100, from the latest InboxKit health snapshot. Omitted when InboxKit has reported no health for the inbox, and on availableForCampaignId lists.
tenantHost
string
The Microsoft 365 tenant of a Microsoft or Azure inbox, <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.
lastSentAt
string (date-time)
The inbox's last send the provider accepted, UTC. Warmup sends do not count. Omitted when it sent nothing in the last 30 days, or when that read failed.
connection
InboxConnectionModel
Health of Kenso's own connection to a mailbox, served on inbox.connection.
health
InboxHealthModel
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).
Request
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"
Response 200
{
  "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

GET/v1/inboxes/{inboxId}/warmupinboxes.get-warmup

Try it on developer.ken.so

status 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

Name
In
Type
Required
Description
inboxId
In: path
integer (int64)
required
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Response 200

data is a InboxWarmupModel.

Field
Type
Description
status
string
not_started, pending, in_progress, paused, completed, maintenance, failed, or degraded. Derived from the live warmup provider's status when one tracks the inbox, otherwise from the legacy inbox warmup column. An Azure inbox with no warmup subscription (cancelled or never bought) is failed: Kenso cannot enroll Azure. Vendor-neutral: no provider name on the wire.
enabled
boolean
Warmup is switched on: the provider is warming the inbox or activating its warmup.
startedAt
string (date-time)
When warmup started. Falls back to the first day a live warmup provider reported warmup sends when the inbox row has no start time.
completedAt
string (date-time)
readiness
InboxWarmupReadinessModel
enrollmentFailure
InboxWarmupEnrollmentFailureModel
Request
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"
Response 200
{
  "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

PATCH/v1/inboxes/{inboxId}/warmupinboxes.update-warmup

Try it on developer.ken.so

enabled: 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

Name
In
Type
Required
Description
inboxId
In: path
integer (int64)
required
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Request body

application/json, optional: object.

Response 200

data is a InboxWarmupModel.

Field
Type
Description
status
string
not_started, pending, in_progress, paused, completed, maintenance, failed, or degraded. Derived from the live warmup provider's status when one tracks the inbox, otherwise from the legacy inbox warmup column. An Azure inbox with no warmup subscription (cancelled or never bought) is failed: Kenso cannot enroll Azure. Vendor-neutral: no provider name on the wire.
enabled
boolean
Warmup is switched on: the provider is warming the inbox or activating its warmup.
startedAt
string (date-time)
When warmup started. Falls back to the first day a live warmup provider reported warmup sends when the inbox row has no start time.
completedAt
string (date-time)
readiness
InboxWarmupReadinessModel
enrollmentFailure
InboxWarmupEnrollmentFailureModel
Request
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 '{}'
Response 200
{
  "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
    }
  }
}

Only 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

Name
In
Type
Required
Description
inboxId
In: path
integer (int64)
required
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
Workspace to act in. Required when your credential can reach more than one workspace (otherwise 400 workspace_required).

Request body

application/json, optional.

Field
Type
Required
Description
localPart
string
optional
The new username: the part before the @ (jane.doe, not [email protected]). The domain stays.

Response 200

data is a InboxRenameModel.

Field
Type
Description
inbox
InboxModel
reconnected
boolean
True when Kenso reconnected the inbox's sending connection under the new address.
warnings
array of string
Follow-up steps that did not finish (the reconnect, for example). The rename itself succeeded.
Request
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"
}'
Response 200
{
  "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"
    ]
  }
}