Skip to main content
Voyages are Sail’s telemetry layer for long-running background-agent tasks. Add a few SDK calls to your existing agent harness. Sail records the run as a trace of named agents, spans, events, Sail inference calls, and Sailbox execs. Every Voyage gets its own page in the dashboard at app.sailresearch.com, showing its recorded trajectory. The SDK returns the link from sail.voyage.dashboard_url(), and the API returns it as dashboard_url. You keep control of the agent loop. Sail provides the runtime pieces (Sailbox and inference) plus the Voyage timeline. Voyages are not an agent framework. They do not own your planner, memory, orchestration, tool abstractions, prompts, or retry policy. Use them with your own Python scripts, LangGraph, CrewAI, job runners, subprocesses, or any custom loop where you want visibility into what happened.
Using a coding agent? Start with the public Sail skills package. Tell your agent: “Use Sail Voyages to add automatic telemetry to my background agent workload. Keep my harness, use the sail package, wrap the run with sail.voyage.run(..., version=1), add @sail.agent and @sail.span where they fit naturally, and attribute Sail inference calls plus any Sailbox execs the workload already uses.” You do not need to know the individual skill names. The package gives your coding agent the right Voyage instructions when they are relevant.

Install

Both paths authenticate SDK processes: the SDK reads SAIL_API_KEY first and falls back to the credential sail auth login stores under ~/.sail. Use SAIL_API_KEY for CI and deployments; logging in once is enough for local scripts.

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, and other evidence for debugging or auditing.
Do not use a Voyage for one-shot API calls. A single sail.inference.responses.create() outside a Voyage works fine and shows up in your inference dashboard without extra instrumentation.

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. If no span is active, the SDK creates an auto-span.
  • A Sailbox exec is automatically recorded when you call sb.exec() inside a Voyage. If no span is active, the SDK creates an auto-span.

Minimal example

Run this, then open the printed URL. You should see one Voyage with one Researcher agent, one explicit span, two events, one attributed model call, and terminal status voyage completed.

What gets attributed automatically

When you call Sail inference inside a Voyage, the SDK attaches active Voyage, agent, and span context so the model call appears in the dashboard. Decorators are the most direct way to attribute function-shaped work:
When you call sb.exec() inside a Voyage, the SDK also carries the active Voyage, agent, and span context into the Sailbox command. sb.exec(...) returns a request handle. Call .wait() for foreground commands so your program observes completion, return code, stdout/stderr tails, and the attributed exec row:
You do not need to pass IDs by hand. If no span is active, Sail inference and Sailbox execs still get a timed auto-span named from the calling code when possible. Auto-spans do not invent agents, so declare an agent when the dashboard should show ownership.

Explicit vs auto spans

Use an explicit span when the step name matters to humans:
If you leave the span out, Sail still captures SDK-owned work. The model call below is recorded under the Researcher agent and wrapped in a timed auto-span:
Auto-spans are useful when you are adding telemetry to an existing agent harness. Add @sail.span(...) when you want a specific step name, payload, or parent/child shape.

Multiple agents in one Voyage

A real code-review agent has at least three distinct participants. A GitHub agent clones the repository, a TestRunner runs the suite in a Sailbox, and a Reviewer drafts the summary with inference. Declare each one with @sail.agent(...), and the dashboard shows three named agents under one Voyage, each with its own spans and events. See the Voyages Patterns guide for the full multi-agent example.

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 delivery only.
Controllers whose create and terminal sites live in different places use the create() primitive and call voyage.complete() / voyage.fail() themselves.

Stop recording and delete

Use voyage.cancel() or sail.voyage.cancel() to stop recording a running Voyage:
Cancel marks the server-side Voyage cancelled and stops this SDK instance from recording further events. The server does not reject late events from other sources, and cancel does not terminate external or non-Sailbox agent code. If you own that process, stop it separately. You can delete a finished Voyage from its dashboard detail page; this removes its history and content from the dashboard and API. Security audit records are retained. There is no API or SDK delete yet.