app.sailresearch.com/prod/voyages/<voyage_id> (or the
matching /dev/ or /staging/ route for your SAIL_MODE).
You bring the agent loop. Sail brings the substrate (Sailbox + inference) and
the timeline (Voyages).
Voyages are currently in beta. APIs and dashboard surfaces may change as we
stabilize the product.
Internal preview: this page is intentionally hidden from the public docs
navigation until launch. Direct preview URLs are
https://docs.sailresearch.com/voyages,
https://docs.sailresearch.com/voyages-quickstart, and
https://docs.sailresearch.com/voyages-patterns.When to use a Voyage
Use a Voyage when:- An agent task runs for more than a few seconds and you want to see its trajectory in real time.
- Multiple cooperating agents (Reviewer, TestRunner, GitHub-poster, etc.) contribute to one logical task.
- You need a customer-visible record of what an agent did — events, model calls, Sailbox execs, terminal status — for debugging or auditing.
sail.inference.responses.create() outside a Voyage works fine and shows up
in your inference dashboard; you don’t need the extra ceremony.
Mental model
- A Voyage is one task.
- An agent is a named participant within the task (e.g., “Reviewer”).
- A span is a logical step the agent performs (e.g., “draft-response”).
- An event is a timestamped marker within a span.
- A model call is automatically recorded when you call Sail inference inside a Voyage.
- A Sailbox exec is automatically recorded when you call
sb.exec()inside a Voyage.
Minimal example
voyage completed.
What gets attributed automatically
When you call Sail inference inside a Voyage, the SDK attaches headers so the model call shows up in the Voyage’s Native Model Calls panel, scoped to the active span and agent:sb.exec() inside a Voyage, the SDK attaches gRPC metadata
so the exec row in the Sailbox tab is attributed to the active agent and
span:
with voyage.agent(...) /
with voyage.span(...) context when you make the call.
Multiple agents in one Voyage
A real code review agent has at least three distinct participants:Terminal status
Every Voyage needs exactly one terminal event before the controller process exits —with sail.voyage.run(...) handles it: clean exit emits
voyage.completed, an exception emits voyage.failed and re-raises.
Terminal status is first-terminal-wins; events after the terminal are
best-effort.
create() primitive and call voyage.complete() / voyage.fail()
themselves.
What to read next
- Voyages Quickstart — copy-paste-ready 60-second example.
- Voyages Patterns — multi-agent and child-attach for subprocesses.
- Building Agents — Sail’s Responses API and tool calling.
- Sailboxes — the runtime substrate.