Workflows
A workflow is a multi-stage pipeline submitted as one artifact. You buy a single completion window for the whole graph instead of one per stage, and Otium schedules the inside of it.
Why this exists
Otium prices waiting: you buy a completion window and we spend it hunting cheap capacity. That works for one call and fails for a chain, because a pipeline pays the full window per stage. Seven stages on a seven-day window is seven weeks.
A workflow moves the window from the stage to the run. One budget, one artifact, and the scheduler gets to see the whole shape before it starts — which is also what lets it keep a model resident across steps, reuse a shared prompt prefix, and retry a malformed output in place instead of costing you another window.
A minimal workflow
A node's body is literally an OpenAI chat-completions request, with ${…} bindings substituted in. If you can write a batch line, you can write a node.
name: summarize
description: One step, to see the shape.
input:
schema:
type: object
required: [text]
properties:
text: { type: string }
schemas:
summary:
type: object
required: [headline]
properties:
headline: { type: string }
nodes:
summarize:
target: { product: otium-small }
estimate: { tokens_in: 800, tokens_out: 120 }
body:
messages:
- role: system
content: "Summarize in one line. Reply as JSON."
- role: user
content: "${input.text}"
output:
validators:
- type: json_schema
schema: { $ref: "#/schemas/summary" }
on_invalid: { retry: 2, then: fallback }
fallback:
- { target: { product: otium-medium } }Dependencies are derived, never declared
Add a node that reads another node's output and you have created an edge. There is no depends_on: the graph is whatever the data says it is, which means it cannot
drift from the prompts.
# A second node that reads the first. THIS is what creates the edge —
# you never declare dependencies, they are derived from the binding.
tag:
target: { product: otium-small }
body:
messages:
- role: user
content: "Tag this headline: ${nodes.summarize.output.headline}"The one edge you can write by hand is after: [x] — ordering with no data flowing,
for when a step has to finish before another starts. The compiler asks about every one
of them, because that is exactly where a pipeline transcribed from existing code carries a serialization
it never needed. Removing one is often the cheapest speedup available.
Validators and fallback
output.validators says what a good result looks like. A failure retries in place
— seconds later, on the same warm worker — instead of costing another batch round trip. When
retries run out, fallback moves that one item to a different target: handle the bulk
cheaply, spend only on the hard few percent.
Steps we don't run
Otium runs no customer code. When your pipeline needs a database write or a search query in
the middle, mark that step type: external: the run parks, you do
the work, and you resume it. The clock stops while it waits, the worker is released, and it is
still one run — so a pipeline that interleaves your steps with ours stays a single completion
window rather than three.
Publishing and submitting
Publish a workflow from the portal, the API, or otiumctl. A version is immutable
and publishing an identical document changes nothing, so re-running publish in CI is safe.
Then submit a batch whose lines reference it — the same JSONL ingress, one line per item:
{"custom_id":"doc-1",
"method":"POST","url":"/v1/chat/completions",
"body":{},
"otium":{"workflow":"summarize@1"}}The batch's completion window becomes the budget for every run in it.
Where the full specification lives
This page is an orientation, not a reference. The complete design — assets, structured
predicates, conditional prompt sections, the compiled plan and its scheduling artifacts,
billing, and the security model — is maintained alongside the code in docs/workflow-graphs.md, with a full worked pipeline in docs/examples/ar15-enrich.yaml.
Everything the compiler will tell you about a document is also available offline: otiumctl workflow validate <file> exits non-zero when a document would be rejected,
so it drops into a pre-commit hook or a CI step.
Stop paying for speed you don’t need.
Otium is in closed alpha. Leave your email and we’ll send an invite when a spot opens — then point your OpenAI-compatible client at our base URL and send your first batch.
No credit card, no spam — one email when your invite is ready.
Closed alpha — onboarding is gated while we calibrate. Already invited? Sign in.