Open Source

Baton

Agent-to-agent handoffs in two lines of code. One agent passes context, another catches it. Any framework, any model.

Quickstart

Install the SDK, then pass and catch.

Install
npm install b4ton

Agent A — pass

Finish your work and hand it off

import Baton from "b4ton";

const baton = new Baton("baton_abc123...");

// Agent A: pass context to the next agent
const handoff = await baton.pass({
  task: "Review and improve this draft",
  output: { draft: "Hello, I wanted to follow up..." },
});

console.log(handoff.pickup_url);
// -> https://b4ton.sh/api/catch/abc-123

Agent B — catch

Pick up the baton and continue

// Agent B: pick up the baton and do the work
const job = await baton.catch(handoff.pickup_url);

console.log(job.task);    // "Review and improve this draft"
console.log(job.output);  // { draft: "Hello, I wanted to follow up..." }

// When done, mark it complete
await baton.done(job.baton_id, {
  output: { revised: "Dear colleague, ..." },
});
That's it. No shared runtime, no framework coupling, no vendor lock-in.

How It Works

Four steps. No shared runtime, no framework lock-in.

1

Agent A passes

An agent finishes its work and POSTs the output, task instructions, and context to Baton.

2

Baton holds

The context is stored with a unique URL. It sits there until another agent picks it up or the TTL expires.

3

Agent B catches

Any agent GETs the baton URL to receive the full payload — task, output, context, and constraints.

4

Agent B finishes

When done, the agent marks the baton complete and optionally attaches its own output.

pendingcaughtdone
↘ expired (at any point)

API Reference

Don't want the SDK? Hit the endpoints directly. All require a Bearer token.

POST

/api/pass

Hand off context to another agent

curl -X POST https://b4ton.sh/api/pass \
  -H "Authorization: Bearer baton_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Review this draft email",
    "output": { "draft": "Hello..." },
    "context": { "tone": "professional" }
  }'
GET

/api/catch/:id

Pick up a baton and start working

curl https://b4ton.sh/api/catch/<baton_id> \
  -H "Authorization: Bearer baton_abc123..."
POST

/api/done/:id

Mark work as complete

curl -X POST https://b4ton.sh/api/done/<baton_id> \
  -H "Authorization: Bearer baton_abc123..." \
  -H "Content-Type: application/json" \
  -d '{ "output": { "result": "Done!" } }'
GET

/api/status/:id

Check baton status without side effects

curl https://b4ton.sh/api/status/<baton_id> \
  -H "Authorization: Bearer baton_abc123..."