Kenso

Agent sandbox runs

The Agent sandbox runs endpoints of the Kenso API.

4 endpointsKen-Version: 1.1AuthenticationWorkspacesErrors

List your sandbox runs

GET/v1/agent-sandbox-runsagent-sandbox-runs.list

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

Try it on developer.ken.so

Your runs in this workspace, newest first, in the canonical list envelope: data is the array of runs and pagination.hasMore is true when older runs follow. active=true lists only live runs (queued, starting, running or stopping). limit is 1 to 50 (default 20), and cursor takes the previous page's nextCursor.

Errors:

- 400 validation_failed: limit is out of range or cursor is not a nextCursor from this list. - 404 not_found: a feature is off. - 503 service_unavailable with Retry-After: the agent work settings could not be read.

Parameters

Name
In
Type
Required
Description
active
In: query
boolean
optional
True lists only live runs (queued, starting, running or stopping).
limit
In: query
integer (int32)
optional
1 to 50, default 20.
cursor
In: query
string
optional
The previous page's nextCursor, unchanged, with the same active.
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
optional
The API version, a date in YYYY-MM-DD form. 1.1 is another name for the first dated version. Leave it out to use your API key's pinned version. Keys created in the Kenso app are pinned to the newest version; keys minted by the CLI login are not. A key with no pinned version and no header gets the legacy shape where the path has one, and 404 where the path exists only in this version. A date that is not a version answers 400 unsupported_version; any other value that is not a version is treated as legacy.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
The id of the workspace to act in. Leave it out when your API key reaches only one workspace. When the key reaches more than one, a request without this header answers 400 workspace_required. A workspace you are not a member of answers 404 not_found.

Response 200

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

Field
Type
Description
id
string
asr_ and 32 lowercase hex characters.
agent
string
The agent the run uses: claude, codex, antigravity, opencode, grok or cursor.
status
string
queued, starting, running, stopping or ended.
endReason
string
Why it ended (queue_empty, stopped, usage_limit, max_length, credits_used, agent_logged_out, answer_refused or failed), set once it is stopping; null before.
trigger
string
manual or automatic.
campaignId
integer (int64)
The campaign it works, or null: a run without a campaign covers the whole workspace.
kinds
array of string
The kinds it works, or null for every kind the workspace has on My agent.
createdAt
string (date-time)
startedAt
string (date-time)
endedAt
string (date-time)
stopRequestedAt
string (date-time)
When the person asked to stop the run (cancel); null until then. The status changes on the run supervisor's next pass.
accepted
integer (int32)
Answers accepted so far.
rejected
integer (int32)
Answers rejected so far.
waiting
integer (int32)
Items in the run's scope still waiting now; 0 once it ended.
minutes
integer (int32)
Minutes run so far while it is live; the billed minutes once it ended.
credits
number (double)
Credits for those minutes so far while it is live; the credits charged once it ended.
confinement
string
full, partial or none, or null until the run reports it.
estimate
AgentSandboxEstimate
What a run is expected to take and the most it can cost.
Request
curl -X GET "https://api.ken.so/v1/agent-sandbox-runs?limit=1" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 1.1" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
Response 200
{
  "success": true,
  "data": [
    {
      "id": "string",
      "agent": "string",
      "status": "string",
      "endReason": "string",
      "trigger": "string",
      "campaignId": 812,
      "kinds": [
        "string"
      ],
      "createdAt": "2026-09-23T15:02:11Z",
      "startedAt": "2026-09-23T15:02:11Z",
      "endedAt": "2026-09-23T15:02:11Z",
      "stopRequestedAt": "2026-09-23T15:02:11Z",
      "accepted": 1,
      "rejected": 1,
      "waiting": 1,
      "minutes": 1,
      "credits": 0.5,
      "confinement": "string",
      "estimate": {
        "waitingItems": 1,
        "expectedMinutes": 1,
        "ceilingMinutes": 1,
        "ceilingCredits": 0.5,
        "creditsPerHour": 0.5
      }
    }
  ],
  "pagination": {
    "nextCursor": "eyJpZCI6ODE1fQ",
    "hasMore": true,
    "total": 1,
    "isTotalCapped": true
  }
}

