Reference

Limits & quotas

Rate limits

LimitValueScope
Sustained request rate30 per minutePer credential
Burst3 per secondPer credential
Credential provisioning5 per hourPer source address

Exceeding a request limit returns 429 with Retry-After: 5:

HTTP/1.1 429 Too Many Requests
Retry-After: 5

{"error":"rate limited","retryAfter":5}

The rate limit is keyed on the credential query parameter, so separate credentials get separate budgets. If you need more throughput for a single workload, do not rotate credentials to get around it.

Thirty per minute is lower than it sounds — design for it

The API is a control plane, not a data path: object bytes never traverse it, so a well-built client makes very few calls. A 1 GiB upload is two calls plus the direct shard writes. A client that hits 30 per minute is usually making one call per small object rather than packing them into shared slabs — see Packing strategy.

Account & billing limits

The account API at https://tessera.storage/api/v1 applies its own limits, separate from the storage rate limits above:

LimitValue
Public signup & auth endpointsRate limited at the edge by nginx zones. Any challenge, where enabled, is scoped to /api/v1/auth/* and never applied to the rest of the API.
New accounts3 per source IP (IPv6 /64) and 20 per /24 (IPv6 /48) per rolling 24 hours, agents and humans together; 429 signup_limit beyond that. Each signup also needs an ALTCHA proof of work (X-Altcha).
Top-up amount$0.01–$10,000 per intent (Tessera's floor; x402 uses only this), quantized to whole cents. Crypto through the payment processor (deposit address or invoice) also needs the coin's processor minimum — about $0.38 for USDC on Base, more for most other coins; live values from GET /billing/topup/minimums or tessera topup --minimums.
Sign-in linksSingle use, expire after 15 minutes.
Browser sessions30-day tessera_session cookie; state-changing requests must match the site origin.

See Accounts & billing for the endpoints these apply to.

Storage caps

Each credential carries caps recorded at provisioning:

CapEnforced
Maximum stored bytesYes — 402 on prepare-write, slabs, and objects
Daily read bytesRecorded, not currently enforced
Daily write bytesRecorded, not currently enforced
Monthly spendRecorded, not currently enforced

Cap accounting is in whole 4 MiB sectors:

EndpointAccounted as
POST /prepare-writetotalShards × 4 MiB
POST /slabssectors × 4 MiB per slab
POST /objects4 KiB per object

Small objects in their own slabs are expensive

A 100 KiB object written as its own 10-of-30 slab is accounted at 30 whole sectors — 120 MiB, a 1200× overhead against its logical size. This is arithmetic, not a penalty: 30 providers each hold a sector, and a sector is the unit they deal in. Pack small objects into shared slabs and the overhead disappears.

Erasure coding constraints

ConstraintValue
Minimum redundancy (totalShards / minShards)1.5×
Maximum redundancy4.0×
minShards≤ totalShards
Default geometry10 data + 20 parity = 30
encryptionKey lengthexactly 32 bytes
Duplicate provider within a slabrejected
Duplicate sector root within a slabrejected
Sector size4 MiB

Request constraints

ConstraintValue
Object keyexactly 32 bytes, 64 hex characters, no /
Slab IDexactly 32 bytes, 64 hex characters
Provider public keyed25519: + 64 hex characters
Sector root64 hex characters
credential / signature encodingbase64url with padding
appKey encodingbase64url without padding
Byte-slice JSON fieldsstandard base64 with padding
validUntilunix seconds, decimal in the query, little-endian uint64 in the hash

Pagination

EndpointMechanismDefaultNotes
GET /slabslimit + offset50Not a stable cursor; entries can be missed if the set changes between pages.
GET /objectslimit + after timestamp50Preferred. Stable enough for synchronisation; make application idempotent for timestamp ties.

For a complete enumeration, walk GET /objects and collect slab IDs from the records rather than paging GET /slabs.

Signature expiry

validUntil is chosen entirely by you. There is no server-imposed maximum, which means the discipline is yours:

  • 60 seconds for interactive calls.
  • Minutes, not days. A signed URL is a bearer capability until it expires; expiry is the only replay protection in the scheme.
  • Never sign a DELETE far into the future. That signature is a deletion capability for as long as it remains valid, wherever the URL was logged.

No CORS

The API cannot be called from a browser

No Access-Control-Allow-Origin header is sent on any endpoint, so cross-origin browser requests are blocked by the browser regardless of what you do client-side. Call the API from a server-side runtime, or proxy it through your own backend — which is the better pattern anyway, since it keeps your credential's private key off the client.

Availability expectations

EndpointBehaviour
prepare-writeMay return 503 when provider availability dips. Always retry with backoff.
Manifest endpointsExpected to be consistently available; 500 is a bug worth reporting.
Shard reads and writesDepend on individual providers, which fail routinely. Your client should treat individual provider failure as normal and route around it.

The service is provided without a service level agreement.