Skip to content

HTTP API reference

The stoka API surface is small. Every route is either:

  • Paid — returns 402 first, expects a signed X-PAYMENT retry.
  • Wallet-signed — free, but requires an Authorization: Stellar … header computed from a server-issued challenge.
  • Public — no payment, no auth; safe to poll.

Base URLs

EnvBase URL
Mainnethttps://api.stoka.space
Testnethttps://test.api.stoka.space

Routes

GET /.well-known/stoka.json

Public. Manifest: service identity, pricing table, x402 configuration, feature flags. Used by the client libraries for automatic discovery.

POST /v1/store

Paid. Create a new blob. Headers:

HeaderRequiredPurpose
X-Stoka-KeyyesKey under which the blob is stored.
X-Stoka-TTL-SecondsnoLifetime in seconds. Default: 30 days. Clamped to server minimum (1 hour) and maximum (90 days).
Content-Typeyesapplication/octet-stream.
X-PAYMENTyes (retry)Base64 x402 payment header from the 402 challenge.

Response: 201 with JSON (owner_pubkey, key, expires_at, ttl_seconds, charged_atomic).

PUT /v1/object/{key}

Paid. Overwrite a blob owned by the signing wallet. 404 if the key is not yours. Same headers as POST /v1/store minus X-Stoka-Key.

GET /v1/retrieve/{key}

Paid. Fetch a blob. Headers:

HeaderRequiredPurpose
X-Stoka-OwnernoHints the owner so the 402 price is exact. Defaults to caller's wallet.
X-PAYMENTyes (retry)Base64 x402 payment header.

Response: 200 with the raw bytes and headers:

  • X-Stoka-Owner-Pubkey — G-address of the blob owner
  • X-Stoka-Expires-At — RFC 3339 timestamp

DELETE /v1/object/{key}

Wallet-signed. Free. Idempotent: deleting a missing or non-owned key still returns 204. Headers:

HeaderRequiredPurpose
AuthorizationyesStellar <G-addr>:<challenge-id>:<hex-sig>

POST /v1/auth/challenge

Public. Request a single-use message to sign for a given audience (delete, usage, profile). Body:

json
{ "audience": "delete" }

Response: { "challenge_id": "…", "message": "…" }. The message is what you sign with your wallet's Ed25519 key (hex-encoded signature).

GET /v1/me/usage

Wallet-signed. Free. Returns per-UTC-day USDC spend counters for the signing wallet. Query param days=N (clamped 1..90).

Response shapes

  • Paid success — the route's native body (JSON for writes, raw bytes for retrieve).
  • 402 challenge{ x402Version, accepts: PaymentRequirements[], error? }. Auto-paying clients read accepts[0] and retry.
  • Non-2xx{ "error": "…" } for server-generated errors. Facilitator / RPC errors from the payment flow come back as a second 402 with an informative error string.

Error codes the clients surface

Client symbolHTTP statusMeaning
StokaError(400)400Malformed request (bad key, missing header).
StokaError(404)404Key not found or not owned.
StokaError(5xx)5xxServer issue; retry with backoff.
PaymentRequired402Auto-pay failed: no signer, unfunded wallet, missing trustline, unknown asset.

MIT Licensed.