GET
https://api.decisionnode.com /v1/batches/{id}/resultsAPI=https://api.decisionnode.com/v1
BATCH=batch_01J9ZB8Q3T
curl "$API/batches/$BATCH/results" \
-H "Authorization: Bearer $DECISIONNODE_API_KEY"Authentication#
AuthorizationheaderrequiredBearer dn_live_..., the same key as every call. A batch belongs to the key that created it: other keys, even in the same workspace, get404for it.
Path parameters#
idstringrequired- The batch id that Create a batch returned, for example
batch_01J9ZB8Q3T.
Query parameters#
format"json"- Leave it out for the whole file as JSON Lines.
jsonreturns one page of lines as a JSON object. offsetintegerdefault0- With
format=json: the first line of the page, counted from 0 in upload order. limitintegerdefault1,000- With
format=json: lines per page, 1 to 1,000.
For a small batch, or to read a large one a page at a time, ask for format=json and follow next_offset:
API=https://api.decisionnode.com/v1
BATCH=batch_01J9ZB8Q3T
# one page; ask again with offset set to the page's next_offset until it is null
curl -G "$API/batches/$BATCH/results" \
-H "Authorization: Bearer $DECISIONNODE_API_KEY" \
-d format=json -d offset=0 -d limit=1000Response#
Without format: 200 OK, Content-Type: application/, one line per request in upload order. With format=json: a page object.
{"custom_id":"ticket-48213","status":200,"body":{"model":"decisionnode-1.0","answers":{"route":{"type":"choice","choice":"billing","confidence":0.81,"probabilities":{"account":0.05,"billing":0.87,"bug":0.08}},"refund":{"type":"truth","truth":0.94}},"usage":{"input_tokens":47,"output_tokens":0}},"headers":{"x-request-id":"req_01J9ZE1A4K","x-decisionnode-model":"decisionnode-1.0","x-decisionnode-safety":"harm=0.002, self_harm=0.001"}}
{"custom_id":"ticket-48214","status":200,"body":{"model":"decisionnode-1.0","answers":{"route":{"type":"choice","choice":"bug","confidence":0.9,"probabilities":{"account":0.03,"billing":0.04,"bug":0.93}},"refund":{"type":"truth","truth":0.02}},"usage":{"input_tokens":45,"output_tokens":0}},"headers":{"x-request-id":"req_01J9ZE1A5M","x-decisionnode-model":"decisionnode-1.0","x-decisionnode-safety":"harm=0.001, self_harm=0.001"}}
{"custom_id":"ticket-48215","status":200,"body":{"model":"decisionnode-1.0","answers":{"route":{"type":"choice","choice":"account","confidence":0.84,"probabilities":{"account":0.89,"billing":0.06,"bug":0.05}},"refund":{"type":"truth","truth":0.03}},"usage":{"input_tokens":46,"output_tokens":0}},"headers":{"x-request-id":"req_01J9ZE1A6P","x-decisionnode-model":"decisionnode-1.0","x-decisionnode-safety":"harm=0.001, self_harm=0.002"}}A result line#
{
"custom_id": "ticket-48213",
"status": 200,
"body": {
"model": "decisionnode-1.0",
"answers": {
"route": {
"type": "choice",
"choice": "billing",
"confidence": 0.81,
"probabilities": { "account": 0.05, "billing": 0.87, "bug": 0.08 }
},
"refund": { "type": "truth", "truth": 0.94 }
},
"usage": { "input_tokens": 47, "output_tokens": 0 }
},
"headers": {
"x-request-id": "req_01J9ZE1A4K",
"x-decisionnode-model": "decisionnode-1.0",
"x-decisionnode-safety": "harm=0.002, self_harm=0.001"
}
}custom_idstring- The id you gave the request.
statusinteger | "expired" | "cancelled"- The HTTP status the live call returned (
200for answers, or the error status), or"expired"or"cancelled"for a request that never ran. bodyobject | null- The live response body:
model,answersandusagefor a200, the live error body (detail) otherwise.nullfor a request that never ran. headersobject- What the live call sends as response headers, since a file has none. Empty for a request that never ran or was refused when uploaded.
x-request-idstring- The request id. Quote it when you contact us.
x-decisionnode-modelstring- The pinned model version that answered.
x-decisionnode-safetystring- The safety check's probability per category, as on every live response.
x-decisionnode-image-tokensstring- The part of
usage.input_tokensthat came from images, on lines with images. x-decisionnode-refusalstring- On a
403: the category the safety check refused. x-decisionnode-billable-tokensstring- On a
403: the tokens the refusal bills,0today. x-decisionnode-errorstring- On an error: what went wrong, in words.
Lines that did not return answers#
{
"custom_id": "ticket-48216",
"status": 400,
"body": {
"detail": {
"error_type": "api_usage_error",
"message": "Unknown model: decisionode-latest"
}
},
"headers": {}
}format=json
resultsarray- The lines of this page, each as above.
offsetinteger- The
offsetyou asked for. limitinteger- The
limityou asked for. totalinteger- Lines in the whole file: the batch's
counters.requests. next_offsetinteger | null- The
offsetof the next page, ornullon the last one.
API=https://api.decisionnode.com/v1BATCH=batch_01J9ZB8Q3Tcurl "$API/batches/$BATCH/results" \ -H "Authorization: Bearer $DECISIONNODE_API_KEY"Errors#
| Status | Type | When | What to do |
|---|---|---|---|
400 | api_usage_error | A query value that cannot be read: an unknown format, offset below 0, limit outside 1 to 1,000 | Fix the query; the message names the value |
401 | authentication_error | The key is missing, unknown or revoked | Check the Authorization header |
404 | not_found_error | No batch with this id belongs to your key | Check the id and that you call with the key that created the batch |
409 | results_not_ready | The batch has not ended yet | Poll the batch until results_url is set |
410 | results_expired | The results were deleted 7 days after the batch ended | Resubmit the requests from your own copy |
429 | rate_limit_error | Over your request rate: batch calls count against it | Wait Retry-After seconds, then send the same call again |
500 | api_error | A fault on our side | Retry with backoff and jitter. A 5xx can come after the call took effect: before you create again, cancel any draft the failed create left behind (see Batch errors) |
529 | overloaded_error | The API cannot take the call right now | Wait Retry-After seconds, then retry with backoff |
Every error body is {"detail": {"error_type": "...", "message": "..."}}. Retry 408, 429 (rate_limit_error), 529 and any 5xx, waiting at least what Retry-After says when it is set; fix the call for the other 4xx. A 429 batch_limit_exceeded clears only when a batch ends or you cancel one. All the bodies are on Errors.
Limits#
| Limit | Value |
|---|---|
| Page size | Up to 1,000 lines with format=json |
| Retention | 7 days after ended_at, until results_expire_at |
Notes#
- Lines come in upload order, whatever order the requests ran in. Match them by
custom_id, not by position, if you reorder anything. - Read
statusbeforebody: acompletedbatch can hold400,402,403and500lines, each with the live error body. - A
500line failed on our side and was not billed; itsx-decisionnode-errorsays why. Resubmit it. - The answers in a line are byte for byte what the live call returns for the same body on the same model version.
- Download the file once and store it: it stays the same until it is deleted.