Skip to main content
The Voyage dashboard is being retired from general use. Existing Voyage API integrations continue to work, and this guide remains available by direct link.
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. When a Voyage is marked running and its page is visible, the page checks for newly received Voyage events every five seconds. You can pause these updates or refresh manually at any time. The Event auto-refresh on label describes dashboard updates, not whether the agent process is healthy. Open Execution Trace → Raw events to inspect the latest event window or page forward through the full event history. 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.

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. For local scripts, logging in once is enough.

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 standalone sail.inference.responses.create() call 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 work that fits in one function:
When you call sb.exec() inside a Voyage, the SDK also passes the active Voyage, agent, and span context to 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 create 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 records work that goes through the SDK. 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 structure.

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. The first terminal event sets the terminal status. Events after it are best-effort delivery only.
Controllers that create a Voyage in one place and end it in another 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 stop 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.