Skip to main content

Responses and errors

Every successful response wraps its payload in data. A failed request returns an HTTP status and a body with error, a message for people, and code, a constant for your code. Branch on code, and use the tables below to decide whether to retry.

Successful responses​

{ "data": { "session": { "id": "9b2e4f60-…", "status": "active" } } }
StatusWhen
200 OKReads, and most changes.
201 CreatedA request that creates something, such as a project, a session, a comment or a cron. Sending a message answers 201 too.
204 No ContentMost deletes. The body is empty.

A few responses break the pattern:

RequestStatusBody
DELETE /api/projects/{projectId}/settings/env-vars200{ "data": { "deleted": 3 } }, the number of variables removed.
DELETE /api/projects/{projectId}/preview/share200{ "data": { "share": null } }, whether or not a link existed.
https://app.kosuke.ai/api/openapi.json200The OpenAPI document itself, without data.

Pagination​

Lists that page do it in one of two ways. Both add meta.pagination next to data, and both set hasMore while more results remain. Other lists, such as projects, models and GitHub repositories, come in one response.

Page-based lists​

The session's jobs and the project's deploys take page (from 1) and pageSize (default 25, at most 100):

curl -s "https://app.kosuke.ai/api/projects/$PROJECT_ID/chat-sessions/$SESSION_ID/jobs/chat?page=2&pageSize=25" \
-H "Authorization: Bearer $KOSUKE_API_KEY"
{
"data": [{ "id": "…", "status": "completed", "jobNumber": 26 }],
"meta": {
"pagination": { "page": 2, "totalPages": 4, "pageSize": 25, "total": 87, "hasMore": true }
}
}

Ask for the next page while hasMore is true. A workspace's crons and a cron's runs take the same page and pageSize, and return their total inside data instead.

Cursor-based lists​

A project's chat sessions, your sessions across workspaces, and Activity take limit and cursor. A project's session list pages only when you send limit.

curl -s "https://app.kosuke.ai/api/projects/$PROJECT_ID/chat-sessions?limit=50" \
-H "Authorization: Bearer $KOSUKE_API_KEY"
{
"data": [{ "id": "…", "title": "Add a healthz endpoint", "status": "active" }],
"meta": {
"pagination": { "pageSize": 50, "total": 132, "hasMore": true, "nextCursor": "eyJ…" }
}
}

Send nextCursor back as cursor, with the same limit and filters, until nextCursor is null. The repository's branch list is the one exception. It returns nextCursor inside data, next to branches.

Error shape​

{ "error": "Validation error", "code": "VALIDATION_ERROR", "details": { "_errors": [], "name": { "_errors": ["Name is required"] } } }

details carries the field errors of a VALIDATION_ERROR, the amounts of a CREDIT_LIMIT_REACHED, and the steerId of a JOB_STOPPED_TEXT_RETURNED.

Status and error codes​

