Response envelope
Every execution — text or media, sync or async, on any provider — returns the same unified response. Your code handles a Claude completion, a GPT call, and an image generation identically.
{
"executionId": "exec_9f2c…",
"status": "succeeded",
"outputs": [
{ "type": "text", "text": "The customer is locked out after a password reset." }
],
"provider": { "type": "openrouter", "model": "anthropic/claude-sonnet-4.5", "requestId": "…" },
"usage": { "inputTokens": 812, "outputTokens": 96, "totalTokens": 908 },
"cost": 0.0027,
"timing": { "startedAt": "2026-08-10T07:17:55Z", "durationMs": 2483 },
"eval": { "passed": true },
"metadata": {}
}
Fields
| Field | Type | Notes |
|---|---|---|
executionId | string | Unique id for this execution |
status | string | succeeded, failed, queued, or running |
outputs | array | One or more outputs (see below) |
provider | object | { type, model, requestId? } — which provider/model actually answered |
usage | object | Token counts, when the provider reports them |
cost | number | Provider cost for this execution, in USD |
timing | object | { startedAt, durationMs } |
eval | object | Result of any attached eval rules |
async | object | Present for async jobs — includes the jobId to poll |
error | object | Present when status is failed |
raw | object | The provider’s raw response, when requested |
metadata | object | Any metadata you passed through |
Output items
Each item in outputs[] has a type and the matching payload:
type | Payload field(s) |
|---|---|
text | text |
json | json (a parsed object) |
image / video / audio / file | url (and mimeType, storageUrl, storageUri) |
for (const out of res.outputs) {
if (out.type === 'text') console.log(out.text);
else if (out.type === 'json') handle(out.json);
else console.log(out.url); // image / video / audio / file
}
Async results
When status is queued or running, poll GET /v1/:projectId/jobs/:jobId (or client.getJob(res.async.jobId)) until it becomes succeeded or failed; the final response carries the outputs.
Errors
On failure, status is failed and error describes what went wrong. HTTP-level problems (bad key, missing scope, unknown prompt) return the corresponding 4xx/5xx status with a JSON error body.