Relaystation logo Relaystation

The three persistence tiers

Every file-taking or file-producing op on Relaystation uses the same I/O model, with three tiers. You pick a tier per call by how you pass (or receive) the bytes — there is no setup step and no required storage product.

TierWhat it isCostLifetimeScope
Inlinebase64 in the request/response bodyfree (part of the call)none — nothing persiststhe one call
Scratchcustomer-scoped working storagefree24 hoursyou only — reusable across calls
Batonthe durable storage productpaid (quoted at create)what you configureshareable, witnessed, durable

Compute is priced per op on the metered input regardless of which tier the bytes came from. Scratch costs nothing; storage and egress economics live in the baton tier alone.

Inline — small files, zero ceremony

Up to 4 MiB (decoded), pass { "inline": "<base64>" } as the op’s file field and get small outputs back the same way: { "output": { "inline": "<base64>", "sizeBytes": ..., "contentType": ... } }. Nothing is stored; there is nothing to clean up. (One asymmetry, stated honestly: the output side gates on the base64-encoded size against the same 4 MiB threshold — base64 inflates ~1.37×, so raw outputs above ~3 MiB come back as a scratch reference instead. Handle both shapes and the difference never bites; see receiving outputs.)

Scratch — the free working tier

Over 4 MiB (or whenever you’d rather upload once and reuse), use scratch:

  1. POST /v1/cputools/upload-url (free) returns a presigned upload form and an inputKey like scratch/<your-customer-id>/<uuid>.
  2. Upload your file (up to 50 MB) with one multipart POST to that URL.
  3. Pass { "inputKey": "..." } as any op’s file field — as many ops, as many times as you like, for 24 hours.

Scratch keys are namespaced to your customer identity. Another customer’s key — even if leaked — resolves to 404 for you, and yours for them. The same gate admits all three auth modes: API key, wallet JWT, or a signed x402 payment (so an account-less agent can use scratch too).

When an op’s output exceeds the inline threshold (measured on the encoded size — raw bytes above ~3 MiB), it lands in your scratch automatically and the response carries both handles:

{ "output": { "outputKey": "scratch/<you>/<uuid>", "outputUrl": "https://…presigned, 1 hour…", "sizeBytes": 12023329, "contentType": "image/png" } }

outputUrl is for downloading now. outputKey is for chaining.

Chaining: outputKey is an inputKey

An op’s outputKey lives in the same namespace as your uploads, so you can feed it straight into the next op’s inputKey — no download, no re-upload, no pipeline product:

# 1. Upload once (12 MB scan)
curl -s -X POST https://api.relaystation.ai/v1/cputools/upload-url \
  -H "Authorization: Bearer $KEY" -d '{"ext":"png"}'
# → { "inputKey": "scratch/<you>/aaaa.png", "url": ..., "fields": {...} }
#   (multipart-POST the file to url+fields)

# 2. First op — output exceeds 4 MiB, so it lands in scratch
curl -s -X POST https://api.relaystation.ai/v1/image/convert \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"file":{"inputKey":"scratch/<you>/aaaa.png"},"format":"png"}'
# → { "output": { "outputKey": "scratch/<you>/bbbb", ... } }

# 3. Chain — the outputKey IS the next inputKey
curl -s -X POST https://api.relaystation.ai/v1/image/metadata \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"file":{"inputKey":"scratch/<you>/bbbb"}}'
# → { "metadata": { "width": 2000, "height": 2000, "format": "png", ... } }

Each step is its own pay-per-call op with its own receipt. The bytes never leave the platform between steps, and the 24-hour scratch window comfortably covers a working session. (For chaining the tabular ops — filter, sort, join, SQL — in a single call, see POST /v1/pipeline, which threads bytes step-to-step and bills the sum.)

Baton — when the result needs to outlive the day

Scratch is working storage: free, yours, gone in 24 hours. When an output needs to be durable (kept past today), shareable (handed to another agent or a human via a token), or witnessed (tamper-evident, provable), that is the baton tier — a paid product with its own quoted price, lifecycle, and trust options.

Batons are optional, always. No op requires one; the lodestone path — one call, one payment, result back — never gains a mandatory storage step.