Built on x402 · Powered by Base

A lease for your agent.
Pay once. Walk away.

It's still there when you're not. Storage, Mailbox, Checkpoint — same primitive, different shortcut. Configure your own or call one of ours.

See the shortcuts → Read the quickstart

Think of it like a parking meter. You pay for a spot, for a defined time, then it expires automatically. Every lease works the same way — the meter just holds a different kind of space. Lease it. Pay for it. Done.

Services

Three shortcuts.
One primitive.

Every variant is a lease — pre-configured for a common workflow. Call the shortcut that fits, or configure your own.

Storage

The configurable primitive

Size, duration, access rules — you pick all three. Multi-read, multi-party handoff, long-lived buffers, anything the shortcuts don't fit.

Storage docs →
Mailbox

Hand a payload, then be gone

Create. Drop your payload. Issue a token. Walk away. The other agent picks it up once; pickup triggers deletion. Nothing to poll, nothing to clean up.

Mailbox docs →
Checkpoint

Hold this for me

Drop a session output or state snapshot. Come back later — or have your successor come back — and pull it down. Retrieval triggers deletion.

Checkpoint docs →

More lease variants coming — Scratchpad (short-lived working memory), Cron (lease + scheduler).

How it works

From task to lease
in a single HTTP call.

Discover and quote are optional. If you already know the rate, skip straight to the create call — one POST and you're done.

TL;DR — minimum viable agent call

POST to the variant endpoint (/api/store, /api/mailbox, or /api/checkpoint) with an x402 payment header or an rs_live_ API key, and the lease parameters in request headers. Receipt comes back in the response — lease_id plus the variant-specific fields you'll use for the rest of the lease's life.

Optional

Discover

Hit /api/pricing once for the live rate, wallet address, and endpoint list. Cache it — it rarely changes.

Optional

Quote

Call /api/quote for an exact price. Or calculate yourself: (bytes/1GB) × (seconds/86400) × $0.001. Same formula for every variant; Checkpoint uses max_body_bytes instead of actual file size.

Required

Pay & Lease

One POST — /api/store, /api/mailbox, or /api/checkpoint — with payment and parameters. Atomic: if the server can't write the lease, the charge refunds automatically.

Done

Spin down

Write the lease_id and expires_at. The underlying resource deletes itself when the lease expires — to the second. No cleanup call.

Quickstart

One required step.
Three variants, one shape.

No SDK. No IAM. No billing account. Just HTTP. Pick the variant below — the shape of the call is the same; the headers tell the server which shortcut you want.

Storage
Mailbox
Checkpoint
// ── OPTIONAL: discover pricing once and cache it ─────────────────────────
const pricing = await fetch('https://relaystation.ai/api/pricing').then(r => r.json());
// → { rateUsdcPerGbDay: 0.001, walletAddress: '0x...', minDurationSeconds: 60 }

// ── OPTIONAL: get an exact quote ─────────────────────────────────────────
const quote = await fetch(
  `https://relaystation.ai/api/quote?size_bytes=${fileBytes}&duration_seconds=3600`
).then(r => r.json());
// → { priceUsdc: 0.01, expiresAt: '...' }

// ── REQUIRED: pay and create the Storage lease ────────────────────────────
const receipt = await fetch('https://relaystation.ai/api/store', {
  method: 'POST',
  headers: {
    'Authorization':      `Bearer ${rs_live_key}`,  // or X-Payment via x402
    'X-File-Name':        'report.pdf',
    'X-Size-Bytes':       String(fileBytes),
    'X-Duration-Seconds':  '3600',
    'Content-Type':       'application/pdf',
  },
  body: fileStream,
});
// → { lease_id, object_key, expires_at, duration_human, paid_usdc }
Why RelayStation

Categorically different
from every alternative.

Each variant competes with different infrastructure, and the pitch against each is the same idea expressed three ways: no account, pay once, expires itself.

Storage vs. object stores

AWS S3 / R2 / Backblaze

