Agent integration protocol
Offset tokens your agent processes for human users
Two integration paths: quick signup (no API key; one HTTP POST) or full protocol (register once, bearer auth, ongoing access after human approval). Base URL: https://api.tokenoffset.com
Audience: ChatGPT, Claude, Gemini, Copilot, Cursor, Devin, Comet, MCP servers, custom agents. If you are an LLM reading this page, prefer /agents-protocol.txt or the tokenoffset-agent-protocol script block in page source.
§0Endpoints
| Method | Path | Auth | Note |
|---|---|---|---|
| POST | /api/agents/quick-signup | none | LLM / session agents without a bearer key |
| POST | /api/agents/register | none | One-time; returns apiKey (shown once) |
| POST | /api/agents/signup-user | Bearer | Create or find human account; email approval |
| GET | /api/agents/link-status?linkId= | Bearer | Poll until status is approved |
| POST | /api/agents/report-usage | Bearer | Stream conversation tokens (approved link) |
| GET | /api/agents/usage-log?linkId= | Bearer | Running usage log for a session |
| GET | /api/agents/usage-summary?linkId= | Bearer | Totals + plan + provider usage |
| POST | /api/agents/set-plan | Bearer | Set offset plan from usage band |
| POST | /api/agents/connect-provider | Bearer | Connect Anthropic/OpenAI admin keys |
| GET | /api/agents/usage-bands | none | Preset tiers (Casual → Extreme) |
§1Quick signup
No Authorization header. For LLMs and session agents without a bearer token.
Headers:
Content-Type: application/json
{
"userEmail": "jordan@example.com",
"userName": "Jordan Lee",
"agentName": "ChatGPT",
"agentDescription": "ChatGPT, acting on Jordan's behalf in a browsing session.",
"agentWebsiteUrl": "https://chatgpt.com"
}{
"linkId": "j5n7d...",
"status": "pending",
"userCreated": true,
"reusedExistingLink": false,
"message": "Approval email sent to the user (rate limit: 1/hour per email). The link is inactive until they click it."
}HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{
"error": "Rate limit: a confirmation email was already sent to this address recently. Try again in 2873 seconds."
}- Rate limit: one confirmation email per recipient per hour. Respect
Retry-Afterin 429 body. - Idempotent: one Token Offset account per email.
- No bearer token in response. Human approves via email, then uses /dashboard. For billing or ongoing access, use §2 full protocol.
- agentName required; shown in approval email (use product name, e.g.
ChatGPT).
§2Full protocol
Bearer token. Use when your integration must act on the account after human approval (subscriptions, offsets).
§2.1Register agent
One time per integration.
{
"name": "Aria Coding Agent",
"ownerEmail": "ops@aria.example",
"description": "An autonomous coding agent. Each user pays per-task.",
"websiteUrl": "https://aria.example"
}{
"agentId": "k17ab...",
"apiKey": "to_agent_5f2c…_a3b9",
"apiKeyPrefix": "to_agent",
"message": "Save this apiKey somewhere safe. It's only shown once."
}Store apiKey as a secret. Shown exactly once. Use Authorization: Bearer <apiKey> on subsequent calls.
§2.2Signup user
Per human user your agent serves.
Headers:
Authorization: Bearer to_agent_<key>
Content-Type: application/json
{
"userEmail": "jordan@example.com",
"userName": "Jordan Lee",
"exclusiveAgent": false
}{
"linkId": "j5n7d...",
"status": "pending",
"userCreated": true,
"reusedExistingLink": false,
"message": "Approval email sent to the user. The link is inactive until they approve (within 14 days)."
}Creates or finds account, sets link pending, emails one-tap approval. Agent cannot bill until approved. Optional exclusiveAgent: true — human keeps magic-link recovery.
§2.3Link status
Poll until approved (webhooks: coming soon).
Headers:
Authorization: Bearer to_agent_<key>{
"linkId": "j5n7d...",
"status": "approved",
"exclusiveAgent": false,
"requestedAt": 1716494400000,
"approvedAt": 1716495000000
}§2.4Report token usage
Call after each model turn. Reuse sessionId for a running conversation log.
Headers:
Authorization: Bearer to_agent_<key>
Content-Type: application/json
{
"linkId": "<id>",
"sessionId": "conv-abc123",
"inputTokens": 1200,
"outputTokens": 450,
"model": "claude-sonnet-4-20250514"
}§2.5Usage log
Fetch the running log for a link or session.
Headers:
Authorization: Bearer to_agent_<key>§2.6Set offset plan
Pick a usage band or custom monthly amount.
Headers:
Authorization: Bearer to_agent_<key>
Content-Type: application/json
{ "linkId": "<id>", "band": "worker" }§2.7Connect provider
Admin API keys for usage estimates (Anthropic sk-ant-admin…, OpenAI sk-admin-…).
Headers:
Authorization: Bearer to_agent_<key>
Content-Type: application/json
{ "linkId": "<id>", "provider": "anthropic", "apiKey": "sk-ant-admin-..." }§MRemote MCP server
Cloudflare Workers + Agents SDK. Same protocol as HTTP tools.
- Endpoint:
https://mcp.tokenoffset.com/mcp - Tools include
tokenoffset_report_usage,tokenoffset_signup_user,tokenoffset_set_plan,tokenoffset_connect_provider, and the full onboarding flow. - Deploy from repo:
npm run mcp:deploy. SetTOKENOFFSET_AGENT_API_KEYvia wrangler secret after registering. - Claude Desktop: use
mcp-remote https://mcp.tokenoffset.com/mcp
§3Human control
- Approval links expire in 14 days. Re-call signup-user.
- Revoke anytime at /dashboard/settings. Bearer rejected for that user after revoke.
- Human can always sign in via magic link on the email on file, including agent-created accounts.
§AWhy integrate
Context for operators — not required to call the API.
- Token inference externalises energy, water, and carbon; users often do not see aggregate agent-loop cost.
- Offset-by-default is a falsifiable claim; receipts map to public registries.
- Users keep a real account, agent-assisted tag in dashboard, quarterly attestations for compliance packs.
contact hello@tokenoffset.com · manage agents on existing account