Estimate or start a sandbox run

POST/v1/agent-sandbox-runsagent-sandbox-runs.create

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

Try it on developer.ken.so

Body: agent (required: claude, codex, antigravity, opencode, grok or cursor, one you connected), campaignId, kinds (agent work kinds; left out for every kind on My agent), estimateOnly and maxCeilingCredits (the estimate.ceilingCredits you were shown). A run works only the kinds you may write. Kenso counts the items of those kinds waiting for your agent in that scope and estimates the run: estimate.expectedMinutes, estimate.ceilingMinutes (the run stops there), estimate.ceilingCredits (the most it can cost) and estimate.creditsPerHour. estimateOnly: true answers 200 with { estimate } and creates nothing. Otherwise Kenso holds ceilingCredits, queues the run and answers 202 with it; it charges the started minutes when the run ends and releases the rest. A run is created even when nothing is waiting: it ends queue_empty within a minute or two and is charged one minute. Poll GET /v1/agent-sandbox-runs/{runId}. One live run per person.

Errors:

- 400 validation_failed: an unknown or missing agent, an empty kinds or an unknown kind. - 402 plan_limit_reached with refusal.code INSUFFICIENT_CREDITS: the workspace cannot cover the ceiling. Nothing was started. - 402 member_credit_limit_reached: the ceiling is more than is left of your monthly credit limit in this workspace. Nothing was started. - 403 forbidden: you may write none of the kinds in scope (the access the work queue's claims need), for the estimate too. - 404 not_found: a feature is off, the campaign is not the workspace's, or the credential is not a person's. - 409 agent_not_connected: connect the agent in your Kenso sandbox first. - 409 run_active: you already have a live run. - 409 estimate_changed: with maxCeilingCredits, more work is waiting than when the run was estimated and its ceiling is now higher. Nothing was held: ask for the estimate again and show it. - 503 service_unavailable with Retry-After: the agent work settings or the credits could not be read, or Kenso could not confirm the run was created.

Open to any workspace member except a Client seat, and never to an API key held to a permission template.

Parameters

Name
In
Type
Required
Description
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
optional
The API version, a date in YYYY-MM-DD form. 1.1 is another name for the first dated version. Leave it out to use your API key's pinned version. Keys created in the Kenso app are pinned to the newest version; keys minted by the CLI login are not. A key with no pinned version and no header gets the legacy shape where the path has one, and 404 where the path exists only in this version. A date that is not a version answers 400 unsupported_version; any other value that is not a version is treated as legacy.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
The id of the workspace to act in. Leave it out when your API key reaches only one workspace. When the key reaches more than one, a request without this header answers 400 workspace_required. A workspace you are not a member of answers 404 not_found.
Idempotency-Key
In: header
string
optional
A unique value, such as a UUID, that makes a retry safe. Send the same key when you retry. For 24 hours, a repeat of the same request with the same key gets the first response again, with the Idempotent-Replayed: true header, and Kenso does not run the action twice. The same key with a different request answers 422 idempotency_key_reused. Keys are per workspace and at most 200 characters long. A repeat sent while the first request is still running can get 503 service_unavailable with Retry-After. Retry it with the same key. Kenso does not store a 5xx response, so a retry after one runs the action again.

Request body

application/json, optional.

Field
Type
Required
Description
agent
string
optional
claude, codex, antigravity, opencode, grok or cursor: an agent you connected.
campaignId
integer (int64)
optional
Only this campaign's work. The campaign must be the workspace's. Left out: the whole workspace.
kinds
array of string
optional
Only these kinds of agent work (meeting_brief, call_brief, workflow_prompt, qualification, segmentation, personalization, rewriting); left out for every kind on My agent.
estimateOnly
boolean
optional
True: answer with the estimate only and create nothing.
maxCeilingCredits
number (double)
optional
The estimate.ceilingCredits the person was shown. When the ceiling is now higher, the start is 409 estimate_changed and holds nothing: show the new estimate. Left out: no check.

Response 200

Also answers 202. data is a AgentSandboxRunEstimateOnly.

Field
Type
Description
estimate
AgentSandboxEstimate
What a run is expected to take and the most it can cost.
Request
curl -X POST "https://api.ken.so/v1/agent-sandbox-runs" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 1.1" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
  "agent": "string",
  "campaignId": 812,
  "kinds": [
    "string"
  ],
  "estimateOnly": true,
  "maxCeilingCredits": 0.5
}'
Response 200
{
  "success": true,
  "data": {
    "estimate": {
      "waitingItems": 1,
      "expectedMinutes": 1,
      "ceilingMinutes": 1,
      "ceilingCredits": 0.5,
      "creditsPerHour": 0.5
    }
  }
}

