Read an execution and its trace
Read the status of an execution while it runs, and its trace node by node once it has moved.
An execution is one request walked through a flow. It is opened by the request to the flow — POST /v1/operations/execute — and keeps the version of the flow it started on. The operations of this page read it: its status, which is what a client waits on, and its trace, node by node. The console shows the same trace on the page of an execution, opened from the Executions tab of a flow.
The status and the trace
GET /v1/executions/{id}/statusanswers with the fields of the answer to the request:status,output,error_code,error_message,cost,cache,waiting_onandtrace_url. While the execution is not over it addsretry_after_seconds, the pause Slen suggests before the next read. Read it to wait for an execution.GET /v1/executions/{id}answers with the trace: the execution with its flow —flow_nameis the flow's name as it is now —, its version, when it started and finished, and two lists —nodesandevents.
Both take the scope read. A key reads the executions of its own project. An execution of another project, or one that does not exist, answers 404 with the code flow_execution_not_found. The executions of one flow are listed on Flows.
What the trace holds
nodeshas a row for each node the walk has finished: the port it left by inoutput_port, its cost, how long it took. A node is written once it is done, so a node the execution waits at is not there yet. A node that ends a path — Return Response, Reject Request — has no port, andoutput_portisnull.A row also names the node and what it decided.
labelis the name the author gave the node in that version,nullwithout one.codeis the node's own decision — the refusal of a Budget Check, the code of a Reject Request,approvedof an approval — and may differ from the execution'serror_code, which is what the caller received.modelis the model of the last attempt of an AI Model node, or the model a Budget Check read its node budget for.A model call lists its attempts in the row of its AI Model node: one attempt for each provider connection it tried, with the connection, the pool, the model it sent (
model_code) and what came of it.eventstells the walk in order, numbered byseq: the estimates and holds, the provider answers and failures, the pauses and the decisions. An event carries amounts, ids and verdicts — never a prompt, an input of the flow or an answer of a model.
The events of a trace are kept for 30 days, and an execution with its nodes for 90 days, unless the service is set up otherwise.
How an execution ended
status says how a request ended, and What the answer says lists every status. error_code and error_message say why one did not complete. Besides the codes of the API, the runtime closes an execution it can no longer walk with a code of its own — Error codes shows what such an execution reads like.
uncertain— it is not known how a model call of the execution ended: the provider did not answer in time, or a call it ran in the background could no longer be asked about.error_codeisoperation_uncertain. The hold of the call stays until it expires, because the provider may have been paid, and Slen does not repeat the call. When the outcome is unknown says what to do.failedwithbackground_hold_expired— a model call ran in the background, and its hold was settled by another capture while it waited. The call ended without asking the provider for its answer, and the provider may still bill it.failedwithexecution_timeout— the walk ran out of time. When a model had already answered, its call was paid for, andcost.actualstill arrives.
The cost of an execution
cost.estimated is the estimates the model calls of the execution were authorized at, added up. cost.actual is what they were captured for, and it comes after the answer: the calls are settled in the background, usually within a minute or two.
cost.actualstaysnullwhile the execution runs, and while any of its calls still waits for its capture, so an execution with two model calls never shows the cost of one.It stays
nullfor good when nothing was captured: a refusal, a cached answer, a failure at the provider.Once it is set, it does not change.
Reading the trace catches up with a cost whose settlement was missed, so a trace read after the settlement shows it.
Operations
The trace of one flow run
GET /v1/executions/{id}
- Scope:
read - Available in the SDK for PHP and Node.js
Node by node, event by event, with the cost on each.
Parameters
| Parameter | Description |
|---|---|
id requiredpath | Snowflake identifier, as a string.
|
Responses
The execution trace
{
"data": {
"execution_id": "74438200973594624",
"flow_id": "74438200973594624",
"flow_version_id": "74438200973594624",
"operation": "generate_email",
"operation_id": "74438200973594624",
"status": "running",
"error_code": "string",
"error_message": "string",
"cost": {
"estimated": "0.02700000",
"actual": "0.02700000"
},
"cache": {
"hit": true,
"cached_at": "2026-10-02T09:30:00Z"
},
"started_at": "2026-10-02T09:30:00Z",
"finished_at": "2026-10-02T09:30:00Z",
"duration_ms": 1,
"flow_name": "string",
"nodes": [
{
"node_key": "string",
"node_type": "sdk_request",
"status": "completed",
"output_port": "string",
"cost": "0.02700000",
"duration_ms": 1,
"started_at": "2026-10-02T09:30:00Z",
"finished_at": "2026-10-02T09:30:00Z",
"metadata": {},
"attempts": [
{
"attempt_id": "74438200973594624",
"attempt_number": 1,
"connection_id": "74438200973594624",
"pool_id": "74438200973594624",
"status": "string",
"error_code": "string",
"latency_ms": 1,
"cost": "0.02700000",
"provider_request_id": "74438200973594624",
"model_code": "gpt-4o-mini"
}
],
"label": "string",
"model": "gpt-4o-mini",
"code": "string"
}
],
"events": [
{
"seq": 1,
"type": "accepted",
"node_key": "string",
"occurred_at": "2026-10-02T09:30:00Z",
"payload": {}
}
]
}
}Errors
| Status | Codes | When |
|---|---|---|
| 401 | No credential, or one that is not valid | |
| 403 | Authenticated, but not allowed: scope ( | |
| 404 | No such resource for this tenant. Somebody else's resource — and a resource of a project the caller does not reach — answers the same way on purpose: the two must not be distinguishable. |
Headers
X-Request-Id
The body of every error is the error envelope.
The polling view of one flow run
GET /v1/executions/{id}/status
- Scope:
read - Available in the SDK for PHP and Node.js
Status, cost, what the run waits on, and the answer once there is one — the endpoint an SDK polls. Answered from a Redis snapshot when there is one and from the row otherwise, byte for byte the same either way. A run of a project the caller does not reach is 404 either way — the snapshot carries its project. Use GET /v1/executions/{id} for the node-by-node trace.
Parameters
| Parameter | Description |
|---|---|
id requiredpath | Snowflake identifier, as a string.
|
Responses
The current state of the execution
{
"data": {
"execution_id": "74438200973594624",
"status": "running",
"operation": "generate_email",
"output": {},
"error_code": "string",
"error_message": "string",
"cost": {
"estimated": "0.02700000",
"actual": "0.02700000"
},
"cache": {
"hit": true,
"cached_at": "2026-10-02T09:30:00Z"
},
"waiting_on": {
"node_key": "string",
"type": "queue_node",
"resume_at": "2026-10-02T09:30:00Z"
},
"trace_url": "string",
"retry_after_seconds": 1
}
}Errors
| Status | Codes | When |
|---|---|---|
| 401 | No credential, or one that is not valid | |
| 403 | Authenticated, but not allowed: scope ( | |
| 404 | No such resource for this tenant. Somebody else's resource — and a resource of a project the caller does not reach — answers the same way on purpose: the two must not be distinguishable. |
Headers
X-Request-Id
The body of every error is the error envelope.
Examples
Read the trace
The id is execution_id of the answer to the request. The answer is the execution with its nodes and events, in the shape the block above describes.
curl https://api.slen.ai/api/v1/executions/74438200973594700 \
-H "Authorization: Bearer $SLEN_API_KEY"Read the status
The execution waits at its node review for a person's decision. There is no resume_at, and retry_after_seconds suggests when to read again.
curl https://api.slen.ai/api/v1/executions/74443028719599616/status \
-H "Authorization: Bearer $SLEN_API_KEY"{
"data": {
"execution_id": "74443028719599616",
"status": "waiting",
"operation": "generate_email",
"output": null,
"error_code": null,
"error_message": null,
"cost": {
"estimated": null,
"actual": null
},
"cache": {
"hit": false,
"cached_at": null
},
"waiting_on": {
"node_key": "review",
"type": "approval",
"resume_at": null
},
"trace_url": "/v1/executions/74443028719599616",
"retry_after_seconds": 30
}
}Where to go next
Async runs and waiting — wait for an execution with the SDK.
When the outcome is unknown — an execution that ended
uncertain.Operations — the request that opens an execution, and the record of each model call.
Inspect an execution — the same executions in the console.
Built from openapi b070e1f, sdk contract 6a2e0e0, php 4089db3, node 0fa87be