Management API

Management API v1

A REST API for backend integrations — create, configure, and manage your paid endpoints via HTTP.

RESTService key authCRUDPricing control

The Management API lets you automate the full lifecycle of a RelAI API — ideal for CI/CD pipelines, multi-tenant platforms, or any workflow where you need to spin up or tear down paid endpoints on the fly.

MethodPathAuthDescription
POST/mcp/management/bootstrap/agentAutonomous agent key provisioning (wallet signature)
POST/mcp/management/bootstrapBearer JWTBootstrap service key from user JWT (one-time)
POST/v1/keysBearer JWTCreate a service key
GET/v1/keysBearer JWTList your service keys
DELETE/v1/keys/:keyBearer JWTRevoke a service key
POST/v1/apisX-Service-KeyCreate an API
GET/v1/apisX-Service-KeyList your APIs
GET/v1/apis/:apiIdX-Service-KeyGet an API
PATCH/v1/apis/:apiIdX-Service-KeyUpdate API metadata
DELETE/v1/apis/:apiIdX-Service-KeyDelete an API
GET/v1/apis/:apiId/pricingX-Service-KeyGet endpoint pricing
PUT/v1/apis/:apiId/pricingX-Service-KeySet endpoint pricing
GET/v1/apis/:apiId/statsX-Service-KeyAggregated revenue & request count
GET/v1/apis/:apiId/paymentsX-Service-KeyPaginated payment history
GET/v1/apis/:apiId/logsX-Service-KeyUsage logs (same format as dashboard)

Authentication

The Management API uses two schemes depending on the operation:

Bearer JWT

Used on /v1/keys endpoints to create and revoke service keys. This is the same token you get from logging in at relai.fi.

X-Service-Key

Used on all /v1/apis endpoints. Suitable for CI/CD and server-to-server calls — no browser session needed.

Get a service key

The easiest way is through the dashboard: Dashboard → Service Keys → New key. The key is shown once — copy it immediately into your environment or secrets manager.

You can also create one via API — log in to relai.fi to get a JWT, then:

bash
curl -X POST https://api.relai.fi/v1/keys \
  -H "Authorization: Bearer <your-jwt>" \
  -H "Content-Type: application/json" \
  -d '{"label": "production"}'
Response — 201 Created
{
  "key": "sk_live_a1b2c3d4e5f6...",
  "label": "production",
  "active": true,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "note": "Store this key securely — it will not be shown again."
}

The plaintext key is shown once. Store it in an environment variable or secrets manager immediately.

Agent self-setup (fully autonomous)

Agents can provision their own service key with zero human involvement — no dashboard visit, no JWT, no copy-paste. The agent uses its own keypair (Solana ed25519 or EVM secp256k1) to sign a challenge and receive a service key. The wallet address becomes the agent's permanent identity on RelAI.

1

Request challenge

POST your public key → receive a message to sign

2

Sign message

Sign with your private key (nacl/ethers/web3)

3

Get service key

POST signature → receive sk_live_... stored forever

Python — full autonomous bootstrap (Solana)
from solders.keypair import Keypair
import base58, requests

BASE = "https://api.relai.fi/mcp/management/bootstrap/agent"
kp = Keypair()  # or: Keypair.from_bytes(bytes.fromhex(os.environ["AGENT_PRIVKEY"]))

# Step 1 — request challenge
msg = requests.post(BASE, json={"publicKey": str(kp.pubkey())}).json()["message"]

# Step 2 — sign
sig = base58.b58encode(bytes(kp.sign_message(msg.encode()))).decode()

# Step 3 — get service key (runs once, then store the key)
sk = requests.post(BASE, json={
    "publicKey": str(kp.pubkey()),
    "signature": sig,
    "message": msg,
    "label": "my-agent",
}).json()["key"]

print(f"Service key: {sk}")  # → sk_live_...
TypeScript — EVM (ethers.js)
import { ethers } from "ethers";

const BASE = "https://api.relai.fi/mcp/management/bootstrap/agent";
const wallet = ethers.Wallet.createRandom(); // or load from env

// Step 1 — request challenge
const { message } = await fetch(BASE, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ publicKey: wallet.address }),
}).then(r => r.json());