Get a sandbox run

GET/v1/agent-sandbox-runs/{runId}agent-sandbox-runs.get

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

Try it on developer.ken.so

One of your runs with its progress: accepted and rejected answers so far, waiting items still waiting in its scope, minutes and credits so far (the billed ones once it ended). Poll it every few seconds while status is not ended.

Errors:

- 404 not_found: no run of yours with this id in the workspace, or a feature is off. - 503 service_unavailable with Retry-After: the agent work settings could not be read.

Parameters

Name
In
Type
Required
Description
runId
In: path
string
required
The run's id, asr_....
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
optional
The API version, a date in YYYY-MM-DD form. 1.1 is another name for the first dated version. Leave it out to use your API key's pinned version. Keys created in the Kenso app are pinned to the newest version; keys minted by the CLI login are not. A key with no pinned version and no header gets the legacy shape where the path has one, and 404 where the path exists only in this version. A date that is not a version answers 400 unsupported_version; any other value that is not a version is treated as legacy.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
The id of the workspace to act in. Leave it out when your API key reaches only one workspace. When the key reaches more than one, a request without this header answers 400 workspace_required. A workspace you are not a member of answers 404 not_found.

Response 200

data is a AgentSandboxRun.

Field
Type
Description
id
string
asr_ and 32 lowercase hex characters.
agent
string
The agent the run uses: claude, codex, antigravity, opencode, grok or cursor.
status
string
queued, starting, running, stopping or ended.
endReason
string
Why it ended (queue_empty, stopped, usage_limit, max_length, credits_used, agent_logged_out, answer_refused or failed), set once it is stopping; null before.
trigger
string
manual or automatic.
campaignId
integer (int64)
The campaign it works, or null: a run without a campaign covers the whole workspace.
kinds
array of string
The kinds it works, or null for every kind the workspace has on My agent.
createdAt
string (date-time)
startedAt
string (date-time)
endedAt
string (date-time)
stopRequestedAt
string (date-time)
When the person asked to stop the run (cancel); null until then. The status changes on the run supervisor's next pass.
accepted
integer (int32)
Answers accepted so far.
rejected
integer (int32)
Answers rejected so far.
waiting
integer (int32)
Items in the run's scope still waiting now; 0 once it ended.
minutes
integer (int32)
Minutes run so far while it is live; the billed minutes once it ended.
credits
number (double)
Credits for those minutes so far while it is live; the credits charged once it ended.
confinement
string
full, partial or none, or null until the run reports it.
estimate
AgentSandboxEstimate
What a run is expected to take and the most it can cost.
Request
curl -X GET "https://api.ken.so/v1/agent-sandbox-runs/string" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 1.1" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
Response 200
{
  "success": true,
  "data": {
    "id": "string",
    "agent": "string",
    "status": "string",
    "endReason": "string",
    "trigger": "string",
    "campaignId": 812,
    "kinds": [
      "string"
    ],
    "createdAt": "2026-09-23T15:02:11Z",
    "startedAt": "2026-09-23T15:02:11Z",
    "endedAt": "2026-09-23T15:02:11Z",
    "stopRequestedAt": "2026-09-23T15:02:11Z",
    "accepted": 1,
    "rejected": 1,
    "waiting": 1,
    "minutes": 1,
    "credits": 0.5,
    "confinement": "string",
    "estimate": {
      "waitingItems": 1,
      "expectedMinutes": 1,
      "ceilingMinutes": 1,
      "ceilingCredits": 0.5,
      "creditsPerHour": 0.5
    }
  }
}

