Threads & Results — API Reference
Package: dodil.scriptum.v1 · Service: ScriptumService
A thread is a single execution of a script version. Threads run in the cloud — you create one, the platform schedules and runs it as a durable, resumable unit, and you read status, events, results, and artifacts back over the API. There is nothing to configure about where it runs.
gRPC reaches every method at dodil.scriptum.v1.ScriptumService/<Method>; the HTTP gateway mirrors each one under /v1/scriptum. HTTP bodies are pbjson (camelCase); gRPC -d uses proto snake_case; int64 fields are JSON strings; bytes fields are base64 over HTTP.
| RPC | HTTP |
|---|---|
CreateThread | POST /v1/scriptum/threads |
GetThread | GET /v1/scriptum/threads/{thread_id} |
ListThreads | GET /v1/scriptum/threads |
CancelThread | POST /v1/scriptum/threads/{thread_id}/cancel |
ResumeThread | POST /v1/scriptum/threads/{thread_id}/resume |
WatchThread | GET /v1/scriptum/threads/{thread_id}/watch (server-stream) |
WatchStep | GET /v1/scriptum/threads/{thread_id}/steps/{step_path}/watch (server-stream) |
GetThreadResult | GET /v1/scriptum/threads/{thread_id}/result |
StreamThreadResult | GET /v1/scriptum/threads/{thread_id}/result/stream (server-stream) |
StreamStepResult | GET /v1/scriptum/threads/{thread_id}/steps/stream (server-stream) |
ListArtifacts | GET /v1/scriptum/threads/{thread_id}/artifacts |
CreateThread
Starts a thread to run a script. Specify the script name, the version to run (0 = active version), and input_json. The thread runs in the cloud; you get back a thread_id to track it.
Request
| Field | Type | Notes |
|---|---|---|
script_name | string | Required. Script to execute. |
version | int32 | Version to run (0 = active version). |
input_json | string | Input parameters as a JSON string (your data). |
timeout | string | Override default timeout, e.g. 5m, 1h. |
metadata | map<string, string> | Arbitrary key-value labels for the thread. |
callback_url | string | Webhook called when the thread completes. |
load_env | bool | Load tenant env vars into the run. |
HTTP
curl -sS -X POST "https://api.dev.dodil.io/v1/scriptum/threads" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG" \
-H "Content-Type: application/json" \
-d '{
"scriptName": "my-etl-pipeline",
"version": 0,
"inputJson": "{\"source\": \"data.csv\"}",
"timeout": "5m",
"loadEnv": true,
"metadata": { "run": "nightly" }
}'Response
HTTP
{
"threadId": "thr_abc123",
"status": "THREAD_STATUS_PENDING",
"createdAtMs": "1748390400000"
}GetThread
Current status and progress of a thread.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread to retrieve. |
HTTP
curl -sS "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG"Response
Returns a Thread directly.
The Thread type
| Field | Type | Notes |
|---|---|---|
thread_id | string | |
script_name | string | |
script_version | int32 | Resolved version actually running. |
status | ThreadStatus | |
current_step_path | string | Hierarchical path of the active step, e.g. 1.0.2. |
total_steps | int32 | Top-level step count. |
current_step_name | string | |
metadata | map<string, string> | Echoed from CreateThread. |
error | string | Set when status is FAILED. |
created_at_ms | int64 | |
started_at_ms | int64 | |
finished_at_ms | int64 | |
organization_name | string | Owning org. |
ListThreads
Cursor-paginated list, optionally filtered by status and/or script name.
Request
| Field | Type | Notes |
|---|---|---|
page_size | int32 | Max threads per page. |
page_token | string | Token from a previous response. |
status_filter | ThreadStatus | Filter by status, e.g. THREAD_STATUS_RUNNING. |
script_name_filter | string | Filter by script name. |
HTTP
curl -sS "https://api.dev.dodil.io/v1/scriptum/threads?pageSize=20&statusFilter=THREAD_STATUS_RUNNING" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG"Response
ListThreadsResponse { repeated Thread threads = 1; string next_page_token = 2; }.
CancelThread
Not yet implemented. Defined in the API but returns
Unimplementedtoday — see Feature Status.
Cancels a running thread, with an optional reason.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread to cancel. |
reason | string | Optional cancellation reason. |
HTTP
curl -sS -X POST "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123/cancel" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG" \
-H "Content-Type: application/json" \
-d '{ "reason": "User requested abort" }'Response
CancelThreadResponse { ThreadStatus status = 1; } — typically THREAD_STATUS_CANCELLED.
ResumeThread
Resumes a paused or failed thread, optionally overriding the input for the failed step.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread to resume. |
step_input_override_json | string | Optional JSON input override for the failed step. |
HTTP
curl -sS -X POST "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123/resume" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG" \
-H "Content-Type: application/json" \
-d '{ "stepInputOverrideJson": "{\"retry_count\": 3}" }'Response
ResumeThreadResponse { ThreadStatus status = 1; }.
WatchThread
Server-streams lightweight ThreadEvent messages — status transitions and yields. No data payloads: use GetThreadResult / StreamStepResult for content.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread to watch. |
HTTP
# Server-Sent Events stream over the HTTP gateway
curl -sS -N "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123/watch" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG"Response
A stream of ThreadEvent — see the event catalog.
WatchStep
Server-streams per-step notification events (StepEvent) — snapshot, decision, done/failed. Pure signals, no data payloads.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread. |
step_path | string | Required. Step to watch, e.g. 1.0.2. |
HTTP
curl -sS -N "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123/steps/1.0.2/watch" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG"Response
A stream of StepEvent — see the event catalog.
GetThreadResult
Unary result: metadata, step summaries, output, and capped yielded values. Scope it with step_path (fetch one step’s detail), output_only, or metadata_only. If output_truncated is true (output exceeds ~4MB), switch to StreamThreadResult; for large per-step data use StreamStepResult.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread to read. |
step_path | optional string | Fetch one step’s detail by path, e.g. 1.0.2. |
output_only | optional bool | Skip step summaries; return metadata + output. |
metadata_only | optional bool | Return only metadata. |
HTTP
curl -sS "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123/result" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG"Response
output_data is JSON bytes (base64 over HTTP) — your script’s final output. steps are lightweight StepSummary entries; step_details is populated only when step_path is set.
HTTP
{
"threadId": "thr_abc123",
"status": "THREAD_STATUS_COMPLETED",
"outputData": "eyJyb3dzIjogMTI0fQ==",
"durationMs": "8421",
"stepsExecuted": 6,
"steps": [
{ "stepPath": "1", "name": "fetch_data", "primitive": "execute", "status": "STEP_STATUS_COMPLETED", "durationMs": "1200", "parentPath": "" }
],
"outputTotalBytes": "11",
"outputTruncated": false,
"yieldedValues": [],
"totalYielded": 0,
"yieldsTruncated": false
}StepSummary
| Field | Type | Notes |
|---|---|---|
step_path | string | Hierarchical path, e.g. 1.0.2. |
name | string | |
primitive | string | execute, decide, iterate, … |
status | StepStatus | |
duration_ms | int64 | |
parent_path | string | Enables client-side tree reconstruction. |
StepDetail
Returned in step_details (via step_path) and streamed by StreamStepResult.
| Field | Type | Notes |
|---|---|---|
step_path | string | |
name | string | |
primitive | string | |
tool | string | Tool name for execute steps. |
status | StepStatus | |
input_data | bytes | JSON bytes (your data). |
output_data | bytes | JSON bytes; truncated if large. |
error | string | |
started_at_ms / finished_at_ms / duration_ms | int64 | |
diagnostics | StepDiagnostics | execution_id, error_detail, logs_url, worker_stderr, schema_warnings[]. |
output_total_bytes | int64 | Actual output size. |
output_truncated | bool | True if output_data was truncated. |
sample_input / sample_output | bytes | First 4KB, for quick inspection. |
StreamThreadResult
Server-streams the thread’s final output only in byte chunks — for outputs that exceed the ~4MB unary cap. No step details.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread to stream. |
max_chunk_bytes | optional int32 | Bytes per chunk (default 2MB, min 64KB, max 16MB). |
HTTP
curl -sS -N "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123/result/stream" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG"Response
A stream of ThreadOutputChunk. The first message carries meta (status + total size); subsequent messages carry output byte chunks. Concatenate output.data in chunk_index order; stop after is_final: true.
message ThreadOutputChunk {
string thread_id = 1;
oneof chunk {
ThreadOutputMeta meta = 2; // sent first: status + size info
OutputChunk output = 3; // byte chunks
}
}
message ThreadOutputMeta {
ThreadStatus status = 1;
int64 total_bytes = 2;
int32 total_chunks = 3; // 0 if unknown
}
message OutputChunk {
bytes data = 1; // client concatenates all chunks
int64 total_bytes = 2;
int32 chunk_index = 3;
bool is_final = 4;
}StreamStepResult
Server-streams step details — all steps, or just one step_path — chunking large per-step input/output.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread to stream step details for. |
step_path | optional string | A specific step, or all steps if unset. |
max_chunk_bytes | optional int32 | Bytes per step-data chunk (default 2MB). |
HTTP
curl -sS -N "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123/steps/stream?stepPath=1.0.2" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG"Response
A stream of StepResultChunk. First a meta message with summaries, then one step (StepDetail) per step, then follow-up data chunks for any large step input/output.
message StepResultChunk {
string thread_id = 1;
oneof chunk {
StepResultMeta meta = 2; // sent first: summaries
StepDetail step = 3; // one per step (output_data may be truncated)
StepDataChunk data = 4; // byte chunks for large step input/output
}
}
message StepResultMeta {
int32 total_steps = 1;
repeated StepSummary steps = 2;
}
message StepDataChunk {
string step_path = 1;
string field = 2; // "input" or "output"
bytes data = 3;
int64 total_bytes = 4;
int32 chunk_index = 5;
bool is_final = 6;
}ListArtifacts
Not yet implemented. Defined in the API but returns
Unimplementedtoday — see Feature Status.
Lists all artifacts a thread produced, each with a short-lived pre-signed download_url.
Request
| Field | Type | Notes |
|---|---|---|
thread_id | string | Required. Thread to list artifacts for. |
HTTP
curl -sS "https://api.dev.dodil.io/v1/scriptum/threads/thr_abc123/artifacts" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "x-organization-name: $DODIL_ORG"Response
HTTP
{
"artifacts": [
{
"name": "report.pdf",
"path": "thr_abc123/report.pdf",
"contentType": "application/pdf",
"sizeBytes": "20480",
"downloadUrl": "https://.../report.pdf?X-Amz-Signature=..."
}
]
}The download_url is a short-lived pre-signed URL — fetch it promptly; do not store it long-term.
Streaming event catalog
Watch streams carry signals only (no bulk data). Resolve content by following up with GetThreadResult or StreamStepResult.
ThreadEvent
Emitted by WatchThread. Every event carries thread_id and timestamp_ms, plus exactly one variant of the event oneof:
message ThreadEvent {
string thread_id = 1;
int64 timestamp_ms = 2;
oneof event {
ThreadStarted started = 10;
StepStarted step_started = 11;
StepCompleted step_completed = 12;
StepFailed step_failed = 13;
ThreadCompleted completed = 14;
ThreadFailed failed = 15;
ThreadCancelled cancelled = 16;
YieldedValue yielded = 17; // a yield primitive produced an intermediate value
}
}| Variant | Fields | Meaning |
|---|---|---|
started (ThreadStarted) | script_name, total_steps | Thread began; total_steps is the top-level count. |
step_started (StepStarted) | step_path, name, primitive, tool | A step started. tool set for execute steps. |
step_completed (StepCompleted) | step_path, name, duration_ms | A step finished successfully. |
step_failed (StepFailed) | step_path, name, error | A step failed. |
completed (ThreadCompleted) | duration_ms, steps_executed | Thread finished successfully. |
failed (ThreadFailed) | error, failed_step_path, failed_step_name | Thread failed. |
cancelled (ThreadCancelled) | reason, cancelled_step_path | Thread was cancelled. |
yielded (YieldedValue) | step_path, name, value_data, sequence, timestamp_ms | A yield produced an intermediate value (value_data = JSON-encoded yielded fields; sequence is a monotonic per-thread counter). |
StepEvent
Emitted by WatchStep. Carries thread_id, step_path, timestamp_ms, plus one event variant:
message StepEvent {
string thread_id = 1;
string step_path = 2;
int64 timestamp_ms = 3;
oneof event {
StepSnapshot snapshot = 10; // sent first (late-subscription catch-up)
DecisionMade decision = 11; // a decide step chose a branch
StepDone done = 12; // step finished (success) — no data
StepFailed step_failed = 13; // step finished (error)
}
}| Variant | Fields | Meaning |
|---|---|---|
snapshot (StepSnapshot) | status, name, primitive, started_at_ms, sample_input, sample_output | Sent first so late subscribers catch up. Samples are first 4KB. |
decision (DecisionMade) | strategy (llm/rule), chosen_branch, reasoning | A decide step chose a branch. |
done (StepDone) | duration_ms, output_bytes | Step finished; output_bytes is a size hint for deciding whether to stream. |
step_failed (StepFailed) | step_path, name, error | Step finished with an error. |
See also
- API Reference — conventions, endpoints, auth, streaming
- Scripts & Versioning — publish the version a thread runs
- Tools, Env & Templates — env loaded into a run
- ScriptContract Appendix —
ThreadStatus,StepStatus - Core Concepts — thread, step, artifact
- Scriptum Language —
yield,decide, and the step primitives behind these events