Kalpana Docs
Reference

Errors

Status codes, the error body, and how to retry safely.

Errors use an HTTP status and a JSON body:

{
  "defined": true,
  "code": "BAD_REQUEST",
  "status": 400,
  "message": "An archived batch takes no new jobs"
}

Log the status, message, request path, and your own correlation id. Never log the full API key.

StatuscodeMeaningWhat to do
400BAD_REQUESTInvalid value or reference, such as a layer that does not exist or a page that is not in the workspace. Job and batch requests list every problem in data.issues.Fix the request.
401UNAUTHORIZEDMissing, invalid, or revoked key.Check the x-api-key header.
402PAYMENT_REQUIREDNot enough credits to run, or the feature needs an active subscription (webhooks and callback URLs).Add credits, reduce the work, or subscribe.
403FORBIDDENYour role or key lacks the permission, the key cannot use this workspace, or the key has no workspace or access set (a legacy key).Check the permission on the endpoint page, or edit the key.
404NOT_FOUNDThe resource does not exist in this workspace, or the workspace does not exist or you are not a member (Workspace not found).Check the id and workspace.
409CONFLICTThe state does not allow it, such as running a job that has already rendered, or updating a template that changed since you read it.Refresh the resource first.
413noneThe body of a job or batch write is larger than 4 MiB. The body is { "error": "request_too_large", "message": "Request exceeds 4 MiB." }.Send fewer rows, or split the batch.
422UNPROCESSABLE_ENTITYThe input is well formed but not acceptable.Correct the fields.
429TOO_MANY_REQUESTSThe key exceeded 100 requests per minute. The message is API key rate limit exceeded.Back off and retry.
500INTERNAL_SERVER_ERRORUnexpected failure. Some rejected runs are also reported as 500 with the reason in message.Read the message; retry reads.
503SERVICE_UNAVAILABLETemporarily unavailable.Retry after a delay.

Requests that fail schema validation, such as a missing field or a value of the wrong type, are rejected with 400 before reaching the endpoint. The message is Input validation failed and data.issues lists each problem with its path:

{
  "defined": false,
  "code": "BAD_REQUEST",
  "status": 400,
  "message": "Input validation failed",
  "data": {
    "issues": [
      { "expected": "string", "code": "invalid_type", "path": ["workspace"], "message": "Invalid input: expected string, received undefined" }
    ]
  }
}

Job and batch requests that fail on their values answer 400 with every problem at once. Each entry has a field, a code and a message, plus the item's job index or the row's row index:

{
  "defined": true,
  "code": "BAD_REQUEST",
  "status": 400,
  "message": "Invalid rows. rows[1].Headlin: No layer \"Headlin\" in this template. Its layers: Headline, Photo, Badge.",
  "data": {
    "issues": [
      { "row": 1, "field": "Headlin", "code": "unknown_layer", "message": "No layer \"Headlin\" in this template. Its layers: Headline, Photo, Badge." }
    ]
  }
}

The codes are listed in Modifications.

A 5xx body carries data.traceId. Quote it when you contact support, so the failed request can be found.

Retry policy

Retry GET requests on 429, 500, and 503 with exponential backoff and random jitter, and cap the number of attempts. For POST requests that create something, check whether the resource already exists before retrying so a lost response does not create a duplicate.

Do not retry 400, 401, 403, 404, or 409 without changing the request or the state it depends on.

Was this page helpful?

Updated 9 Nov 2026

On this page