Creating a run
prompt are keyword-only.
| Argument | Type | Default | Description |
|---|---|---|---|
prompt | str | required | The instruction for the run. |
template | Template | str | Template.AUTO | Canvas template. See Templates. |
blocks | Iterable[BlockType | str] | None | Allow-list of block types the run may produce. |
agent_instructions | str | None | None | Extra system-prompt instructions for the agent. |
webhook_url | str | None | None | Reserved for future webhook delivery. |
files | Iterable[...] | None | Files to upload — see below. |
runs.create returns a RunHandle (or AsyncRunHandle) that holds
run_id, canvas_id, and a reference back to the client.
Uploading files
The SDK normalises several shapes so you can mix them freely:Waiting for completion
handle.wait() polls the server with exponential backoff until the run
reaches a terminal state, then returns the RunResult:
| Argument | Default | Notes |
|---|---|---|
timeout | 900.0 seconds | Raises SpineTimeoutError if exceeded. |
poll_interval | 2.0 seconds | Initial delay between polls. |
max_poll_interval | 30.0 seconds | Upper bound for the exponential backoff. |
wait raises SpineAPIError if the run terminates with status
failed. Partial successes (some blocks failed, some succeeded)
return normally — inspect handle.refresh().errors afterwards.
Streaming progress
Drive a progress bar withhandle.stream_progress(). It yields a
RunProgress snapshot on each poll and exits silently when the run
terminates — call wait() or refresh() afterwards to get the result.
Manual polling
If you want full control, callclient.runs.get() directly: