What is relayfor.si?

API overview

Two surfaces, two keys. Everything to know before the first request.

relayfor.si has two APIs. Your server runs your project with the management API and its secret key. Your agents call models through the RFS Router, each with a router key that spends one token's credit.

SurfaceBase URLKeyWho calls it
Management APIhttps://relayfor.si/api/project/v1Secret key rf_sk_Your server
RFS Routerhttps://relayfor.si/api/v1Router key rf_ai_Your agents

Management API

Launch tokens, bring existing ones, set fee strategies, read tokens and payouts, make router keys, buy credit, and receive webhooks. Its OpenAPI 3.1 file describes every operation, and these pages are drawn from it.

GroupWhat it covers
ProjectThe project a secret key belongs to
Fee strategiesHow your part of each token's creator fee splits
LaunchesLaunches for the creator's wallet to sign
TokensYour tokens, and bringing a token already on pump.fun
AccountsCredit accounts, their ledgers and USDC purchases
KeysRouter keys and their spending limits
UsageRouter usage by day, account, key and model
StatementsEach month's credits and spend
WebhooksEndpoints, deliveries and signing secrets

Authentication

Send the project's secret key as a bearer token, or as x-api-key:

Authorization: Bearer rf_sk_...

Secret keys are made on the dashboard's Keys page and shown once. They belong on a server: the management API sends no CORS headers, so a browser can't call it, and a key in a web page can be read by anyone.

Idempotency

Every POST needs an Idempotency-Key header: any unique string, a UUID. A retry with the same key and body gets the first answer back for 24 hours, so a request that timed out can be sent again without launching twice. The same key with another body is refused with idempotency_mismatch.

  • A secret comes back too. Retrying POST /keys answers the same rf_ai_ key, and retrying POST /webhooks or POST /webhooks/{id}/rotate the same whsec_ secret. It is null only when it can no longer be given back.
  • While the first request runs, a retry is refused with 409 idempotency_in_progress and Retry-After: 2. Wait, then send it again.
  • A request that died mid-run (a timeout, a deploy) frees its key after 6 minutes, so the same request can run again.

Answers and errors

Answers are JSON. Amounts in dollars are decimal strings ("41.208734"), amounts on chain are base units as strings ("20000000" lamports is 0.02 SOL), and times are ISO 8601 in UTC. Every answer carries a request-id header.

Every refusal has one shape, with the HTTP status that fits:

{
  "error": {
    "code": "invalid_request",
    "message": "At most 13 bytes (pump.fun's limit).",
    "param": "symbol",
    "request_id": "req_ODwyxD4b59lXGyN8"
  }
}

Branch on code: codes are stable, messages may be reworded. param names the field at fault. See every code in Errors.

Pagination

Lists answer newest first, as { "data": [...], "next_cursor": "..." }. Pass limit (1 to 100, 20 by default) and cursor=<next_cursor> for the next page. next_cursor is null on the last page.

RFS Router

The OpenAI and Anthropic formats over hundreds of models, paid by a token's credit. Any OpenAI or Anthropic SDK works once you change two settings: the address and the key.

MethodPathFormatKey
POST/chat/completionsOpenAI Chat CompletionsYes
POST/responsesOpenAI ResponsesYes
POST/messagesAnthropic MessagesYes
POST/imagesImage generationYes
GET/modelsEvery model and its priceNo
GET/images/modelsEvery image model and its priceNo
GET/balanceWhat the key can spendYes

The Anthropic SDKs take https://relayfor.si/api as their base URL: they add /v1 themselves. Any other path under /api/v1, such as embeddings, answers 404 not_found in JSON.

  • Bodies pass through as sent. Every field of each format works, beyond the ones these pages list.
  • Stateless. Nothing is stored between calls, and prompts and answers are never kept. Send the conversation every time.
  • From anywhere. The router accepts calls from any origin, so browser tools work. A router key in a web page can be read by its visitors: give it a small spending limit, or keep it on a server.

Answers follow each format's own shape, with three additions:

Field or headerWhat it is
usage.costWhat the call was charged, in dollars. On every format but Messages.
x-relayfor-call-idThe call's id. Its charge in the account's ledger is call: and this id.
x-generation-idThe model provider's id for the answer.

Errors use each format's own shape, with a stable code. See Errors and Rate limits.

On this page