AI lines
The AI lines endpoints of the Kenso API.
List a contact's AI lines
/v1/contacts/{contactId}/ai-linesai-lines.listNeeds the ai_line_edit feature on your workspace. Until it is on, calls answer 404.
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
400 workspace_required).Response 200
data is a list of ContactAiLineModel. Each item has these fields. The response also carries pagination.
first_line).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"
{
"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
/v1/contacts/{contactId}/ai-lines/{aiLineId}ai-lines.updateNeeds the ai_line_edit feature on your workspace. Until it is on, calls answer 404.
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
400 workspace_required).Request body
application/json, optional.
Response 200
data is a ContactAiLineModel.
first_line).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"
}'{
"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
/v1/contacts/{contactId}/ai-lines/regenerateai-lines.regenerateNeeds the ai_line_edit feature on your workspace. Until it is on, calls answer 404.
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
400 workspace_required).Response 202
data is a AiRunModel.
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"
{
"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"
}
}