StatusCodeMeaningWhat to do
400BAD_REQUESTThe request is malformed, or the resource's state refuses it. error says which, for example a message to an Archived or Completed session.Fix the request or the state, then send again.
400SESSION_UNDER_REVIEWThe session is Under Review. Only a member's own message resumes it, so a message from a Cron or another session is refused. A member's message is refused too when the session went Under Review while it was on its way.Resume the session, or send the message yourself.
400VALIDATION_ERRORThe body or query failed validation.Fix the fields named in details.
401UNAUTHORIZEDThe API key is missing, unknown, revoked or expired.Create a new API key.
401GITHUB_RECONNECT_REQUIREDGitHub stopped accepting your GitHub Connection. Your API key is fine.Reconnect GitHub in Settings > You > Integrations.
402CREDIT_LIMIT_REACHEDThe workspace is blocked on billing.Stop until an admin sorts out billing. See Limits.
403FORBIDDENYour API key is valid, but the action is not allowed. You are not a member of the workspace, the action needs an owner or admin, or it needs the web app.Do not retry.
404NOT_FOUNDNo such resource, or no access to it. Project routes answer 404 for both.Check the ids. Do not retry.
409JOB_IN_PROGRESSA turn is running, so a message being sent from Up next must wait. A fresh chat-session message waits Up next instead, even when a turn starts while it is on its way.Leave it Up next. It goes when the turn ends.
409QUEUE_FULLUp next already holds 20 messages.Wait for one to go, or delete one.
409QUEUED_MESSAGE_CHANGEDThe Up next message changed or was sent while you edited it.Read Up next again, then save.
409QUEUED_MESSAGE_GONEThe message already left Up next.Read Up next again.
409STEER_UNAVAILABLENo turn of yours can take the steer right now, or the Up next message is a runtime command, is being edited, has just changed or is already on its way. The message stays Up next.Let it start its own turn.
409JOB_STOPPEDA person stopped the turn or deploy you named.Do not start another on your own.
409JOB_STOPPED_TEXT_RETURNEDA person stopped the turn before it took your steer. The message stays Up next.Leave it there. Up next is paused.
409JOB_ACTIVEA turn is running, so a file write, commit or push must wait.Try again when the turn ends.
409TURN_IN_FLIGHTA runtime command was sent to your Sensei Chat while its turn runs. In a chat session the command waits Up next instead.Wait for the turn to end.
409COMMAND_IN_FLIGHTA runtime command is still running, so a message being sent from Up next, a steer, a move to Backlog or another Sensei Chat command must wait. Fresh chat-session messages wait Up next instead.Wait for it to finish.
409SESSION_UPDATINGAnother change to the session is in progress.Send the same request again.
409SESSION_BUSYAnother request is changing the session right now, such as a start, a send or a runtime command.Send the same request again.
409SESSION_STATUS_CHANGEDThe session changed under the request.Read the session again before you send.
409SESSION_CHANGEDThe session changed while the request ran.Read the session again, then retry.
409SANDBOX_LIMIT_REACHEDThe workspace runs as many sandboxes as its plan allows.Free a slot, then send again.
409SANDBOX_STARTINGThe session's sandbox is still starting.Send the same request again shortly.
409SKILL_NAME_TAKENA skill with this name already exists.Pick another name.
409DEPLOY_IN_PROGRESSThe project is deploying. Only a Backlog session can be created, and none can be started.Wait for the deploy to end.
409DEPLOY_ACTIVEA deploy is already running, or still stopping.Wait for it to end.
409DEPLOY_RESUME_UNAVAILABLEThe stopped deploy can no longer be resumed.Start a new deploy.
409NOT_DEPLOYEDThe project is not deployed yet, so a Deploy Chat message has no deploy to continue.Start a deploy.
429TOO_MANY_REQUESTSToo many requests to a public share link or an invitation preview.Back off and retry.
500SERVER_ERRORSomething broke on Sensei's side.Retry once after a pause. If it repeats, get help.
503SERVICE_UNAVAILABLEA step failed and is worth repeating, or the feature is off.Retry with backoff. If error says the feature is off, stop.

Retry safely​

Retry the same request, with a growing pause, after SESSION_UPDATING, SESSION_BUSY, SANDBOX_STARTING and 503. Start at one second and double up to about 30 seconds.

Stop and read the situation after 402, JOB_STOPPED, SANDBOX_LIMIT_REACHED and QUEUE_FULL. Retrying them unchanged fails the same way.

A send whose response you never received may still have landed. Before you resend, list the session's jobs with GET /api/projects/{projectId}/chat-sessions/{sessionId}/jobs/chat and Up next with GET /api/projects/{projectId}/chat-sessions/{sessionId}/queue. A resent session create makes a second session, so search the project's sessions by title first.

Limits​

Credits​

When a workspace is blocked on billing, requests that start work or read a sandbox answer 402:

{
"error": "This workspace is blocked on billing.",
"code": "CREDIT_LIMIT_REACHED",
"details": { "usedUsd": 25.41, "limitUsd": 25 }
}

The 402 covers creating a session with a first message, starting a Backlog session, sending a message, running the compact runtime command and starting a deploy. It also covers reading files, the diff and git state, and committing and pushing. Filing a Backlog session and reading sessions and messages still work. A turn already running finishes.

The preview request answers 200 with creditLimitReached: true instead. GET /api/organizations/{workspaceId}/credits returns isOverLimit, so you can check before you start work. An admin clears the block under Plans and billing.

Other limits​

LimitValueWhat you see
Concurrent sandboxesSet by the plan. See Plans and billing.startFailure with reason: "sandbox_limit" on the preview's health, 409 SANDBOX_LIMIT_REACHED on a send, and 400 when you start a Backlog session.
Up next20 messages per session, and 20 in the Deploy Chat409 QUEUE_FULL
Attachments20 files per message, 10 MB each400 BAD_REQUEST
Attachment typesJPEG, PNG, GIF and WebP images. PDF, plain text, CSV, TSV, Markdown, XML, YAML, JSON, Excel and Word documents.400 BAD_REQUEST. Some models read no images or PDFs, and the message says so.
Diff comments sent with one message50400 VALIDATION_ERROR
Page size100 for most lists, 200 for ActivityLarger values are cut to the maximum.
Cron scheduleAt most one fire every 15 minutes400 BAD_REQUEST
Rate limits429 applies to the public share-link routes and the invitation preview429 TOO_MANY_REQUESTS

Next steps​