Skip to Content
We are live but in Staging 🎉
API ReferenceThreads & Results

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.

RPCHTTP
CreateThreadPOST /v1/scriptum/threads
GetThreadGET /v1/scriptum/threads/{thread_id}
ListThreadsGET /v1/scriptum/threads
CancelThreadPOST /v1/scriptum/threads/{thread_id}/cancel
ResumeThreadPOST /v1/scriptum/threads/{thread_id}/resume
WatchThreadGET /v1/scriptum/threads/{thread_id}/watch (server-stream)
WatchStepGET /v1/scriptum/threads/{thread_id}/steps/{step_path}/watch (server-stream)
GetThreadResultGET /v1/scriptum/threads/{thread_id}/result
StreamThreadResultGET /v1/scriptum/threads/{thread_id}/result/stream (server-stream)
StreamStepResultGET /v1/scriptum/threads/{thread_id}/steps/stream (server-stream)
ListArtifactsGET /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

FieldTypeNotes
script_namestringRequired. Script to execute.
versionint32Version to run (0 = active version).
input_jsonstringInput parameters as a JSON string (your data).
timeoutstringOverride default timeout, e.g. 5m, 1h.
metadatamap<string, string>Arbitrary key-value labels for the thread.
callback_urlstringWebhook called when the thread completes.
load_envboolLoad tenant env vars into the run.
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

{ "threadId": "thr_abc123", "status": "THREAD_STATUS_PENDING", "createdAtMs": "1748390400000" }

GetThread

Current status and progress of a thread.

Request

FieldTypeNotes
thread_idstringRequired. Thread to retrieve.
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

FieldTypeNotes
thread_idstring
script_namestring
script_versionint32Resolved version actually running.
statusThreadStatus
current_step_pathstringHierarchical path of the active step, e.g. 1.0.2.
total_stepsint32Top-level step count.
current_step_namestring
metadatamap<string, string>Echoed from CreateThread.
errorstringSet when status is FAILED.
created_at_msint64
started_at_msint64
finished_at_msint64
organization_namestringOwning org.

ListThreads

Cursor-paginated list, optionally filtered by status and/or script name.

Request

FieldTypeNotes
page_sizeint32Max threads per page.
page_tokenstringToken from a previous response.
status_filterThreadStatusFilter by status, e.g. THREAD_STATUS_RUNNING.
script_name_filterstringFilter by script name.
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 Unimplemented today — see Feature Status.

Cancels a running thread, with an optional reason.

Request

FieldTypeNotes
thread_idstringRequired. Thread to cancel.
reasonstringOptional cancellation reason.
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

FieldTypeNotes
thread_idstringRequired. Thread to resume.
step_input_override_jsonstringOptional JSON input override for the failed step.
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

FieldTypeNotes
thread_idstringRequired. Thread to watch.
# 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

FieldTypeNotes
thread_idstringRequired. Thread.
step_pathstringRequired. Step to watch, e.g. 1.0.2.
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

FieldTypeNotes
thread_idstringRequired. Thread to read.
step_pathoptional stringFetch one step’s detail by path, e.g. 1.0.2.
output_onlyoptional boolSkip step summaries; return metadata + output.
metadata_onlyoptional boolReturn only metadata.
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.

{ "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

FieldTypeNotes
step_pathstringHierarchical path, e.g. 1.0.2.
namestring
primitivestringexecute, decide, iterate, …
statusStepStatus
duration_msint64
parent_pathstringEnables client-side tree reconstruction.

StepDetail

Returned in step_details (via step_path) and streamed by StreamStepResult.

FieldTypeNotes
step_pathstring
namestring
primitivestring
toolstringTool name for execute steps.
statusStepStatus
input_databytesJSON bytes (your data).
output_databytesJSON bytes; truncated if large.
errorstring
started_at_ms / finished_at_ms / duration_msint64
diagnosticsStepDiagnosticsexecution_id, error_detail, logs_url, worker_stderr, schema_warnings[].
output_total_bytesint64Actual output size.
output_truncatedboolTrue if output_data was truncated.
sample_input / sample_outputbytesFirst 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

FieldTypeNotes
thread_idstringRequired. Thread to stream.
max_chunk_bytesoptional int32Bytes per chunk (default 2MB, min 64KB, max 16MB).
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

FieldTypeNotes
thread_idstringRequired. Thread to stream step details for.
step_pathoptional stringA specific step, or all steps if unset.
max_chunk_bytesoptional int32Bytes per step-data chunk (default 2MB).
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 Unimplemented today — see Feature Status.

Lists all artifacts a thread produced, each with a short-lived pre-signed download_url.

Request

FieldTypeNotes
thread_idstringRequired. Thread to list artifacts for.
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

{ "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 } }
VariantFieldsMeaning
started (ThreadStarted)script_name, total_stepsThread began; total_steps is the top-level count.
step_started (StepStarted)step_path, name, primitive, toolA step started. tool set for execute steps.
step_completed (StepCompleted)step_path, name, duration_msA step finished successfully.
step_failed (StepFailed)step_path, name, errorA step failed.
completed (ThreadCompleted)duration_ms, steps_executedThread finished successfully.
failed (ThreadFailed)error, failed_step_path, failed_step_nameThread failed.
cancelled (ThreadCancelled)reason, cancelled_step_pathThread was cancelled.
yielded (YieldedValue)step_path, name, value_data, sequence, timestamp_msA 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) } }
VariantFieldsMeaning
snapshot (StepSnapshot)status, name, primitive, started_at_ms, sample_input, sample_outputSent first so late subscribers catch up. Samples are first 4KB.
decision (DecisionMade)strategy (llm/rule), chosen_branch, reasoningA decide step chose a branch.
done (StepDone)duration_ms, output_bytesStep finished; output_bytes is a size hint for deciding whether to stream.
step_failed (StepFailed)step_path, name, errorStep finished with an error.

See also