Kenso

Agent work

The Agent work endpoints of the Kenso API.

4 endpointsKen-Version: 1.1AuthenticationWorkspacesErrors

Get the agent work queue

GET/v1/agent-workagent-work.get

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

Try it on developer.ken.so

Returns every kind, always all seven in hand-out order, with its executor, the items waiting for your agent (waiting, 0 for a kind on kenso_ai), the items held by open claims (claimed), what holds the kind back (heldBy: billing_blocked, out_of_credits or ai_paused, else null) and when an answer of it was last accepted. With campaignId, the counts are that campaign's. Kinds you may not write are listed too.

Errors:

- 404 not_found: the workspace does not have the agent_work feature, or the campaign is not the workspace's. - 503 service_unavailable with Retry-After: the agent work settings could not be read. Try again.

Open to any workspace member except a Client seat.

Parameters

Name
In
Type
Required
Description
campaignId
In: query
integer (int64)
optional
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 AgentWorkStatus.

Field
Type
Description
kinds
array of AgentWorkKind
All seven kinds, always, in hand-out order (work with a deadline first).
Request
curl -X GET "https://api.ken.so/v1/agent-work" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 1.1" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
Response 200
{
  "success": true,
  "data": {
    "kinds": [
      {
        "kind": "string",
        "executor": "string",
        "waiting": 1,
        "claimed": 1,
        "heldBy": "string",
        "lastAcceptedAt": "2026-09-23T15:02:11Z"
      }
    ]
  }
}

Claim agent work

POST/v1/agent-work/claimsagent-work.create-claim

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

Try it on developer.ken.so

Hands out up to limit items (1 to 50, default 10) of the first kind, in hand-out order, that waits for your agent and that you may write: only the kinds in kinds when you send it, only campaignId's work when you send it. A kind on kenso_ai, one Kenso cannot hand out yet, or one held back (heldBy) is skipped. One claim holds one kind, and one campaign for a campaign kind. The claim holds its items for leaseMinutes (5 to 240, default 30): Kenso's AI and other claims leave them alone until then. Each item carries its target, the prompt Kenso's AI would have run and what the answer must look like (answer.format json or text, and answer.schema, a JSON Schema object or null). Nothing waiting is 200 with id null and no items, and stores no claim. A claim stops short of limit when its items would pass about 900 KB; the rest stay in the queue. Send an Idempotency-Key to retry safely: a resend with the same key returns the same claim.

Errors:

- 400 validation_failed: an unknown kind, an empty kinds, or limit or leaseMinutes out of range. Each problem is one details[] entry, such as kinds[1]. - 404 not_found: the workspace does not have the agent_work feature, or the campaign is not the workspace's. - 429 rate_limited: more than 120 claims a minute or 1,800 an hour for the workspace. - 503 service_unavailable with Retry-After: the agent work settings could not be read. Nothing was handed out. Try again.

Open to any workspace member except a Client seat; hands out only the kinds the caller may write.

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
kinds
array of string
optional
The kinds to take, in any order; left out for every kind. Kinds are still handed out in hand-out order.
campaignId
integer (int64)
optional
Only this campaign's work (campaign kinds). The campaign must be the workspace's.
limit
integer (int32)
optional
The most items to take, 1 to 50. Default 10.
leaseMinutes
integer (int32)
optional
How long the claim holds its items, in minutes, 5 to 240. Default 30.

Response 200

data is a AgentWorkClaim.

