Image variables
The image tokens of a campaign's sequence, each one shared image or one image per lead: create, edit, estimate, test and regenerate them.
List a campaign's image variables
/v1/campaigns/{campaignId}/image-variablesimage-variables.listNeeds the campaign_images feature on your workspace. Until it is on, calls answer 404.
Ordered by key, at most 5, one page (hasMore is always false). Beside data: linkHostReady (the workspace has a link host to serve images from; without one no image variable can be created or sent), coverage (leads plus, per reference wire name, how many leads have that reference) and models (each image model with its estimated credits per per_prospect image). Requires the Campaigns page.
Parameters
400 workspace_required).Response 200
data is a list of ImageVariableModel. Each item has these fields. The response also carries pagination, linkHostReady, coverage, models.
hero_image for {{hero_image}}).shared or per_prospect.{{first_name}}.profile_photo, company_logo, sender_logo, website_screenshot, custom_image.models.1024x1024, 1536x1024 or 1024x1536.low, medium or high.previewUrl is a presigned link for the app, valid until previewExpiresAt.curl -X GET "https://api.ken.so/v1/campaigns/812/image-variables" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": [
{
"key": "string",
"kind": "string",
"prompt": "string",
"references": [
"string"
],
"model": "string",
"size": "string",
"quality": "string",
"spellingCheck": true,
"requiredForSending": true,
"enabled": true,
"altText": "string",
"sharedImage": {
"imageKey": "string",
"status": "string",
"errorCode": "string",
"previewUrl": "https://example.com",
"previewExpiresAt": "2026-09-23T15:02:11Z"
},
"counts": {
"ready": 1,
"pending": 1,
"failed": 1
},
"createdAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-09-23T15:02:11Z"
}
],
"pagination": {
"nextCursor": "eyJpZCI6ODE1fQ",
"hasMore": true,
"total": 1,
"isTotalCapped": true
},
"linkHostReady": true,
"coverage": {
"key": 1
},
"models": [
{
"id": "string",
"displayName": "string",
"creditsPerImage": 0.5
}
]
}Create an image variable
/v1/campaigns/{campaignId}/image-variablesimage-variables.createNeeds the campaign_images feature on your workspace. Until it is on, calls answer 404.
Returns 201 and Location. key shares the namespace of custom and AI variables and is normalized (Hero Image becomes hero_image); custom_image and a key a custom, AI or image variable of the campaign has are 409 variable_key_taken. No link host in the workspace is 409 link_host_required; a sixth variable is 409 image_variable_limit. A new variable starts off: enabled: true is a 400 on enabled, and false or absent is accepted. Turn it on with PATCH after reading its estimate. Requires Campaigns edit.
Parameters
400 workspace_required).Request body
application/json, optional.
Hero Image is stored as hero_image). Fixed after create.shared or per_prospect. Fixed after create.sender_logo.openai/gpt-image-2.5-sunburst.1024x1024.medium.true is a 400 on enabled. Turn it on with PATCH after reading its estimate.Response 201
data is a ImageVariableModel.
hero_image for {{hero_image}}).shared or per_prospect.{{first_name}}.profile_photo, company_logo, sender_logo, website_screenshot, custom_image.models.1024x1024, 1536x1024 or 1024x1536.low, medium or high.previewUrl is a presigned link for the app, valid until previewExpiresAt.curl -X POST "https://api.ken.so/v1/campaigns/812/image-variables" \
-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 '{
"key": "string",
"kind": "string",
"prompt": "string",
"references": [
"string"
],
"model": "string",
"size": "string",
"quality": "string",
"spellingCheck": true,
"requiredForSending": true,
"enabled": true,
"altText": "string"
}'{
"success": true,
"data": {
"key": "string",
"kind": "string",
"prompt": "string",
"references": [
"string"
],
"model": "string",
"size": "string",
"quality": "string",
"spellingCheck": true,
"requiredForSending": true,
"enabled": true,
"altText": "string",
"sharedImage": {
"imageKey": "string",
"status": "string",
"errorCode": "string",
"previewUrl": "https://example.com",
"previewExpiresAt": "2026-09-23T15:02:11Z"
},
"counts": {
"ready": 1,
"pending": 1,
"failed": 1
},
"createdAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-09-23T15:02:11Z"
}
}Get one image variable
/v1/campaigns/{campaignId}/image-variables/{variableKey}image-variables.getNeeds the campaign_images feature on your workspace. Until it is on, calls answer 404.
A shared variable carries its current image with a presigned previewUrl (1 hour). Requires the Campaigns page.
Parameters
400 workspace_required).Response 200
data is a ImageVariableModel.
hero_image for {{hero_image}}).shared or per_prospect.{{first_name}}.profile_photo, company_logo, sender_logo, website_screenshot, custom_image.models.1024x1024, 1536x1024 or 1024x1536.low, medium or high.previewUrl is a presigned link for the app, valid until previewExpiresAt.curl -X GET "https://api.ken.so/v1/campaigns/812/image-variables/string" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"key": "string",
"kind": "string",
"prompt": "string",
"references": [
"string"
],
"model": "string",
"size": "string",
"quality": "string",
"spellingCheck": true,
"requiredForSending": true,
"enabled": true,
"altText": "string",
"sharedImage": {
"imageKey": "string",
"status": "string",
"errorCode": "string",
"previewUrl": "https://example.com",
"previewExpiresAt": "2026-09-23T15:02:11Z"
},
"counts": {
"ready": 1,
"pending": 1,
"failed": 1
},
"createdAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-09-23T15:02:11Z"
}
}Update an image variable
/v1/campaigns/{campaignId}/image-variables/{variableKey}image-variables.updateNeeds the campaign_images feature on your workspace. Until it is on, calls answer 404.
Absent fields stay unchanged; prompt and altText are cleared by null or blank. key and kind never change (400 on that field). A changed prompt, reference set, model, size or quality replaces the images of leads with no sent or queued step that uses the variable; read the estimate first. enabled: false is always allowed and keeps the existing images. Requires Campaigns edit.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 200
data is a ImageVariableModel.
hero_image for {{hero_image}}).shared or per_prospect.{{first_name}}.profile_photo, company_logo, sender_logo, website_screenshot, custom_image.models.1024x1024, 1536x1024 or 1024x1536.low, medium or high.previewUrl is a presigned link for the app, valid until previewExpiresAt.curl -X PATCH "https://api.ken.so/v1/campaigns/812/image-variables/string" \
-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 '{
"key": "string",
"kind": "string",
"prompt": "string",
"references": [
"string"
],
"model": "string",
"size": "string",
"quality": "string",
"spellingCheck": true,
"requiredForSending": true,
"enabled": true,
"altText": "string"
}'{
"success": true,
"data": {
"key": "string",
"kind": "string",
"prompt": "string",
"references": [
"string"
],
"model": "string",
"size": "string",
"quality": "string",
"spellingCheck": true,
"requiredForSending": true,
"enabled": true,
"altText": "string",
"sharedImage": {
"imageKey": "string",
"status": "string",
"errorCode": "string",
"previewUrl": "https://example.com",
"previewExpiresAt": "2026-09-23T15:02:11Z"
},
"counts": {
"ready": 1,
"pending": 1,
"failed": 1
},
"createdAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-09-23T15:02:11Z"
}
}Delete an image variable
/v1/campaigns/{campaignId}/image-variables/{variableKey}image-variables.deleteNeeds the campaign_images feature on your workspace. Until it is on, calls answer 404.
Returns 204. 409 image_variable_in_use while any step of the campaign holds {{key}} in its body or subject: remove it there first, or disable the variable instead. Its images stay. Requires Campaigns edit.
Parameters
400 workspace_required).Response 204
curl -X DELETE "https://api.ken.so/v1/campaigns/812/image-variables/string" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
HTTP/1.1 204 No Content
Estimate what running an image variable would generate and cost
/v1/campaigns/{campaignId}/image-variables/{variableKey}/estimateimage-variables.estimateNeeds the campaign_images feature on your workspace. Until it is on, calls answer 404.
A read: nothing is written. The body holds optional draft fields (absent = the saved value). leadsNow is how many leads would get an image now, already counting the replaceCount leads whose current image the change would replace; creditsNow = leadsNow x creditsPerImage. A shared variable is one image and 0 per new lead. Every credit field is credits. Requires Campaigns edit.
Parameters
400 workspace_required).Request body
application/json, optional.
Response 200
data is a ImageVariableEstimateModel.
curl -X POST "https://api.ken.so/v1/campaigns/812/image-variables/string/estimate" \
-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 '{
"prompt": "string",
"references": [
"string"
],
"model": "string",
"size": "string",
"quality": "string",
"spellingCheck": true
}'{
"success": true,
"data": {
"leadsNow": 1,
"replaceCount": 1,
"creditsPerImage": 0.5,
"creditsNow": 0.5,
"creditsPerNewLead": 0.5
}
}Test a per_prospect image variable on up to 5 leads
/v1/campaigns/{campaignId}/image-variables/{variableKey}/testimage-variables.testNeeds the campaign_images feature on your workspace. Until it is on, calls answer 404.
Sync: generates for up to 5 eligible leads (leads with no image first, then leads whose image failed), charged per ready image, and returns the images (a lead whose generation failed outright is left out). They become those leads' images. A lead whose image Kenso staff blocked is never picked. Does not turn the variable on. A shared variable is 409 wrong_kind. Reserves one editor generation per lead it picks (at most 5, none when no lead is eligible), after those checks. Requires Campaigns edit.
Parameters
400 workspace_required).Response 200
data is a ImageVariableTestModel.
curl -X POST "https://api.ken.so/v1/campaigns/812/image-variables/string/test" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"images": [
{
"imageKey": "string",
"contactId": 812,
"variableKey": "string",
"status": "string",
"errorCode": "string",
"errorDetail": "string",
"width": 1,
"height": 1,
"previewUrl": "https://example.com",
"previewExpiresAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-09-23T15:02:11Z"
}
]
}
}Regenerate one lead's image
/v1/campaigns/{campaignId}/image-variables/{variableKey}/contacts/{contactId}/regenerateimage-variables.regenerate-contactNeeds the campaign_images feature on your workspace. Until it is on, calls answer 404.
Sync and charged per ready image; reserves 1 editor generation once the checks pass. Returns the new image, ready or failed; the previous image stays in use until a new one is ready. 409 image_in_use when the lead already has a sent or queued step that uses the variable, so it keeps that image. 409 blocked when Kenso staff blocked the lead's current image: a block covers that one image, not its slot, so a changed prompt still lets the generation job make the lead a new one, but this route does not replace it. A lead outside the campaign's image audience is 404; a shared variable is 409 wrong_kind. Requires Campaigns edit.
Parameters
400 workspace_required).Response 200
data is a CampaignImageModel.
curl -X POST "https://api.ken.so/v1/campaigns/812/image-variables/string/contacts/812/regenerate" \ -H "Authorization: Bearer $KEN_API_KEY" \ -H "Ken-Version: 2026-11-02" \ -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
{
"success": true,
"data": {
"imageKey": "string",
"contactId": 812,
"variableKey": "string",
"status": "string",
"errorCode": "string",
"errorDetail": "string",
"width": 1,
"height": 1,
"previewUrl": "https://example.com",
"previewExpiresAt": "2026-09-23T15:02:11Z",
"updatedAt": "2026-09-23T15:02:11Z"
}
}