Control your entire RelAI integration programmatically.
Manage keys, budgets, usage, and payments — all from one API.
Everything you can do in the dashboard — you can automate here.
This is the control plane for your entire RelAI integration.
Why Management API?
Use the Management API when:
What you can control
Quick start
Create a service key and start managing your integration programmatically:
curl -X POST https://api.relai.fi/v1/keys -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" -d '{"label": "production"}'{ "key": "sk_live_a1b2c3d4...", "label": "production", "active": true }Use that key to control your account programmatically:
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",
"network": "base",
"merchantWallet": "0xYourWallet",
"endpoints": [
{ "path": "/v1/predict", "method": "post", "usdPrice": 0.05 }
]
}'Automate everything
AI agents can use the Management API directly via MCP — Claude, Cursor, and Windsurf can call all management tools without a browser or dashboard. See the AI Agent / MCP section below.
Built for production
Authentication
The Management API uses two schemes depending on the operation:
Used on /v1/keys endpoints to create and revoke service keys. This is the same token you get from logging in at relai.fi.
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:
curl -X POST https://api.relai.fi/v1/keys \
-H "Authorization: Bearer <your-jwt>" \
-H "Content-Type: application/json" \
-d '{"label": "production"}'{
"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.
Request challenge
POST your public key → receive a message to sign
Sign message
Sign with your private key (nacl/ethers/web3)
Get service key
POST signature → receive sk_live_... stored forever
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_...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
curl https://api.relai.fi/v1/keys \
-H "Authorization: Bearer <your-jwt>"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.
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | yes | Display name shown in the marketplace |
| baseUrl | string | yes | Target server base URL (e.g. https://my-api.example.com) |
| description | string | no | Short description |
| network | string | no | Payment network. Default: solana |
| facilitator | string | no | Facilitator. Default: relai |
| x402Version | number | no | 1 or 2. Default: 2 |
| merchantWallet | string | no | Wallet address receiving payments |
| subdomain | string | no | Custom subdomain under relai.fi — must be unique |
| websiteUrl | string | no | Link to your API docs or homepage |
| logoUrl | string | no | URL of the API logo |
| ownerEmail | string | no | Contact email for the API owner |
| endpoints | array | no | Initial pricing (see below) |
endpoints[] item fields:
| Field | Type | Required | Description |
|---|---|---|---|
| path | string | yes | Endpoint path, e.g. /v1/predict |
| method | string | no | HTTP method: get | post | put | patch | delete. Default: get |
| usdPrice | number | no | Price per call in USD. Default: 0.01 |
| description | string | no | Endpoint description |
| enabled | boolean | no | Whether the endpoint is active. Default: true |
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 }
]
}'{
"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.
curl https://api.relai.fi/v1/apis \
-H "X-Service-Key: sk_live_..."{
"apis": [
{ "apiId": "1751234567890", "name": "My Prediction API", ... }
]
}GET/v1/apis/:apiId — Get an API
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.
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
curl -X DELETE https://api.relai.fi/v1/apis/1751234567890 \
-H "X-Service-Key: sk_live_..."{ "success": true, "apiId": "1751234567890" }Pricing management
Pricing is configured per endpoint (path + method). All monetary values are in USD.
GET/v1/apis/:apiId/pricing
curl https://api.relai.fi/v1/apis/1751234567890/pricing \
-H "X-Service-Key: sk_live_..."{
"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.
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 }
]
}'{ "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.
curl https://api.relai.fi/v1/apis/1751234567890/stats \
-H "X-Service-Key: sk_live_..."{
"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 param | Type | Default | Description |
|---|---|---|---|
| limit | number | 50 | Number of records to return (max 500) |
| cursor | string | — | Transaction ID — return records after this entry |
| from | string | — | ISO date — filter from this timestamp |
| to | string | — | ISO date — filter up to this timestamp |
curl "https://api.relai.fi/v1/apis/1751234567890/payments?limit=20&from=2025-01-01" \
-H "X-Service-Key: sk_live_..."{
"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 param | Type | Default | Description |
|---|---|---|---|
| limit | number | 50 | Records to return (max 500) |
| cursor | string | — | Transaction ID — return records after this entry |
| from | string | — | ISO date — filter from this timestamp |
| to | string | — | ISO date — filter up to this timestamp |
curl "https://api.relai.fi/v1/apis/1751234567890/logs?limit=20&from=2025-01-01" \
-H "X-Service-Key: sk_live_..."{
"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:
{
"mcpServers": {
"relai-management": {
"url": "https://api.relai.fi/mcp/management",
"headers": {
"X-Service-Key": "sk_live_..."
}
}
}
}Windsurf
Add to ~/.codeium/windsurf/mcp_config.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):
{
"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:
| Tool | Description |
|---|---|
| create_api | Create a new x402-monetised API (status: pending) |
| list_apis | List all APIs owned by this service key |
| get_api | Get details of a specific API |
| update_api | Update API metadata (name, baseUrl, description…) |
| delete_api | Permanently delete an API |
| set_pricing | Replace endpoint pricing configuration |
| get_pricing | Get current endpoint pricing |
| get_stats | Get aggregated revenue and request count |
| get_logs | Get 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.
# 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." }| Status | Meaning |
|---|---|
| 400 | Validation error — missing or invalid fields |
| 401 | Missing or invalid credentials |
| 403 | Authenticated but not authorised for this resource |
| 404 | Resource not found |
| 409 | Conflict — e.g. subdomain already taken |
| 500 | Internal 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 value | Chain | Token |
|---|---|---|
| solana | Solana Mainnet | USDC |
| base | Base Mainnet | USDC |
| base-sepolia | Base Sepolia | USDC |
| skale-base | SKALE Base | USDC, USDT, skUSD, ETH, BTC, … |
| polygon | Polygon | USDC |
| avalanche | Avalanche C-Chain | USDC |
| ethereum | Ethereum Mainnet | USDC |
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.
| URL | Format | Purpose |
|---|---|---|
| /.well-known/ai-plugin.json | JSON | OpenAI plugin manifest — discovered by ChatGPT, LangChain, AutoGPT and compatible agents |
| /.well-known/agent.json | JSON | Agent Protocol manifest — MCP endpoint, capabilities, auth info |
| /llms.txt | Plain text | Full LLM context — how to use the API, agent bootstrap flow, MCP config |
| /openapi.json | OpenAPI 3.1 | Full 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 findai-plugin.jsonandagent.json - LLM-aware crawlers check
/llms.txtfor plain-text context (similar torobots.txt) - Agents using OpenAPI tooling can import
/openapi.jsondirectly - 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.
Bridge
The Bridge API lets agents and backends move USDC between supported networks programmatically. Every bridge transfer is an x402 payment on the source chain followed by a USDC payout on the destination chain. All endpoints require an X-Service-Key header.
Mainnet bridge is capped at $1 USDC during beta. Testnet (Solana Devnet ↔ SKALE Base Sepolia) allows up to $10 USDC.
List directions
Returns all enabled bridge directions with token addresses and network metadata.
curl https://api.relai.fi/v1/bridge/networks -H "X-Service-Key: sk_live_..."
// Response
{
"directions": [
{
"id": "solana-to-skale-base",
"from": { "id": "solana", "label": "Solana", "type": "solana", "token": "EPjFWdd5...", "decimals": 6, "caip2": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
"to": { "id": "skale-base", "label": "SKALE Base", "type": "evm", "token": "0x85889c8c...", "decimals": 6, "caip2": "eip155:1187947933" }
}
]
}Quote
Returns the output amount after the 0.1% bridge fee. Use this before executing a bridge to show the user the exact amount they will receive.
curl "https://api.relai.fi/v1/bridge/quote?amount=1&from=solana&to=skale-base" -H "X-Service-Key: sk_live_..."
// Response
{
"from": "solana",
"fromLabel": "Solana",
"to": "skale-base",
"toLabel": "SKALE Base",
"inputAmount": 1000000,
"inputUsd": 1,
"outputAmount": 999000,
"outputUsd": 0.999,
"fee": 1000,
"feeBps": 10
}Balances
Returns current USDC liquidity on all enabled networks. Bridge execution will be rejected with 503 if the destination has insufficient funds.
curl https://api.relai.fi/v1/bridge/balances -H "X-Service-Key: sk_live_..."
// Response
{
"solana": { "atomic": 5000000, "usd": 5, "label": "Solana" },
"skale-base": { "atomic": 8000000, "usd": 8, "label": "SKALE Base" },
"solana-devnet": { "atomic": 50000000, "usd": 50, "label": "Solana Devnet" },
"skale-base-sepolia": { "atomic": 30000000, "usd": 30, "label": "SKALE Base Sepolia" }
}Execute bridge
Initiates a bridge transfer. The endpoint uses the x402 protocol — on the first call it returns a 402 Payment Required response. Your x402-compatible wallet or SDK signs the transaction and retries with an X-PAYMENT header. The bridge then pays out on the destination chain and returns both transaction hashes.
| Field | Type | Description |
|---|---|---|
| amount | string | number | Amount in USDC (e.g. "0.5" or 0.5). Max $1 mainnet, $10 testnet. |
| destinationWallet | string | Recipient address on the destination network (EVM 0x… or Solana base58). |
// Using @relai-fi/x402 SDK (handles 402 automatically)
import { createX402Client } from '@relai-fi/x402';
const client = createX402Client({ solanaWallet, solanaRpcUrl });
const result = await client.fetch('https://api.relai.fi/v1/bridge/solana-to-skale-base', {
method: 'POST',
headers: { 'X-Service-Key': 'sk_live_...', 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: '0.5', destinationWallet: '0xYourEvmAddress' }),
});
// Response
{
"success": true,
"direction": "solana-to-skale-base",
"from": "solana",
"to": "skale-base",
"destinationWallet": "0xYourEvmAddress",
"amountOut": 499500,
"amountOutUsd": 0.4995,
"txHash": "0xabc...",
"explorerUrl": "https://skale-base-explorer.skalenodes.com/tx/0xabc...",
"paymentTxHash": "5Kq7...",
"paymentExplorerUrl": "https://solscan.io/tx/5Kq7..."
}Supported directions
| direction | From | To | Environment |
|---|---|---|---|
| solana-to-skale-base | Solana | SKALE Base | Mainnet |
| skale-base-to-solana | SKALE Base | Solana | Mainnet |
| solana-devnet-to-skale-base-sepolia | Solana Devnet | SKALE Base Sepolia | Testnet |
| skale-base-sepolia-to-solana-devnet | SKALE Base Sepolia | Solana Devnet | Testnet |