Stop a sandbox run

POST/v1/agent-sandbox-runs/{runId}/cancelagent-sandbox-runs.cancel

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

Try it on developer.ken.so

Asks Kenso to stop the run and answers with it as it reads right after, with stopRequestedAt set; its status changes on the next pass of the run supervisor, within about 20 seconds. A queued run then ends (endReason stopped) without starting, and nothing is charged. A starting or running run stops: claims it holds go back to the queue, and the minutes it ran are charged. An ended run comes back as it is. Asking again is safe.

Errors:

- 404 not_found: no run of yours with this id in the workspace, or a feature is off.

Parameters

Name
In
Type
Required
Description
runId
In: path
string
required
The run's id, asr_....
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
optional
The API version, a date in YYYY-MM-DD form. 1.1 is another name for the first dated version. Leave it out to use your API key's pinned version. Keys created in the Kenso app are pinned to the newest version; keys minted by the CLI login are not. A key with no pinned version and no header gets the legacy shape where the path has one, and 404 where the path exists only in this version. A date that is not a version answers 400 unsupported_version; any other value that is not a version is treated as legacy.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
The id of the workspace to act in. Leave it out when your API key reaches only one workspace. When the key reaches more than one, a request without this header answers 400 workspace_required. A workspace you are not a member of answers 404 not_found.

Response 200

data is a AgentSandboxRun.

Field
Type
Description
id
string
asr_ and 32 lowercase hex characters.
agent
string
The agent the run uses: claude, codex, antigravity, opencode, grok or cursor.
status
string
queued, starting, running, stopping or ended.
endReason
string
Why it ended (queue_empty, stopped, usage_limit, max_length, credits_used, agent_logged_out, answer_refused or failed), set once it is stopping; null before.
trigger
string
manual or automatic.
campaignId
integer (int64)
The campaign it works, or null: a run without a campaign covers the whole workspace.
kinds
array of string
The kinds it works, or null for every kind the workspace has on My agent.
createdAt
string (date-time)
startedAt
string (date-time)
endedAt
string (date-time)
stopRequestedAt
string (date-time)
When the person asked to stop the run (cancel); null until then. The status changes on the run supervisor's next pass.
accepted
integer (int32)
Answers accepted so far.
rejected
integer (int32)
Answers rejected so far.
waiting
integer (int32)
Items in the run's scope still waiting now; 0 once it ended.
minutes
integer (int32)
Minutes run so far while it is live; the billed minutes once it ended.
credits
number (double)
Credits for those minutes so far while it is live; the credits charged once it ended.
confinement
string
full, partial or none, or null until the run reports it.
estimate
AgentSandboxEstimate
What a run is expected to take and the most it can cost.
Request
curl -X POST "https://api.ken.so/v1/agent-sandbox-runs/string/cancel" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 1.1" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
Response 200
{
  "success": true,
  "data": {
    "id": "string",
    "agent": "string",
    "status": "string",
    "endReason": "string",
    "trigger": "string",
    "campaignId": 812,
    "kinds": [
      "string"
    ],
    "createdAt": "2026-09-23T15:02:11Z",
    "startedAt": "2026-09-23T15:02:11Z",
    "endedAt": "2026-09-23T15:02:11Z",
    "stopRequestedAt": "2026-09-23T15:02:11Z",
    "accepted": 1,
    "rejected": 1,
    "waiting": 1,
    "minutes": 1,
    "credits": 0.5,
    "confinement": "string",
    "estimate": {
      "waitingItems": 1,
      "expectedMinutes": 1,
      "ceilingMinutes": 1,
      "ceilingCredits": 0.5,
      "creditsPerHour": 0.5
    }
  }
}