V1 Token System & Bootstrap
Zero-touch agent onboarding: discover Opacus, sign once with a wallet, get 3 scoped tokens, and use any service — no human intervention required.
https://opacus.xyz — All V1 endpoints live under /api/v1/*. Discovery at /.well-known/opacus.jsonDiscovery
Any agent can discover Opacus automatically by fetching the standard discovery document:
GET https://opacus.xyz/.well-known/opacus.json
Returns the full service catalog, bootstrap URLs, token definitions, supported networks, and error codes. No authentication required.
GET /api/v1/discovery
Lightweight inline version of the same information.
Token Types
V1 uses 3 scoped tokens — each with a distinct prefix, scope set, and TTL:
| Token | Prefix | Scopes | TTL | Use For |
|---|---|---|---|---|
OPACUS_AGENT_TOKEN |
obr_agent_ |
nitro.execute, oracle.hint, monitor.events, routing.resolve, reputation.read | 24 hours | Compute, oracle queries, routing, monitoring |
OPACUS_DATA_TOKEN |
obr_data_ |
0g.upload, 0g.download, 0g.compute, databridge.sync | 24 hours | 0G storage, download, compute, DataBridge |
OPACUS_PAY_TOKEN |
obr_pay_ |
pay.escrow_lock, pay.escrow_release, pay.transfer, budget.read, budget.write | 1 hour | Payments, escrow, budget management |
POST /api/v1/auth/refresh.Bootstrap Flow
Full zero-touch onboarding in 3 steps:
Step 1: Request Challenge
POST /api/v1/bootstrap/challenge
Content-Type: application/json
{
"wallet_address": "0xYourWalletAddress",
"network": "base" // base | ethereum | solana | 0g
}
Response:
{
"ok": true,
"nonce": "a4c61874972bef6bd24e44d89e5a737c",
"message": "Opacus V1 Bootstrap — Ownership Proof\nWallet: ...\nNonce: ...",
"expires_at": "2026-04-12T21:33:46.978Z"
}
Step 2: Sign & Register
Sign the message with your wallet (EVM: personal_sign), then submit:
POST /api/v1/bootstrap/register
Content-Type: application/json
{
"nonce": "a4c61874972bef6bd24e44d89e5a737c",
"signature": "0x...",
"agent_name": "my-agent" // optional
}
Response:
{
"ok": true,
"did": "did:opacus:v1:0xabcd...",
"agent_id": "citadel_abc123_xyz",
"tokens": {
"OPACUS_AGENT_TOKEN": "obr_agent_...",
"OPACUS_DATA_TOKEN": "obr_data_...",
"OPACUS_PAY_TOKEN": "obr_pay_..."
},
"token_details": { ... },
"network": "base",
"free_tier": {
"enabled": true,
"budget_usd": 5.00,
"api_calls_per_day": 1000,
"storage_bytes": 104857600
}
}
Step 3: Use Tokens
# Set environment variables
export OPACUS_AGENT_TOKEN=obr_agent_...
export OPACUS_DATA_TOKEN=obr_data_...
export OPACUS_PAY_TOKEN=obr_pay_...
# Use any V1 endpoint
curl -H "Authorization: Bearer $OPACUS_AGENT_TOKEN" \
https://opacus.xyz/api/v1/oracle/query?q=ETH/USD
Authentication
All V1 service endpoints require a valid token in the Authorization header:
Authorization: Bearer obr_agent_...
Or via the X-Opacus-Token header. Each endpoint requires a specific scope — using the wrong token type returns 403 AUTH_SCOPE_DENIED.
Token Refresh
POST /api/v1/auth/refresh
Authorization: Bearer obr_agent_... // any valid (or recently expired) token
Returns 3 fresh tokens. The old tokens are revoked.
Token Revoke
POST /api/v1/auth/revoke
Authorization: Bearer obr_agent_...
Service Endpoints
Compute & Routing
| Method | Path | Token | Description |
|---|---|---|---|
| POST | /api/v1/nitro/execute | Agent | Execute an intent (swap, transfer, etc.) |
| GET | /api/v1/oracle/query?q=ETH/USD | Agent | Query on-chain oracle |
| POST | /api/v1/oracle/query | Agent | Oracle query via POST body |
| GET | /api/v1/routing/endpoints | Agent | List available service endpoints |
| GET | /api/v1/routing/health | Agent | Service health check |
| GET | /api/v1/reputation/:agentId | Agent | Get agent reputation score |
0G Storage & Compute
| Method | Path | Token | Description |
|---|---|---|---|
| POST | /api/v1/0g/upload | Data | Upload file to 0G storage |
| GET | /api/v1/0g/download/:rootHash | Data | Download by root hash |
| GET | /api/v1/0g/files | Data | List uploaded files |
| GET | /api/v1/0g/usage | Data | Storage usage stats |
| POST | /api/v1/0g/compute | Data | Run 0G inference |
Payments & Budget
| Method | Path | Token | Description |
|---|---|---|---|
| POST | /api/v1/pay/escrow/lock | Pay | Lock USDC in escrow |
| POST | /api/v1/pay/escrow/release | Pay | Release escrow |
| GET | /api/v1/pay/escrows | Pay | List escrows |
| GET | /api/v1/pay/balance | Pay | Get USDC balance |
| GET | /api/v1/budget/status | Pay | Budget status & remaining |
| POST | /api/v1/budget/lock | Pay | Lock budget for operation |
| GET | /api/v1/budget/usage | Pay | Budget usage history |
Monitoring & Agents
| Method | Path | Token | Description |
|---|---|---|---|
| GET | /api/v1/monitor/events | Agent | Recent system events |
| GET | /api/v1/monitor/rules | Agent | Active monitoring rules |
| GET | /api/v1/agents | Agent | List your agents |
| POST | /api/v1/agents | Agent | Register new agent |
| GET | /api/v1/agents/keys | Agent | List active V1 tokens |
Bridge & DataBridge
| Method | Path | Token | Description |
|---|---|---|---|
| POST | /api/v1/bridge/initiate | Pay | Initiate cross-chain bridge |
| GET | /api/v1/bridge/status?requestId=... | Pay | Check bridge status |
| GET | /api/v1/databridge/token | Data | Get DataBridge sync token |
| POST | /api/v1/databridge/token | Data | Generate new sync token |
Public (No Auth)
| Method | Path | Description |
|---|---|---|
| GET | /.well-known/opacus.json | Full discovery document |
| GET | /api/v1/discovery | Inline discovery |
| GET | /api/v1/stats | Live agent count & network stats |
| POST | /api/v1/bootstrap/challenge | Request bootstrap challenge |
| POST | /api/v1/bootstrap/register | Complete bootstrap with signature |
Standard Error Codes
All V1 errors follow a standard format:
{
"error": {
"code": "AUTH_SCOPE_DENIED",
"message": "Token does not have the required scope",
"retry_after_seconds": null,
"docs_url": "https://opacus.xyz/docs"
}
}
| Code | HTTP | Description |
|---|---|---|
AUTH_INVALID_TOKEN | 401 | Token missing, expired, or not recognised |
AUTH_SCOPE_DENIED | 403 | Token does not have required scope for this endpoint |
AUTH_TOKEN_EXPIRED | 401 | Token TTL exceeded — refresh required |
AUTH_TOKEN_REVOKED | 401 | Token has been explicitly revoked |
BOOTSTRAP_CHALLENGE_EXPIRED | 400 | Challenge nonce expired or not found |
BOOTSTRAP_SIGNATURE_INVALID | 401 | Wallet signature verification failed |
BOOTSTRAP_REPLAY_DETECTED | 400 | Nonce already used (anti-replay) |
RATE_LIMIT_EXCEEDED | 429 | Too many requests — see retry_after_seconds |
BUDGET_EXHAUSTED | 402 | Free tier or budget limit reached |
SERVICE_UNAVAILABLE | 503 | Backend service temporarily unavailable |
Free Tier
Every bootstrapped agent gets a free tier:
| Resource | Limit |
|---|---|
| Budget | $5.00 USD |
| API calls | 1,000 / day |
| 0G Storage | 100 MB |
Once limits are hit, requests return BUDGET_EXHAUSTED (402). Top up via the Agentboard billing section.
Full Example (Node.js)
import { ethers } from 'ethers';
// 1. Discovery
const disc = await fetch('https://opacus.xyz/.well-known/opacus.json')
.then(r => r.json());
// 2. Bootstrap
const wallet = ethers.Wallet.createRandom(); // or your existing wallet
const ch = await fetch(disc.bootstrap.challenge, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ wallet_address: wallet.address, network: 'base' })
}).then(r => r.json());
const sig = await wallet.signMessage(ch.message);
const reg = await fetch(disc.bootstrap.register, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ nonce: ch.nonce, signature: sig })
}).then(r => r.json());
// 3. Use services
const oracle = await fetch('https://opacus.xyz/api/v1/oracle/query?q=ETH/USD', {
headers: { 'Authorization': 'Bearer ' + reg.tokens.OPACUS_AGENT_TOKEN }
}).then(r => r.json());
console.log('ETH/USD:', oracle);