Developers
API
Authentication, topups, credit, inference, and admin endpoints.
An inference request
Your server
OpenAI-compatible SDK
/api/v1
Scope + budget checks
Developers
Authentication, topups, credit, inference, and admin endpoints.
An inference request
Your server
OpenAI-compatible SDK
/api/v1
Scope + budget checks
Completion
JSON or an SSE stream
AgentPass provides an OpenAI-compatible inference API at /api/v1. It uses the same wallet credit and admin-managed model prices as Chat. The wallet management API uses a signed-in session.
| Surface | Authentication | Use |
|---|---|---|
/api/v1/models, /api/v1/chat/completions | Scoped Bearer API key | Server integrations |
/api/chat, /api/chat/models, credit and key routes | Session cookie plus matching wallet header | Signed-in workspace |
| Admin routes | Admin wallet session; management mutations validate origin | Model and key administration |
For the interface walkthrough, see API keys. The current inference API supports Models list and Chat Completions, including SSE. It does not implement the OpenAI Responses API.
AGENTPASS_API_KEY in your server environment and set AGENTPASS_BASE_URL to your AgentPass origin followed by /api/v1.AGENTPASS_MODEL. Check its prices and max_output_tokens before sending a completion.Install the official openai package in your integrating application. The examples below run on a server. Set all three environment variables explicitly so an omitted base URL cannot route requests to a different service. The examples request 256 output tokens; lower that value if the chosen model's configured maximum is smaller.
These examples disable automatic SDK retries. Repeating an accepted inference request can incur a second charge; the endpoint does not provide an idempotency-key contract. If the catalog is empty, check enabled models and the key's model restrictions.
Send Authorization: Bearer $AGENTPASS_API_KEY on every inference request. An app session cookie does not authorize these endpoints. API keys cannot create other keys, change models, access admin routes, or perform wallet transactions.
Keys start with sk-ap-, contain 256 random bits, and are stored as SHA-256 hashes. The database retains a masked prefix for display. A key expires after 90 days by default; choose 1 to 365 days when creating it. Revocation blocks new reservations. Already-reserved requests can finish and settle their charges.
GET /api/v1/models requires models:read. It returns an OpenAI list object with data containing enabled models permitted by the key. Each entry includes id, object: "model", created, and owned_by. AgentPass adds name, max_output_tokens, and pricing with input_usd_per_million and output_usd_per_million. created is 0 because provider release dates are not tracked.
POST /api/v1/chat/completions requires chat:write, a .ai Agent ID, and enough wallet credit. Your messages are forwarded without an added AgentPass system prompt. Responses use chat.completion, choices, message, finish_reason, and standard token usage. Non-streaming responses include X-AgentPass-Cost-Usd with the billed amount.
Supported inputs:
system, developer, user, assistant, and tool roles. Text content parts are accepted.max_tokens or max_completion_tokens, up to the model limit. Omit both to use that limit. Do not send both.temperature, top_p, presence_penalty, frequency_penalty, stop, and seed.tools, tool_choice, parallel_tool_calls, assistant tool_calls, and tool_call_id for tool results.response_format using text, json_object, or a named .Model support for tools, reasoning, structured output, and sampling controls varies. A provider rejection returns a sanitized error. n must be 1; store must be false if provided. user is accepted but not forwarded or stored. Requests accept at most 128 messages and a 256 KiB JSON body. Unknown parameters are rejected.
The workspace's thinking setting belongs to /api/chat. It is not an accepted top-level parameter for /api/v1/chat/completions; neither are reasoning or reasoning_effort in this release.
This release implements Models list and Chat Completions. Responses, embeddings, image/audio inputs and generation, files, batches, stored completions, and model retrieval by ID are not implemented. Use the SDK's chat.completions.create method. Integrations run on your server; cross-origin browser calls are not enabled.
With stream: true, the response is text/event-stream. Events contain OpenAI chat.completion.chunk objects; successful streams end with data: [DONE]. When requested, the final usage chunk has empty choices and the full token counts. AgentPass requests provider usage for billing even when the client does not ask to receive it.
Credit is reserved before contacting the provider. The wallet limit of 30 requests per minute is shared by Chat and all keys. A key may have a lower rate limit and a lifetime USD budget. Budgets include settled spending and pending reservations. They do not add credit or reset when you top up. The full output reservation must fit within both the budget and available credit.
Provider failures before output release the reservation. Interrupted streams and client disconnects settle the output already observed, then release the remainder. If final provider usage is missing, usage is estimated from input and output text. Charges remain capped at the reservation. Abandoned reservations release after five minutes. The upstream deadline is 90 seconds.
Errors before streaming use an OpenAI-style { "error": { "message", "type", "param", "code" } } object and an HTTP status. After streaming starts, failures are SSE error events without a success [DONE] marker. Every response includes X-Request-Id. A 429 response includes Retry-After: 60.
| Status | Inference meaning |
|---|---|
| 400 | Invalid parameters, unavailable model, or unsupported model options |
| 401 | Missing, invalid, expired, or revoked key |
| 402 | Insufficient wallet credit or key lifetime budget |
| 403 | Missing scope, model permission, or Agent ID |
| 413 | JSON body exceeds 256 KiB |
| 415 | Content type must be application/json |
| 429 | Wallet or key rate limit |
| 502 | Provider failure or invalid upstream response |
| 503 | Database, Agent ID lookup, or gateway unavailable |
The API keys page shows masked keys, permissions, model restrictions, expiry, last inference time, spending, reservations, and the latest 50 API requests. Search matches names and prefixes; Active and Inactive filters narrow the cards. Full keys are shown once and are not saved in browser storage. Dismissing the creation dialog, navigating away, switching wallets, or signing out clears the displayed secret.
These endpoints require the wallet's session cookie and an X-AgentPass-Wallet header equal to the signed-in wallet. Mutations reject foreign origins; creation requires application/json. Inference Bearer credentials do not authorize management.
| Method | Path | Result |
|---|---|---|
| GET | /api/keys | Wallet keys and recent API usage |
| POST | /api/keys | Create a key; returns id, prefix, and one-time secret |
| DELETE | /api/keys/{id} | Permanently revoke a wallet-owned key |
| GET | /api/admin/keys | Up to 100 keys, active first; optional ?wallet=0x... filter; admin session required |
| DELETE | /api/admin/keys/{id} | Revoke a key as admin; records the actor |
Create body:
Use null for allowedModels to allow all enabled models, including future catalog additions. Use null for budgetUsd to use the wallet balance as the spending limit. Budgets accept up to six decimals and a maximum of $10,000. A wallet can hold 20 active keys and create at most 50 keys per day. To change restrictions or rotate credentials, create a replacement and revoke the old key. Key creation and revocations are recorded in app.api_key_events; raw keys and prompts are not recorded.
Auth uses EIP-712 and an httpOnly JWT cookie.
Response:
The nonce expires after 5 minutes and can be used once.
Sign the typed data with the wallet, then:
The response sets the agentpass_session cookie. The session lasts 7 days.
Credit, usage, topup history, and Chat requests require the signed-in session and an X-AgentPass-Wallet header matching that wallet. Login and balance reads never grant NFT credit.
GET /api/topups returns { "topups": [...] } with the latest 50 credited payments for the wallet. Entries contain chainId, contractAddress, txHash, logIndex, paymentToken, amountPaid, amountUsd, paidAt, and creditedAt. Token amounts are integer strings and USD values are decimal strings. Timestamps use ISO 8601. This endpoint is read-only; credit is created only by the receipt-verifying indexer worker.
The Chat guide describes the workspace. The endpoint below returns one completed JSON response, not an SSE stream. It adds an AgentPass system prompt. The Chat and capability routes require a session cookie and X-AgentPass-Wallet matching the signed-in wallet.
GET /api/chat/models returns a map of enabled model IDs to their supported effort levels:
These IDs illustrate the shape only. Use the actual catalog. Auto is always the default and is not included in efforts. The provider capability lookup is cached for five minutes; the authenticated route response is no-store. A failed capability lookup returns 503. Non-Auto requests are checked against the provider catalog before reservation.
Response:
Rules:
thinking accepts auto, low, medium, or high; omitted means auto. Explicit effort must be supported by that model.If the wallet is not in the snapshot, allocation is null.
The active dashboard uses credit, usage, and topup history endpoints. The endpoints below remain for historical claims and operator tools.
Returns pass supply, holders, reward totals, recent mints, reward epochs, airdrop claims, and tax distributions.
Returns passes with all wallet NFTs, pass as the latest NFT for compatibility, reward claims, airdrop claims, and the latest aggregate weight change. Holder counts use distinct owners.
The admin page uses this to gate the UI. Contract actions require their on-chain roles. Model management requires a session wallet in ADMIN_WALLETS.
GET /api/admin/models returns { "models": [...] }, including disabled entries.
PUT /api/admin/models creates or updates a model:
DELETE /api/admin/models accepts { "id": "openai/gpt-4o-mini" }. It removes availability, preserving historical usage and request pricing. Unknown IDs return 404. All three methods require an admin session. Mutations validate request origin and record the actor in app.model_changes.
| Status | Meaning |
|---|---|
| 400 | Invalid input, model, or expired nonce |
| 401 | No session or invalid signature |
| 402 | Insufficient credit |
| 403 | Missing Agent ID, wallet mismatch, or admin access |
| 429 | Rate limit |
| 502 | OpenRouter failure |
| 503 | Auth, database, or AI gateway not configured |
json_schemastream and stream_options.include_usage.import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AGENTPASS_API_KEY"],
base_url=os.environ["AGENTPASS_BASE_URL"],
max_retries=0,
)
models = client.models.list()
model_id = os.environ["AGENTPASS_MODEL"]
if not any(model.id == model_id for model in models.data):
raise RuntimeError("Choose an enabled model returned by the catalog.")
completion = client.chat.completions.create(
model=model_id,
messages=[{"role": "user", "content": "Explain BNB Chain in one sentence."}],
max_completion_tokens=256,
)
print(completion.choices[0].message.content)
import OpenAI from "openai";
const apiKey = process.env.AGENTPASS_API_KEY;
const baseURL = process.env.AGENTPASS_BASE_URL;
const modelId = process.env.AGENTPASS_MODEL;
if (!apiKey || !baseURL || !modelId) {
throw new Error("Set AGENTPASS_API_KEY, AGENTPASS_BASE_URL, and AGENTPASS_MODEL.");
}
const client = new OpenAI({
apiKey,
baseURL,
maxRetries: 0,
});
const models = await client.models.list();
if (!models.data.some((model) => model.id === modelId)) {
throw new Error("Choose an enabled model returned by the catalog.");
}
const stream = await client.chat.completions.create({
model: modelId,
messages: [{ role: "user", content: "Write a short greeting." }],
max_tokens: 256,
stream: true,
stream_options: { include_usage: true },
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta.content ?? "");
if (chunk.usage) console.error(chunk.usage);
}
curl "$AGENTPASS_BASE_URL/models" \
-H "Authorization: Bearer $AGENTPASS_API_KEY"
curl "$AGENTPASS_BASE_URL/chat/completions" \
-H "Authorization: Bearer $AGENTPASS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello"}],
"max_completion_tokens": 256
}'
{
"name": "My agent",
"scopes": ["models:read", "chat:write"],
"allowedModels": ["openai/gpt-4o-mini"],
"budgetUsd": "5.00",
"requestsPerMinute": 10,
"expiresInDays": 90
}
GET /api/auth/nonce?wallet=0x...
{
"nonce": "123...",
"expiry": 1793551532,
"domain": {
"name": "AgentPass",
"version": "1",
"chainId": 97
},
"types": {
"Login": [
{ "name": "wallet", "type": "address" },
{ "name": "nonce", "type": "uint256" },
{ "name": "expiry", "type": "uint256" }
]
},
"primaryType": "Login"
}
POST /api/auth/verify
Content-Type: application/json
{
"wallet": "0x...",
"nonce": "123...",
"expiry": 1793551532,
"signature": "0x..."
}
GET /api/auth/session
{
"authenticated": true,
"wallet": "0x..."
}
POST /api/auth/logout
GET /api/credits
{
"agentEligible": true,
"handle": "alice",
"topUpCount": 1,
"toppedUpUsd": "10",
"grantedUsd": "10.000000",
"usedUsd": "0.000015",
"balanceUsd": "9.999985",
"balanceMicro": "9999985",
"expiresAt": null,
"model": "openai/gpt-4o-mini",
"models": [{ "id": "openai/gpt-4o-mini", "label": "GPT-4o mini", "inputUsdPerMillion": "0.150000", "outputUsdPerMillion": "0.600000", "maxOutput": 4000, "enabled": true }],
"requestsPerMinute": 30
}
GET /api/credits/usage
{
"usage": [
{
"model": "openai/gpt-4o-mini",
"inputTokens": 12,
"outputTokens": 24,
"costUsd": "0.000015",
"createdAt": "2026-11-01T16:42:46.026Z"
}
]
}
{
"example/reasoning-model": { "efforts": ["low", "medium", "high"] },
"example/text-model": { "efforts": [] }
}
POST /api/chat
Content-Type: application/json
X-AgentPass-Wallet: 0x...
{
"model": "openai/gpt-4o-mini",
"thinking": "auto",
"messages": [
{ "role": "user", "content": "What is AgentPass?" }
]
}
{
"id": "41680574-4a1d-48a6-84b8-c5174743110c",
"content": "AgentPass provides on-chain AI credit topups.",
"model": "openai/gpt-4o-mini",
"modelLabel": "GPT-4o mini",
"usage": {
"inputTokens": 12,
"outputTokens": 24,
"costUsd": "0.000015"
},
"balanceUsd": "1.499985"
}
GET /api/airdrop?wallet=0x...
{
"configured": true,
"wallet": "0x...",
"allocation": {
"wallet": "0x...",
"amount": "28571428571428571428571428",
"proof": ["0x..."],
"root": "0x..."
}
}
GET /api/stats
GET /api/me?wallet=0x...
GET /api/admin/session
{
"authorized": true,
"wallet": "0x..."
}
{
"id": "openai/gpt-4o-mini",
"label": "GPT-4o mini",
"inputUsdPerMillion": "0.15",
"outputUsdPerMillion": "0.60",
"maxOutput": 4000,
"enabled": true
}