Kenso

AI lines

The AI lines endpoints of the Kenso API.

AI3 endpointsKen-Version: 2026-11-02AuthenticationWorkspacesErrors

List a contact's AI lines

GET/v1/contacts/{contactId}/ai-linesai-lines.list

Needs the ai_line_edit feature on your workspace. Until it is on, calls answer 404.

Try it on developer.ken.so

One line per AI variable of the contact's campaign: the stored line its next send renders (the newest personalized line, or its rewrite when the prompt rewrites; the segment's prompt before the campaign's). Older runs and replaced lines are not listed. Ordered by variable, at most 200 lines, not paginated. A contact outside the workspace, deleted, or not in a campaign is not_found. Requires ReadAccess.

Parameters

Name
In
Type
Required
Description
contactId
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 list of ContactAiLineModel. Each item has these fields. The response also carries pagination.

Field
Type
Description
id
integer (int64)
The AI line id.
promptId
integer (int64)
The prompt that wrote the line.
variable
string
The template variable the line fills, the prompt's name (for example first_line).
text
string
The line's text.
rewrite
boolean
True when a rewriting prompt wrote the line from a personalized one.
segmentId
integer (int64)
The segment the line was written for. Omitted when the line is not segment-scoped.
stepOrder
integer (int32)
The sequence step the line was written for. Omitted when the line serves every step.
createdAt
string (date-time)
When the line was written.
Request
curl -X GET "https://api.ken.so/v1/contacts/812/ai-lines" \
  -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": 812,
      "promptId": 812,
      "variable": "string",
      "text": "string",
      "rewrite": true,
      "segmentId": 812,
      "stepOrder": 1,
      "createdAt": "2026-09-23T15:02:11Z"
    }
  ],
  "pagination": {
    "nextCursor": "eyJpZCI6ODE1fQ",
    "hasMore": true,
    "total": 1,
    "isTotalCapped": true
  }
}

Replace the text of one of a contact's AI lines

PATCH/v1/contacts/{contactId}/ai-lines/{aiLineId}ai-lines.update

Needs the ai_line_edit feature on your workspace. Until it is on, calls answer 404.

Try it on developer.ken.so

The next send of the lead renders the new text, and an approval draft that shows the lead is updated. Steps already sent keep what they sent. text is required, at most 4,000 characters; it gets the cleanup a generated line gets (emoji removed, dashes normalized, spaces collapsed) and must be 1 to 1,000 characters after it, else validation_failed. Another of the contact's lines that the send does not read (an older run, a personalized line its rewrite replaces) is 409 invalid_state and nothing changes; list the lines again and edit the one shown. A line that is not the contact's is not_found. Requires WriteAccess.

Parameters

Name
In
Type
Required
Description
contactId
In: path
integer (int64)
required
aiLineId
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
text
string
optional
The new line, 1 to 4,000 characters. It gets the cleanup a generated line gets (emoji removed, dashes normalized, spaces collapsed, line breaks kept) and must be at most 1,000 characters after it.

Response 200

data is a ContactAiLineModel.

Field
Type
Description
id
integer (int64)
The AI line id.
promptId
integer (int64)
The prompt that wrote the line.
variable
string
The template variable the line fills, the prompt's name (for example first_line).
text
string
The line's text.
rewrite
boolean
True when a rewriting prompt wrote the line from a personalized one.
segmentId
integer (int64)
The segment the line was written for. Omitted when the line is not segment-scoped.
stepOrder
integer (int32)
The sequence step the line was written for. Omitted when the line serves every step.
createdAt
string (date-time)
When the line was written.
Request
curl -X PATCH "https://api.ken.so/v1/contacts/812/ai-lines/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 '{
  "text": "string"
}'
Response 200
{
  "success": true,
  "data": {
    "id": 812,
    "promptId": 812,
    "variable": "string",
    "text": "string",
    "rewrite": true,
    "segmentId": 812,
    "stepOrder": 1,
    "createdAt": "2026-09-23T15:02:11Z"
  }
}

Write a contact's AI lines again

POST/v1/contacts/{contactId}/ai-lines/regenerateai-lines.regenerate

Needs the ai_line_edit feature on your workspace. Until it is on, calls answer 404.

Try it on developer.ken.so

Clears the contact's personalized lines (and the rewritten lines built on them) and queues a personalization run for that contact alone, charged as one lead. Returns 202 with the run; poll GET /v1/ai-runs/{aiRunId}. When the run lands, an approval draft that shows the lead is updated. A lead already sent or exported, with a send queued, or in an unfinished AI run is 409 invalid_state and nothing changes. AI quota limits answer 429 quota_exceeded and too few credits 402, both before anything is cleared, so the lead keeps its lines. Only a full AI run queue (503) after the clear leaves the lead without lines until a retry or the next scheduled AI run. Requires WriteAccess.

Parameters

Name
In
Type
Required
Description
contactId
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 202

data is a AiRunModel.

Field
Type
Description
id
string
status
string
flow
string
campaignId
integer (int64)
segmentId
integer (int64)
provider
string
model
string
createdAt
string (date-time)
startedAt
string (date-time)
completedAt
string (date-time)
contactsProcessed
integer (int32)
batchId
string
error
string
Request
curl -X POST "https://api.ken.so/v1/contacts/812/ai-lines/regenerate" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 2026-11-02" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
Response 202
{
  "success": true,
  "data": {
    "id": "string",
    "status": "string",
    "flow": "string",
    "campaignId": 812,
    "segmentId": 812,
    "provider": "string",
    "model": "string",
    "createdAt": "2026-09-23T15:02:11Z",
    "startedAt": "2026-09-23T15:02:11Z",
    "completedAt": "2026-09-23T15:02:11Z",
    "contactsProcessed": 1,
    "batchId": "string",
    "error": "string"
  }
}