Requires IAM setup by a human
Monthly billing to a credit card
Agent can't open an account mid-task
No second-level expiry — lifecycle rules are day-granularity only
No agent-to-agent handoff primitive

RelayStation Storage

No account, no IAM, no signup
Pay once per lease, upfront in USDC
Agent pays autonomously mid-task via x402
Expiry to the second — physical deletion enforced
Sealed handoff tokens for agent-to-agent transfer
Mailbox vs. webhooks / SQS

Webhooks / SQS

Webhooks need a receiver your agent has to stand up and tear down
Signature verification infrastructure to own and rotate
SQS requires an AWS account and IAM — no agent self-onboarding
Monthly or per-request billing against a credit card
Manual retention policy or DLQ to configure and monitor

RelayStation Mailbox

Nothing to stand up — RelayStation is the receiver
Drop token is the credential; no signing secret to rotate
Accountless for the drop side; owner uses API key or x402
Prepaid once for the capacity × duration you asked for
Expiry-on-pickup (one-shot) or expiry-on-lease-end — self-cleaning
Checkpoint vs. Redis / DynamoDB / Memcached

Redis / DynamoDB / Memcached

Requires an account or a running cluster to talk to
Shared credentials — every agent needs the connection string
Monthly / usage billing with no one-shot semantics
TTL eviction is best-effort; no physical-delete guarantee
No built-in "hand this to my successor" pattern

RelayStation Checkpoint

No cluster, no account for ephemeral agents — API key or x402
Per-workflow credential; no shared connection to leak
Reservation pricing — pay once, write as many versions as you need
Physical deletion at expiry — not eviction, not best-effort
Retrieval-triggers-deletion for one-shot handoff to a successor
Mailbox

Hand a payload to another agent.
Then be gone.

A Mailbox is a lease for one thing: create, drop your payload, issue a token, walk away. The other agent picks it up once. Pickup triggers deletion. Nothing to poll, nothing to clean up, nothing to pay again.

How a Mailbox works

Same primitive as Storage, pre-configured for async inter-agent handoff. The backend also supports multi-drop + polling for richer workflows — the shortcut above is the default, not the ceiling.

Agent A — create

POST /api/mailbox with X-Capacity-Bytes and X-Duration-Seconds. Returns a drop_url and a poll_url.

Agent A → B

Share the drop_url. Anyone holding it can POST a payload — no auth on the drop endpoint, the URL IS the credential.

Agent B — pick up

GET poll_url for the message index, GET a single message to read it. In the one-shot shortcut, this is also the last call.

Lease expires

Every queued message and the mailbox itself are physically deleted at expires_at. No cron, no retention sweep — expiry is the cleanup.

Mailbox flow
// Agent A — pay once for 1 MB capacity, 1 hour
const mb = await fetch('https://relaystation.ai/api/mailbox', {
  method: 'POST',
  headers: {
    'Authorization':      `Bearer ${rs_live_key}`,
    'X-Capacity-Bytes':   '1048576',
    'X-Duration-Seconds': '3600',
  },
}).then(r => r.json());
// → { drop_url, poll_url, expires_at, capacity_bytes, cost_micros }

// Hand drop_url to whoever needs to deliver — no auth on drop
await fetch(mb.drop_url, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ task: 'review contract-42.pdf' }),
});

// Agent B — pick up (one-shot)
const messages = await fetch(mb.poll_url, {
  headers: { 'Authorization': `Bearer ${rs_live_key}` },
}).then(r => r.json());
// → { items: [{ id, size_bytes, received_at }, ...] }
Why not webhooks / SQS / redis? Webhooks need a receiver your agent can stand up in seconds and tear down in minutes — plus signature verification infrastructure you don't want to own. SQS needs an AWS account. Redis needs shared credentials. A Mailbox is prepaid, accountless, and self-cleaning — it exists for exactly the lease you paid for, then it's gone.
Handoff — the cross-cutting feature

Any lease can be handed off.
Same token. Same flow.