Field
Type
Description
id
string
The claim id (awc_ and 22 URL-safe characters). Null when nothing was waiting.
kind
string
The one kind this claim holds; null when nothing was waiting.
campaignId
integer (int64)
The campaign of a campaign kind's claim; null otherwise.
expiresAt
string (date-time)
When the claim lets go of its unanswered items, in UTC; null when nothing was waiting.
items
array of AgentWorkItem
The items to answer. Empty when nothing was waiting.
Request
curl -X POST "https://api.ken.so/v1/agent-work/claims" \
  -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 '{
  "kinds": [
    "string"
  ],
  "campaignId": 812,
  "limit": 1,
  "leaseMinutes": 1
}'
Response 200
{
  "success": true,
  "data": {
    "id": "string",
    "kind": "string",
    "campaignId": 812,
    "expiresAt": "2026-09-23T15:02:11Z",
    "items": [
      {
        "id": "string",
        "kind": "string",
        "target": {
          "type": "string",
          "id": "string",
          "campaignId": 812
        },
        "prompt": {
          "system": "string",
          "user": "string"
        },
        "answer": {
          "format": "string",
          "schema": null,
          "instruction": "string"
        }
      }
    ]
  }
}

Submit agent work answers

POST/v1/agent-work/claims/{claimId}/answersagent-work.submit-answers

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

Try it on developer.ken.so

Takes in up to 50 answers to the claim's items: { "agent": { "cli", "model" }, "answers": [ { "itemId", "output" } ] }. output is a JSON object for a json item and a string for a text item, at most 64 KB. Returns one result per answer, in the order sent: accepted (stored where Kenso's AI would have stored it); rejected with a reason (invalid_format, too_large, unknown_item or a check the answer failed; the item is closed and its work goes back to the queue); expired (the claim ran out or was released, or the record no longer needs an answer); duplicate (the item already has an answer, or one is being taken in). Each result also has retryable: true only when Kenso could not take the answer in and the item is still held (rejected with failed_checks), so send that answer again; false for every other result. Always 200 when the claim exists, whatever each answer's result. Answer items of a claim in as many calls as you like: the claim closes once every item is answered. The agent's cli and model are saved on the claim. Send an Idempotency-Key to retry safely: an answer stored once is never stored twice.

Errors:

- 400 validation_failed: no answers, more than 50, an answer that is not an object, or an agent name over 100 characters. - 403 forbidden: you may not write the claim's kind. - 404 not_found: the workspace does not have the agent_work feature, or the claim is not the workspace's. - 429 rate_limited: more than 300 submits a minute or 6,000 an hour for the workspace.

Open to any workspace member except a Client seat who may write the claim's kind.

Parameters

Name
In
Type
Required
Description
claimId
In: path
string
required
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
AgentWorkAgentBody
optional
The agent that wrote the answers, saved on the claim. Optional.
answers
array of AgentWorkAnswerBody
optional
1 to 50 answers, each to an item of this claim.

Response 200

data is a AgentWorkSubmit.

Field
Type
Description
results
array of AgentWorkAnswerResult
One result per answer, in the order sent.
accepted
integer (int32)
How many answers were accepted.
rejected
integer (int32)
How many answers were rejected.
Request
curl -X POST "https://api.ken.so/v1/agent-work/claims/string/answers" \
  -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": {
    "cli": "string",
    "model": "string"
  },
  "answers": [
    {
      "itemId": "string",
      "output": null
    }
  ]
}'
Response 200
{
  "success": true,
  "data": {
    "results": [
      {
        "itemId": "string",
        "status": "string",
        "reason": "string",
        "message": "string",
        "retryable": true
      }
    ],
    "accepted": 1,
    "rejected": 1
  }
}

Release an agent work claim

DELETE/v1/agent-work/claims/{claimId}agent-work.release-claim

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

Try it on developer.ken.so

Gives the claim's unanswered items back to the queue now and closes the claim; answers already stored stay. Returns how many items went back. Releasing a claim that is already closed (answered, released or expired) is 200 with released 0.

Errors:

- 403 forbidden: you may not write the claim's kind. - 404 not_found: the workspace does not have the agent_work feature, or the claim is not the workspace's.

Open to any workspace member except a Client seat who may write the claim's kind.

Parameters

Name
In
Type
Required
Description
claimId
In: path
string
required
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 AgentWorkRelease.

Field
Type
Description
released
integer (int32)
How many held items went back to the queue. 0 for a claim already closed.
Request
curl -X DELETE "https://api.ken.so/v1/agent-work/claims/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": {
    "released": 1
  }
}