// Steps 2+3 — sign and get key
const signature = await wallet.signMessage(message);
const { key } = await fetch(BASE, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ publicKey: wallet.address, signature, message, label: "my-agent" }),
}).then(r => r.json());

console.log("Service key:", key); // → sk_live_...

Run once, store forever. Save the keypair (private key) and the returned sk_live_... securely. On every subsequent start the agent loads both from env/secrets — no server calls needed until the key is revoked.

List and revoke keys

bash — list keys (masked)
curl https://api.relai.fi/v1/keys \
  -H "Authorization: Bearer <your-jwt>"
bash — revoke a key
curl -X DELETE https://api.relai.fi/v1/keys/sk_live_... \
  -H "Authorization: Bearer <your-jwt>"

API management

All endpoints below require the X-Service-Key header.

POST/v1/apis — Create an API

Creates a new x402-monetised API. Optionally set initial endpoint pricing in the same request via the endpoints array.

FieldTypeRequiredDescription
namestringyesDisplay name shown in the marketplace
baseUrlstringyesTarget server base URL (e.g. https://my-api.example.com)
descriptionstringnoShort description
networkstringnoPayment network. Default: solana
facilitatorstringnoFacilitator. Default: relai
x402Versionnumberno1 or 2. Default: 2
merchantWalletstringnoWallet address receiving payments
subdomainstringnoCustom subdomain under relai.fi — must be unique
websiteUrlstringnoLink to your API docs or homepage
logoUrlstringnoURL of the API logo
ownerEmailstringnoContact email for the API owner
endpointsarraynoInitial pricing (see below)

endpoints[] item fields:

FieldTypeRequiredDescription
pathstringyesEndpoint path, e.g. /v1/predict
methodstringnoHTTP method: get | post | put | patch | delete. Default: get
usdPricenumbernoPrice per call in USD. Default: 0.01
descriptionstringnoEndpoint description
enabledbooleannoWhether the endpoint is active. Default: true
bash
curl -X POST https://api.relai.fi/v1/apis \
  -H "X-Service-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Prediction API",
    "baseUrl": "https://inference.example.com",
    "description": "Pay-per-call ML inference",
    "network": "base",
    "merchantWallet": "0xYourWalletAddress",
    "endpoints": [
      { "path": "/v1/predict", "method": "post", "usdPrice": 0.05 },
      { "path": "/v1/status",  "method": "get",  "usdPrice": 0.001 }
    ]
  }'
Response — 201 Created
{
  "apiId": "1751234567890",
  "name": "My Prediction API",
  "description": "Pay-per-call ML inference",
  "baseUrl": "https://inference.example.com",
  "subdomain": null,
  "network": "base",
  "facilitator": "relai",
  "x402Version": 2,
  "status": "approved",
  "merchantWallet": "0xYourWalletAddress",
  "createdAt": "2025-01-01T00:00:00.000Z",
  "updatedAt": "2025-01-01T00:00:00.000Z"
}

GET/v1/apis — List APIs

Returns all APIs owned by the authenticated service key's user.

bash
curl https://api.relai.fi/v1/apis \
  -H "X-Service-Key: sk_live_..."
Response — 200 OK
{
  "apis": [
    { "apiId": "1751234567890", "name": "My Prediction API", ... }
  ]
}

GET/v1/apis/:apiId — Get an API

bash
curl https://api.relai.fi/v1/apis/1751234567890 \
  -H "X-Service-Key: sk_live_..."

PATCH/v1/apis/:apiId — Update API metadata

All fields are optional. Only the provided fields are updated. Updatable fields: name, description, baseUrl, merchantWallet, websiteUrl, logoUrl.

bash
curl -X PATCH https://api.relai.fi/v1/apis/1751234567890 \
  -H "X-Service-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "description": "Updated description" }'

DELETE/v1/apis/:apiId — Delete an API

bash
curl -X DELETE https://api.relai.fi/v1/apis/1751234567890 \
  -H "X-Service-Key: sk_live_..."
Response — 200 OK
{ "success": true, "apiId": "1751234567890" }

Pricing management

Pricing is configured per endpoint (path + method). All monetary values are in USD.

GET/v1/apis/:apiId/pricing