Storage file, Mailbox drop, Checkpoint snapshot — once you have a lease, you can turn it into a sealed claim URL that another agent redeems without authentication. The token IS the credential. Handoff is free at v1 defaults; you pay once for the underlying lease.

How handoff works

A self-destructing sealed envelope that fits any lease variant. Agent A has a lease — storage, mailbox, or checkpoint — and seals it. Agent B receives the claim URL and opens it. The envelope is gone. No shared backend. No trust required between agents.

Agent A — has a lease

Any variant. Storage lease_id, mailbox lease_id, checkpoint lease_id. Same /api/handoff/{id} endpoint regardless.

Agent A — seal

POST /api/handoff/{lease_id} with max_claims, delete_on_claim, ttl_seconds. Get back a claim_url.

Agent A → B

Pass the claim_url through any channel — message queue, mailbox drop, webhook, shared context. The URL itself is the credential.

Agent B — claim

GET the claim_url — no auth, no wallet, no setup. The underlying resource streams back. If delete_on_claim, the lease is physically deleted on the final claim.

Storage handoff
Mailbox handoff
Checkpoint handoff
// Agent A — after creating a Storage lease, issue a handoff token
const handoff = await fetch(`https://relaystation.ai/api/handoff/${storage_lease_id}`, {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${rs_live_key}` },
  body: JSON.stringify({
    max_claims:      1,
    delete_on_claim: true,
    ttl_seconds:     3600,
  }),
}).then(r => r.json());
// → { claim_url, handoff_token, expires_at, lease_expires_at }

// Agent B — redeem, no auth required. Bytes stream back with original filename.
const file = await fetch(handoff.claim_url);
Token knobs:   max_claims — how many times the token can be redeemed (default 1)  ·  delete_on_claim — physically delete the underlying resource after the final claim (default false)  ·  ttl_seconds — token expiry, clamped to the lease's own expiry (default 3600)

Revoke early:   DELETE /api/handoffs/:id invalidates an outstanding token. Idempotent — the second call returns 404. Claims already completed stand.
Pricing

Pay for exactly what you need.
Nothing more.

Rate: $0.001 / GB / day. Same formula across every variant. You pay once at creation — no subscription, no renewal. Prices that hit the network minimum are shown in green.

Duration is a tool, not just a limit. Your lease ends at the expiry you paid for — the underlying resource is physically deleted at that instant, not before and not after. Pick the shortest duration you actually need; a lease requested for 10 years stays for 10 years, even if your agent only needed it for an hour.
1 MB PDF contract
4 GB video file

Custom calculator — Storage

for
Handoff is free. Issuing a claim token (POST /api/handoff/:lease_id) and redeeming one (GET /api/claim/:token) are $0 at v1 defaults. You pay once for the underlying lease; every handoff off that lease is free.
Built for agents

Spin up. Work. Store.
Spin down.

Every design decision optimises for autonomous operation with zero human involvement.

🔍

Machine-discoverable

Every variant is advertised at /.well-known/x402.json and /api/pricing. Rates, minimums, canonical endpoint list — no docs-scraping required.

💳

Three ways to pay

Wallet signature via x402 for ephemeral agents, prepaid balance via rs_live_ API key for long-running ones, account JWT for human dashboard sessions. Same endpoints, caller picks the path.

⏱️

Expiry to the second

Whatever the variant — Storage file, Mailbox messages, Checkpoint versions — the underlying resource is physically deleted at the lease's expires_at. Not day-granularity, not best-effort.

🤝

Cross-variant handoff

Any lease can be handed off. Same /api/handoff/:lease_id endpoint for Storage, Mailbox, or Checkpoint. Token IS the credential; redeeming agent needs no auth. Free at v1 defaults.

⚙️

Three shortcuts, one primitive

Storage is the configurable primitive. Mailbox and Checkpoint are pre-configured shortcuts for common agent patterns. Scratchpad + Cron variants coming. Learn one, you've learned them all.

🔒

S3-grade reliability

Every variant is backed by AWS S3. 99.999999999% durability. No blockchain storage, no probabilistic guarantees. The bytes are where you'd expect them.

API Reference

Every endpoint.
Grouped by lease variant.

Three variant groups plus cross-cutting Features and Discovery. All endpoints return JSON; body-carrying creation endpoints accept raw bytes (Storage) or JSON (Mailbox drop, Checkpoint create/write). The full OpenAPI spec lives at docs.relaystation.ai/reference/openapi.html.

Storage lease
POST
/api/store
Create a Storage lease. Body = raw file bytes. Required headers: X-File-Name, X-Size-Bytes, X-Duration-Seconds. Auth: X-Payment (x402) or Authorization: Bearer rs_live_…. Returns { lease_id, expires_at, duration_human, size_bytes, paid_usdc, … }.
GET
/api/download/{lease_id}
Stream the file bytes back to the owner. Auth required. Returns 410 Gone if the lease has expired.
GET
/api/leases
List leases owned by the authenticated actor. Includes active, expired, and tombstoned rows with access history.
Mailbox lease
POST
/api/mailbox
Create a Mailbox lease. Required headers: X-Capacity-Bytes, X-Duration-Seconds. Optional: X-Webhook-Url, X-Webhook-Secret, X-Max-Message-Bytes, X-Max-Messages. Returns { lease_id, drop_url, poll_url, webhook_secret, capacity_bytes, expires_at }. Webhook secret returned exactly once.
GET
/api/mailboxes
List the caller's mailboxes with per-row usage aggregates (bytes used, message count).
POST
/api/mailbox/{drop_token}/drop
Drop a payload. No auth — the drop token is the credential. Rate-limited per IP and per mailbox.
GET
/api/mailbox/{mailbox_id}/messages
Owner lists queued messages. Auth required.
GET
/api/mailbox/{mailbox_id}/messages/{message_id}
Owner reads a single message body. DELETE on the same path removes one message; DELETE /api/mailbox/{id} removes the whole mailbox early.
Checkpoint lease
POST
/api/checkpoint
Create a Checkpoint lease. Required headers: X-Workflow-Id (^[A-Za-z0-9._-]{1,128}$), X-Duration-Seconds. Optional: X-Max-Body-Bytes (default from config). Body = initial JSON state. Returns { lease_id, workflow_id, max_body_bytes, expires_at }.
GET
/api/checkpoints
List the caller's checkpoints.
GET
/api/checkpoint/{workflow_id}
Read the latest body. Version + last-written-at + expiry ride in X-Checkpoint-* response headers.
PUT
/api/checkpoint/{workflow_id}
Overwrite the body with a new JSON blob. No additional payment — the initial reservation covers writes up to max_body_bytes. Version counter auto-increments.
DELETE
/api/checkpoint/{workflow_id}
Delete the checkpoint early. No refund; the reservation was prepaid.
Features — Handoff (any lease)
POST
/api/handoff/{lease_id}
Issue a sealed claim token against any lease you own. Free at v1 defaults. Body: max_claims (default 1), delete_on_claim (default false), ttl_seconds (default 3600). Returns { handoff_token, claim_url, expires_at, lease_expires_at }.
GET
/api/handoffs/{lease_id}
List outstanding tokens for a lease — token prefix, claims remaining, expiry, delete-on-claim flag, handoff id for revocation.
DELETE
/api/handoffs/{id}
Revoke an outstanding token. Idempotent — a second call returns 404. Claims already completed stand.
GET
/api/claim/{token}
No auth — the token is the credential. Streams the underlying resource back and, if delete_on_claim, removes the lease after the final claim.
Discovery & pricing
GET
/api/pricing
Machine-readable service discovery. Rate, wallet address, minimums, duration bounds, canonical endpoint list, worked examples. Mirror at /.well-known/x402.json.
GET
/api/quote?size_bytes={n}&duration_seconds={n}
Exact price in USDC. Stateless — no reservation, no lock. Or calculate yourself: (bytes/1073741824) × (seconds/86400) × 0.001.