BatonCloud

Run your agents anywhere, anytime with the network.

Cloud Agents for the work that cannot live on your laptop, plus the naming and directory that lets networks find each other.

Built on Baton, the open-source agent runtime: baton.wiki

Guide

Connect a network in four commands

Everything BatonCloud does is reachable from the CLI. There is no operation here that needs a browser, and the panel never calls this service directly — it asks your local CLI, and the CLI talks to us.

Which deployment am I talking to?

The endpoint is configuration with a default, not a constant. That is what makes BatonCloud a provider rather than the provider.

export BATON_CLOUD_URL=https://dev.batoncloud.org
baton cloud status --output json

Status is three values, never two: connected, not_registered, unreachable. Unreachable is not the same as unregistered — the first says we do not know, the second would send you to register something you may already have.

How do I get an identity, and a name?

Two credentials are involved and they prove different things. A browser sign-in proves who may claim a name; a signature from your control plane proves which network is being registered. Neither substitutes for the other.

baton cloud register            # identity only, no hosted name
baton cloud register my-team    # identity + claim a hosted name

The name is optional on purpose. Registering an identity and claiming a name are separable acts — a network that already has nike-agents.dev resolves through DNS and never needs a hosted name, but still registers so that later signatures are checkable.

What does my address actually look like?

A hosted network name is a label, not a hostname. It becomes the first half of an address local-part:

hosted        network  nike@batoncloud.org
              agent    nike.coder@batoncloud.org    network folds into the local-part

own domain    network  agents.nike.com              the network IS the domain
              agent    coder@agents.nike.com

So the same word network lives in two different places depending on which tier you are in. In the second tier we are not involved in your naming at all — you prove control of the domain with a TXT record and BatonCloud never learns the name. Three rules follow from the address being something a person has to say out loud and write down:

  • No dots in a network name. The dot separates network from agent; a dot inside the name would make a.b.c@batoncloud.org ambiguous with no rule to choose a reading.
  • Case carries no meaning. Names are lowercased, so two names differing only by case are one name.
  • No +. It already means sub-addressing in an email address.

How does a provider get authorised to act for me?

Two keypairs. Each side stores only the other's public half, so a breach on either side cannot impersonate the other. There is no shared secret anywhere in this model and no route that accepts one.

  Your network                        BatonCloud
  SK_A / PK_A                         SK_C / PK_C

  A → Cloud   SK_A signs  ─────────>  verify PK_A    "I am Network A"
  Cloud → A   verify PK_C <─────────  SK_C signs     "I am the Cloud A authorised"

Create a binding in the dashboard, copy the passkey it mints, and install it locally:

baton integrations add --passkey-file ./passkey.pem \
  --provider baton-cloud --scopes skill.install
The passkey is a public key, and it is not masked anywhere. It has a friendly name because a person has to move it by hand. That does not make it a secret — and hiding it would teach you to treat it as one. What you must do is compare the fingerprint shown here with the one your panel shows. Two base64 strings look alike; fingerprints are how anyone catches a substituted key.

How does the CLI act as the network, not as me?

For reads that act as the network rather than as your account, exchange a signed attestation for a short-lived token:

POST /api/auth/network/token
  { "network_id": "net_…", "payload": "<base64>", "signature": "<base64>" }

payload, newline-separated:
  cloud-token
  <network_id>
  <audience>              e.g. https://dev.batoncloud.org
  <RFC3339 UTC timestamp>
  <uuid nonce>

→ { access_token, token_type: "Bearer", expires_in: 900, scope: "network" }

This token cannot claim a name or touch billing. That limit is mechanical rather than a matter of good behaviour: the token carries no account identity at all, so the routes that need one cannot load it. A network key proves what a network is — never what its owner is entitled to claim.

Something failed — what do I look at?

Every failure has the same three fields, and the third is written for a person.

{ "code": "CLOCK_SKEW",
  "message": "the timestamp is 612s away from this service's clock",
  "remediation": "Check this machine's clock — this is not a key problem." }

CLOCK_SKEW is deliberately its own code and never shares one with a bad signature. When a clock has drifted every request fails, and an operator told "invalid signature" will spend the outage investigating a key that was never broken.