bash
curl https://api.relai.fi/v1/apis/1751234567890/pricing \
  -H "X-Service-Key: sk_live_..."
Response — 200 OK
{
  "apiId": "1751234567890",
  "endpoints": [
    { "path": "/v1/predict", "method": "post", "usdPrice": 0.05, "network": "base", "enabled": true },
    { "path": "/v1/status",  "method": "get",  "usdPrice": 0.001,"network": "base", "enabled": true }
  ]
}

PUT/v1/apis/:apiId/pricing

Replaces all endpoint pricing for an API. To update a single endpoint, send the full list including the unchanged entries.

bash
curl -X PUT https://api.relai.fi/v1/apis/1751234567890/pricing \
  -H "X-Service-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "endpoints": [
      { "path": "/v1/predict", "method": "post", "usdPrice": 0.10 },
      { "path": "/v1/status",  "method": "get",  "usdPrice": 0.001 }
    ]
  }'
Response — 200 OK
{ "success": true, "apiId": "1751234567890", "updated": 2 }

Analytics

Monitor revenue and individual payments for any API you own.

GET/v1/apis/:apiId/stats

Aggregated totals: number of paid requests and total revenue in USD.

bash
curl https://api.relai.fi/v1/apis/1751234567890/stats \
  -H "X-Service-Key: sk_live_..."
Response — 200 OK
{
  "apiId": "1751234567890",
  "totalRequests": 142,
  "totalRevenue": 7.1,
  "currency": "USD"
}

GET/v1/apis/:apiId/payments

Paginated list of individual payments. Results are sorted newest-first.

Query paramTypeDefaultDescription
limitnumber50Number of records to return (max 500)
cursorstringTransaction ID — return records after this entry
fromstringISO date — filter from this timestamp
tostringISO date — filter up to this timestamp
bash
curl "https://api.relai.fi/v1/apis/1751234567890/payments?limit=20&from=2025-01-01" \
  -H "X-Service-Key: sk_live_..."
Response — 200 OK
{
  "apiId": "1751234567890",
  "payments": [
    {
      "transaction": "0xabc123...",
      "path": "/v1/predict",
      "method": "post",
      "amount": 0.05,
      "currency": "USD",
      "network": "base",
      "status": "settled",
      "success": true,
      "payer": "user_abc",
      "createdAt": "2025-06-01T12:34:56.000Z"
    }
  ],
  "nextCursor": "0xabc123..."
}

To paginate, pass the returned nextCursor value as the cursor query param in the next request. When nextCursor is null, you have reached the end.

GET/v1/apis/:apiId/logs

Usage logs in the exact same format as the Usage Logs tab in the dashboard — fields include timestamp, method, path, status, cost, duration, and transaction.

Query paramTypeDefaultDescription
limitnumber50Records to return (max 500)
cursorstringTransaction ID — return records after this entry
fromstringISO date — filter from this timestamp
tostringISO date — filter up to this timestamp
bash
curl "https://api.relai.fi/v1/apis/1751234567890/logs?limit=20&from=2025-01-01" \
  -H "X-Service-Key: sk_live_..."
Response — 200 OK
{
  "items": [
    {
      "id": "1751234567890-0xabc123...",
      "timestamp": "2025-06-01T12:34:56.000Z",
      "method": "POST",
      "path": "/v1/predict",
      "status": "settled",
      "cost": 0.05,
      "currency": "USD",
      "duration": 312,
      "transaction": "0xabc123...",
      "network": "base",
      "success": true,
      "payer": "user_abc"
    }
  ],
  "nextCursor": "0xabc123..."
}

AI Agent / MCP

The Management API is exposed as an MCP (Model Context Protocol) server at POST /mcp/management. AI agents (Claude, Cursor, custom LLM pipelines) can call all management tools directly — no browser, no dashboard.

The agent authenticates with X-Service-Key — the same key used for the REST API. No JWT or login flow needed.

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

