Skip to content

Errors and retries

A call to answer a text ends one of three ways:

Status Body Saved
200 The result, status: "ok" Yes
502 The result, status: "failed" Yes
4xx or 500 An error body with a code and a message No
503 Service Unavailable, with no code, while a server restarts No

A 502 is not an error body. It is the failed result, in the format you asked for, with answers: null and an error in words:

502 Bad Gateway
{
"id": "0192f5c3-2b4e-7d10-8a61-5e0f9c7d2a13",
"ref": "TCK-8812",
"prism": "support-routing",
"version": 3,
"status": "failed",
"error": "The model took too long to answer, so we stopped after 15 seconds.",
"took_ms": 15012,
"created_at": "2026-09-23T09:15:40.502Z",
"answers": null
}

Every other failure has the error body, in JSON whatever format you asked for:

400 Bad Request
{
"error": {
"code": "validation_failed",
"message": "Missing fields: subject"
}
}

The errors reference lists every status, code and message.

Status Retry? Why
400 No The request is wrong. Fix it first.
401 No The key is missing, wrong or revoked.
404 No The prism, version or result does not exist in this account, or is archived.
409 No The idempotency key or the retry conflicts. Read the message.
413, 415 No The body is too large or not JSON. Fix it first.
500 Yes A bug on our side. Retry a few times with a pause, then stop.
502 Yes The model failed. The result is saved and can be retried.
503 Yes A server is restarting. Nothing was saved or sent to the model.
Timeout or network error Yes You can't tell whether the result was saved, so retry with the same key.

POST /v1/results/{result_id}/retry

The retry endpoint sends a failed result's stored fields to the model again and saves the answer as a new result.

curl -X POST https://api.prismlet.com/v1/results/0192f5c3-2b4e-7d10-8a61-5e0f9c7d2a13/retry \
-H "Authorization: Bearer $PRISMLET_API_KEY"
200 OK
{
"id": "0192f5c4-9e27-7c55-b3d8-41a6f0e8c9b2",
"ref": "TCK-8812",
"prism": "support-routing",
"version": 3,
"status": "ok",
"error": null,
"took_ms": 640,
"created_at": "2026-09-23T09:16:05.931Z",
"answers": {
"team": "billing",
"team_probability": 0.91,
"urgent": "yes",
"tone": "annoyed",
"tone_average": 2.05
}
}
  • The response is the new result, with its own id, on 200 or 502.
  • It runs against the exact version and fields of the failed result, even when the prism has newer versions.
  • Only a failed result can be retried. Retrying one that succeeded answers 409 with Only a failed result can be retried.
  • A failed result can be retried once. A second retry answers 409 with This result was already retried as <id>., naming the new result. Read that one, and if it failed too, retry it in turn.
  • A result of an archived prism can't be retried. It answers 404 with This prism is archived, so it cannot answer.
  • An idempotency key held by the failed result moves to the new one.
  • Send no body. A Content-Type: application/json header with an empty body answers 400 with Malformed request.

A timeout on your side doesn't tell you whether Prismlet saved the result. Send an idempotency_key and you can repeat the call and still get one result for it.

{
"ref": "TCK-8812",
"fields": {
"subject": "Charged twice this month",
"text": "Hi, I was billed twice for September. Please refund the second charge before Friday."
},
"idempotency_key": "tck-8812-1"
}

What a repeat with the same key returns depends on what the key already holds:

The key holds The repeat
Nothing Answers the text as a normal call.
A result that succeeded Returns that result with 200 without asking the model. fields, version and ref in the new body are ignored.
A result that failed Retries it, as the retry endpoint does, and returns the new result on 200 or 502. The key moves to the new result.
A result of another prism Answers 409 with This idempotency key was already used for another prism.
  • A repeat of a failed result retries the fields stored with it, not the fields in your new body. If you want a changed text answered, use a new key.
  • Because the key moves on every retry, repeating a call after a 502 until it answers 200 is safe, and the key ends up on one successful result.
  • Two calls with the same key at the same moment both get the one stored result, though both may be sent to the model.
  • Keys are unique across the whole account and shared with the app, whose file runs use keys of their own. Derive yours from your record, such as tck-8812-1, and change the suffix when you want the record answered again.
  • The prism is still checked first, so a repeat against an archived prism answers 404. The body is still validated, so a repeat with a malformed body answers 400.

The JavaScript and Python versions send a call with an idempotency key and repeat it on a timeout, a network error, a 500 or a 502, waiting 1, 2 and then 4 seconds. Every other status comes straight back. The body must carry an idempotency_key, or a repeat can answer the text twice.

curl https://api.prismlet.com/v1/prisms/support-routing/results \
--fail --max-time 45 --retry 3 --retry-connrefused \
-H "Authorization: Bearer $PRISMLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ref": "TCK-8812",
"fields": {
"subject": "Charged twice this month",
"text": "Hi, I was billed twice for September. Please refund the second charge before Friday."
},
"idempotency_key": "tck-8812-1"
}'

--retry repeats after a timeout, a 500 or a 502, among others, and doubles its wait each time from one second. With --fail, curl prints only the successful attempt's body, and for a 4xx or a last 5xx it prints the status on stderr instead. It does not repeat a connection that drops in the middle of a call. --retry-all-errors, in curl 7.71 or later, repeats that too, but it also repeats every 4xx.

After the last attempt you may still hold a 502. The failed result is saved, so run the same call later with the same key and it retries the result then.