ReinkeyDocsConsole

Limits

These are the numbers a facilitator enforces. They are configuration, not protocol: if you run your own (backend/ in the repository) you set your own. The values below are the defaults in backend/src/config/config.ts and the constants compiled into the controllers; where the hosted testnet facilitator at https://reinkey.onrender.com differs, both are given.

A rejection for any of these is RATE_LIMITED (HTTP 429, with Retry-After), except where noted. See Reason codes.

Rate limits

Limit
Per IP, general3000 / minuteFixed 60-second window. The payment path counts against it, so it is deliberately loose. GET /events and GET /health are exempt.
Per IP, costly30 / minuteEndpoints that make the server pay a chain fee or write an unverified record: POST /channels/:id/claim, POST /receipts/:id/attest, POST /v1/report, POST /demo/agent/run, POST /demo/owner/freeze.
Per channel, vouchers1200 / minuteCounted per channel, in a one-minute window, after the signature verifies — a forged voucher can't burn someone else's budget.
Open SSE connections, per IP8GET /events. A ninth connection is refused with RATE_LIMITED.
Open SSE connections, total200Across all clients.

Set IP_RATE_LIMIT_PER_MINUTE=0 to turn the IP limiter off entirely when self-hosting.

Stream sessions

Used by @reinkey/meter's rk.stream() and the /streams endpoints.

Limit
Open sessions per channel4
Open sessions, total1000
Idle timeout90 seconds without a /wait or a voucher → the session ends with ABORTED
POST /streams/:id/wait long polldefault 10 s, minimum 1 s, maximum 30 s (timeoutMs)
Voucher timeout in rk.stream()default 10 s (voucherTimeoutMs), then the stream ends with TIMEOUT

A /wait on a channel whose remaining deposit can't cover the next slice returns exhausted immediately rather than waiting.

Settlement

The facilitator claims on the seller's behalf; these decide when.

DefaultHosted facilitator
Claim threshold (unclaimed amount that triggers a claim)1000000 base units (0.1 USDC)250000 (0.025 USDC)
Claim scheduler interval30 s30 s
Expiry margin — always claim this many ledgers before a channel expires120 ledgers (≈10 min)same
Voucher safety margin — a voucher is refused this close to expiry, with CHANNEL_EXPIRING60 ledgers (≈5 min)same
Manual claim (POST /channels/:id/claim) minimum1000 base unitssame
Manual claim cooldown, per channel30 ssame

Page sizes

EndpointDefaultMaximum
GET /accounts/:addr/ledger50200
GET /receipts50200
GET /float?history=200 samples500
GET /sellers/:payTo/revenue?days=30 days365
GET /events backlog before the live streamlast 200 events

GET /channels returns every known channel, newest first, and is not paginated.

Demo seller prices

The facilitator hosts a metered seller so you can try the flow without writing one. Prices are in USDC base units (7 decimals).

ResourcePriceSlice
GET /demo/book5000 per request (0.0005 USDC)
GET /demo/ticker/stream1000 per second (0.0001 USDC)1 second on the hosted facilitator (default 10)
POST /demo/chat200 per token (0.00002 USDC)50 tokens

The live values are in GET /demo/info and GET /llms.txt; read them rather than hard-coding these.

Protocol limits that are not configuration

  • Amounts are i128 base units. USDC on Stellar has 7 decimals. Use bigint; never floats.
  • A channel's deposit is the buyer's maximum loss, and one slice is the seller's.
  • One contract call per transaction on Soroban. That is why openChannelWith (swap, then open) is two transactions.
  • A voucher's cumulative amount only increases and may never exceed the deposit.

Reinkey runs on Stellar testnet. The contracts are unaudited. Don't send mainnet funds.