json
{
  "mcpServers": {
    "relai-management": {
      "url": "https://api.relai.fi/mcp/management",
      "headers": {
        "X-Service-Key": "sk_live_..."
      }
    }
  }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

json
{
  "mcpServers": {
    "relai-management": {
      "serverUrl": "https://api.relai.fi/mcp/management",
      "headers": {
        "X-Service-Key": "sk_live_..."
      }
    }
  }
}

Cursor

Add to .cursor/mcp.json in your project (or global ~/.cursor/mcp.json):

json
{
  "mcpServers": {
    "relai-management": {
      "url": "https://api.relai.fi/mcp/management",
      "headers": {
        "X-Service-Key": "sk_live_..."
      }
    }
  }
}

Available tools

Once connected, the agent has access to these tools:

ToolDescription
create_apiCreate a new x402-monetised API (status: pending)
list_apisList all APIs owned by this service key
get_apiGet details of a specific API
update_apiUpdate API metadata (name, baseUrl, description…)
delete_apiPermanently delete an API
set_pricingReplace endpoint pricing configuration
get_pricingGet current endpoint pricing
get_statsGet aggregated revenue and request count
get_logsGet usage logs with date filtering and pagination

Example prompt: "Create a monetised API for https://ml.myapp.com, charge $0.05 per /v1/predict call on Base network" — the agent will call create_api and set_pricing automatically.

Full workflow example

End-to-end: obtain a key, create an API, set pricing, verify.

bash
# 1. Create a service key (requires your user JWT)
KEY=$(curl -s -X POST https://api.relai.fi/v1/keys \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"label":"ci"}' | jq -r .key)

# 2. Create an API
API_ID=$(curl -s -X POST https://api.relai.fi/v1/apis \
  -H "X-Service-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weather API",
    "baseUrl": "https://weather.example.com",
    "network": "base",
    "merchantWallet": "0xYourWallet"
  }' | jq -r .apiId)

# 3. Set pricing
curl -X PUT "https://api.relai.fi/v1/apis/$API_ID/pricing" \
  -H "X-Service-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{"endpoints":[{"path":"/forecast","method":"get","usdPrice":0.002}]}'

# 4. Verify
curl "https://api.relai.fi/v1/apis/$API_ID" \
  -H "X-Service-Key: $KEY"

Error reference

All error responses share the same shape:

{ "error": "Human-readable description." }
StatusMeaning
400Validation error — missing or invalid fields
401Missing or invalid credentials
403Authenticated but not authorised for this resource
404Resource not found
409Conflict — e.g. subdomain already taken
500Internal server error

Supported networks

Only networks with EIP-3009 (transferWithAuthorization) compliant tokens are supported. For skale-base, multiple tokens are accepted automatically — no token address configuration needed.

network valueChainToken
solanaSolana MainnetUSDC
baseBase MainnetUSDC
base-sepoliaBase SepoliaUSDC
skale-baseSKALE BaseUSDC, USDT, skUSD, ETH, BTC, …
polygonPolygonUSDC
avalancheAvalanche C-ChainUSDC
ethereumEthereum MainnetUSDC

See the Networks page for full details including chain IDs, token addresses, and gas sponsoring.

Agent Discovery

RelAI exposes machine-readable endpoints so AI agents and tooling can discover the platform automatically — without any hardcoded configuration.

URLFormatPurpose
/.well-known/ai-plugin.jsonJSONOpenAI plugin manifest — discovered by ChatGPT, LangChain, AutoGPT and compatible agents
/.well-known/agent.jsonJSONAgent Protocol manifest — MCP endpoint, capabilities, auth info
/llms.txtPlain textFull LLM context — how to use the API, agent bootstrap flow, MCP config
/openapi.jsonOpenAPI 3.1Full Management API spec — importable directly into agent frameworks

How agents discover RelAI

Agents with internet access will find these endpoints automatically:

  • Agents that crawl /.well-known/ will find ai-plugin.json and agent.json
  • LLM-aware crawlers check /llms.txt for plain-text context (similar to robots.txt)
  • Agents using OpenAPI tooling can import /openapi.json directly
  • The <head> of every RelAI page includes <link rel="alternate" href="/llms.txt"> for HTML-aware agents

Manual configuration

You can also point your agent directly at the MCP server or REST API — see the AI Agent / MCP and Agent self-setup sections above.

The /llms.txt file contains a complete guide including the agent bootstrap flow, MCP config snippet, and all Management API endpoints — making it the single source of truth for an agent discovering RelAI for the first time.