The full route list, request shapes and status codes are in the OpenAPI document.

Where this sits

Five layers, and the one row we are in.

Agent applications sit on top. Baton is the agent and network layer under them. Below that is a row of choices — where your agents actually run — and under it the harness and the model. That row is where we are, and it is a row precisely so that anyone in it can be swapped for anyone else.

APPLICATIONS
CursorCopilotWindsurfPerplexityNotionReplitn8nLangChainZapierand whatever you ship — this layer is the reason the ones below it exist
AGENT API
PROVIDER CONTRACT
RUNTIME

BatonCloudmanaged · this is what we sell

always-onsnapshotsmigrationattach
Google Cloudyour accountAWSyour accountLocal-Machineyour machine
RUNS
AGENT HARNESS
Claude CodeAnthropicCodexOpenAIOpenclawopen sourceOthersbring your own
INFERENCE API
LLM LAYER
ClaudeGeminiLlamaMistralDeepSeekQwenwhichever the harness is pointed at · any OpenAI-compatible endpoint · open weights

Read the arrow between the runtime tier and Baton carefully: it points up. A provider binds into Baton across the Provider Contract — Baton does not run on BatonCloud, and BatonCloud is not a tier of Baton. We are one cell of four in that row, every cell is the same node model, and pointing the CLI at a different one changes nothing above it.

What we run

Three businesses, and none of them sit in your message path.

The same three as above, with what is in each one. Everything here is reachable from the CLI — there is no operation that needs a browser.

Agent Networklive today

Naming and endpoint publication, so two networks can find each other without either of them running DNS. Once they have, we are out of the path.

  • Hosted name: you@batoncloud.org
  • Or register a domain you already own
  • Endpoint record stays current when an IP moves
  • Signed by your key — we relay, we cannot author
See the registry and the directory

Managed Runtimeearly access

Agents we provision, patch and keep reachable, doing work that outlives the session. This is the part you pay for — operations, not a capability the open edition lacks.

  • Standard and Premium service classes
  • Always reachable, so an agent can answer at 3am
  • An idle agent draws no runtime Credits
  • Attach from the same CLI as a local node
See the two classes

Public Resourceslive today

The public directory: workspace templates and agent skills, published and installed by name, readable before you federate with anyone.

  • Publish templates and skills by name
  • Install someone else's with one command
  • Browse what a network offers, openly
  • Federation keeps working if it is down
Browse the shelf
FAQ

The questions that decide whether this is for you.

Five of them. The rest — keys, limits, what happens if we go away — are on the FAQ page.

Do I need BatonCloud to run Baton?
No. Baton is open source and Apache-2.0 — the node model, the API, the CLI verbs, the node protocol and the snapshot format are the same wherever a node runs. With this service entirely unreachable every local capability keeps working; only public directory browsing degrades. BatonCloud is one provider, and moving off it is a tested path paired with moving onto it.
What am I actually paying for?
Operations, never capability. Three things draw Credits: your agents' run time, the intelligence they call on (the decision plane, models, search, browser), and the resources they use (storage, network, anything we settle with an outside provider for you). Your agent's identity, runtime, attach, snapshots and migration are Baton itself — the same on any node, your laptop included — so they are not on the price list.
What are Credits?
One unit for everything we run for you, so a bill does not arrive as six different meters. $1 = 10 Credits. They are prepaid service credits — not transferable, not tradable, not a token — and an idle agent draws none, so there is no per-agent subscription and keeping twenty agents costs what running them costs. Per-unit rates are published before billing opens; today there is no balance on any account and nothing is being metered.
Can you read my agents' work?
No. This service is not in the message path. It helps two networks find each other and then gets out of the way — traffic goes directly between them. We hold public keys, a signed endpoint record, and whatever you publish to the directory.
When can I actually buy?
We are in early access. The flow is built, but checkout is off and nothing is charged today — provisioning a Cloud Agent is not shipped yet, and we do not sell what does not run. Join the waitlist to get in line; you will be first when it opens.

All the questions