# API Reference Base URL: `https://api.toolrouter.com` All requests and responses use JSON. Authenticated endpoints require a `Bearer` token in the `Authorization` header. ## How does authentication work? All authenticated endpoints require a Bearer token: `Authorization: Bearer YOUR_API_KEY`. Keys are created via the dashboard or CLI. The same key works for REST, MCP, and CLI. ``` Authorization: Bearer YOUR_API_KEY ``` API keys are created via the dashboard or CLI (`toolrouter keys create`). The same key works for REST, MCP, and CLI. ## How do I discover tools? ### GET /v1/tools List all available tools. ```bash curl https://api.toolrouter.com/v1/tools ``` ```json { "tools": [ { "name": "seo", "displayName": "SEO Analyzer", "description": "On-page SEO analysis...", "version": "1.0.0", "categories": ["marketing"], "skills": [{ "name": "analyze_page", "displayName": "Analyze Page", ... }] } ] } ``` ### GET /v1/tools/search?q={query} Search tools by keyword. ```bash curl "https://api.toolrouter.com/v1/tools/search?q=screenshot" ``` ### GET /v1/tools/:tool Get detailed information about a specific tool including all skills, input/output schemas, examples, and pricing. ```bash curl https://api.toolrouter.com/v1/tools/seo ``` ```json { "name": "seo", "displayName": "SEO Analyzer", "description": "On-page SEO analysis, meta tag auditing, and content optimization", "version": "1.0.0", "categories": ["marketing"], "skills": [ { "name": "analyze_page", "displayName": "Analyze Page", "description": "Full SEO audit of a URL", "input": { "type": "object", "properties": { "url": { "type": "string" } }, "required": ["url"] }, "examples": [{ "description": "Analyze a page", "input": { "url": "https://example.com" } }], "returns": "SEO audit with scores, issues, and recommendations" } ] } ``` ## How do I get an API key? ### POST /v1/auth/provision Create a free API key instantly. No signup needed. Rate-limited per IP. ```bash curl -X POST https://api.toolrouter.com/v1/auth/provision ``` ```json { "api_key": "tr_live_fb8c6a1a78551d0f...", "key_prefix": "tr_live_fb8c...7a83", "claim_url": "https://toolrouter.com/claim?token=53a3d78f...", "account_id": "prov_15b7271a...", "message": "Your API key is ready. Free tools work immediately. To unlock premium tools and billing, have your user visit the claim URL." } ``` The returned `api_key` works immediately for free tools. To link the key to a full account and add credits, the user should visit `claim_url`. ## How do I execute tools? ### POST /v1/tools/call Execute a tool skill. ```bash curl -X POST https://api.toolrouter.com/v1/tools/call \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tool": "seo", "skill": "analyze_page", "input": { "url": "https://example.com" } }' ``` **Response:** ```json { "id": "call_abc123", "status": "success", "output": { "title": "Example Domain", "score": 72, ... }, "usage": { "cost": 0.0105, "currency": "USD", "credits_remaining": 9.99, "raw_cost": 0.01, "markup": 1.05 }, "meta": { "tool": "seo", "skill": "analyze_page", "latency_ms": 1234 } } ``` **BYOK headers** — pass your own provider keys to get reduced 5% billing: ```bash curl -X POST https://api.toolrouter.com/v1/tools/call \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "X-Provider-Key-Serper: sp_xxx" \ -d '{ "tool": "seo", "skill": "analyze_page", "input": { "url": "https://example.com" } }' ``` ### POST /v1/tools/call (dry run) Validate a call without executing. No credits consumed. ```bash curl -X POST https://api.toolrouter.com/v1/tools/call \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "tool": "seo", "skill": "analyze_page", "input": { "url": "https://example.com" }, "dry_run": true }' ``` **Response:** ```json { "valid": true, "input_valid": true, "input_errors": [], "credentials_ok": true, "missing_credentials": [], "billing": { "balance_usd": 9.99, "sufficient": true }, "rate_limit": { "remaining": 58, "limit": 60 } } ``` ### POST /v1/tools/call (streaming) Stream results via Server-Sent Events. ```bash curl -N -X POST https://api.toolrouter.com/v1/tools/call \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: text/event-stream" \ -d '{ "tool": "seo", "skill": "check_meta", "input": { "url": "https://example.com" } }' ``` Events: `started` → `progress` (handler logs) → `rate_limit` → `result` (or `error`). ### POST /v1/tools/batch Run up to 10 tool calls concurrently. ```bash curl -X POST https://api.toolrouter.com/v1/tools/batch \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "calls": [ { "tool": "dns-domain", "skill": "lookup_dns", "input": { "domain": "a.com" } }, { "tool": "dns-domain", "skill": "check_ssl", "input": { "domain": "b.com" } } ] }' ``` **Response:** `{ "results": [...] }` — same shape as individual calls, in order. ## How do I manage billing? ### GET /v1/billing/balance Get current credit balance. ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.toolrouter.com/v1/billing/balance ``` ```json { "available_usd": 9.99 } ``` ### POST /v1/billing/checkout Create a Stripe checkout session to purchase credits. ```bash curl -X POST https://api.toolrouter.com/v1/billing/checkout \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "amount_usd": 10 }' ``` ```json { "url": "https://checkout.stripe.com/c/pay/...", "credit_usd": 10.00, "fee_usd": 0.80, "total_usd": 10.80 } ``` ### POST /v1/billing/portal Get a Stripe billing portal link for managing payment methods and viewing invoices. ```bash curl -X POST https://api.toolrouter.com/v1/billing/portal \ -H "Authorization: Bearer YOUR_API_KEY" ``` ```json { "url": "https://billing.stripe.com/p/session/..." } ``` ### GET /v1/billing/preferences Get auto-reload and budget limit settings. ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.toolrouter.com/v1/billing/preferences ``` ```json { "autoReloadEnabled": true, "autoReloadThreshold": 5, "autoReloadAmount": 20, "budgetLimit": 100 } ``` ### PUT /v1/billing/preferences Update auto-reload and budget limit settings. Only include fields you want to change. ```bash curl -X PUT https://api.toolrouter.com/v1/billing/preferences \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "autoReloadEnabled": true, "autoReloadThreshold": 5, "autoReloadAmount": 20, "budgetLimit": 100 }' ``` - `autoReloadEnabled` — enable/disable auto-reload (boolean) - `autoReloadThreshold` — balance (USD) that triggers a reload - `autoReloadAmount` — amount (USD) to add per reload ($1–$500) - `budgetLimit` — monthly spending cap in USD, or `null` to remove ## How do I manage API keys? ### POST /v1/keys Create a new API key. ```bash curl -X POST https://api.toolrouter.com/v1/keys \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "name": "My App", "credits": 10 }' ``` ### GET /v1/keys List all API keys (secrets masked). ### GET /v1/keys/:id Get details for a specific key. ### DELETE /v1/keys/:id Revoke an API key. ### POST /v1/keys/:id/credits Add credits to a key. ```bash curl -X POST https://api.toolrouter.com/v1/keys/key_abc/credits \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "amount": 5 }' ``` ## How do I check usage? ### GET /v1/usage Usage summary by tool and skill. ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.toolrouter.com/v1/usage?period=month" ``` Query params: `period` (day, week, month, all), `key_id`. ### GET /v1/usage/history Recent call history with costs. ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.toolrouter.com/v1/usage/history?limit=20" ``` Query params: `key_id`, `limit`. ## How do I manage async jobs? Long-running tool calls (30+ seconds) return a `202` with a `job_id` instead of an inline result. Poll for completion. ### GET /v1/jobs/:jobId Get the status and result of an async job. ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.toolrouter.com/v1/jobs/job_abc123 ``` ```json { "job_id": "job_abc123", "status": "completed", "tool": "deep-research", "skill": "research", "output": { "summary": "..." }, "elapsed_seconds": 45 } ``` Status values: `pending`, `running`, `completed`, `failed`, `cancelled`. ### POST /v1/jobs/:jobId/cancel Cancel a running async job. ```bash curl -X POST https://api.toolrouter.com/v1/jobs/job_abc123/cancel \ -H "Authorization: Bearer YOUR_API_KEY" ``` ```json { "cancelled": true, "job_id": "job_abc123" } ``` ## How do I manage credentials (BYOK)? Save your own provider API keys to override platform defaults. All tools work without this — BYOK is optional. ### GET /v1/account/requirements List all saved provider keys. ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.toolrouter.com/v1/account/requirements ``` ### PUT /v1/account/requirements/:name Save or update a provider key. ```bash curl -X PUT https://api.toolrouter.com/v1/account/requirements/openai \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "value": "sk-xxx", "label": "My OpenAI Key" }' ``` ### DELETE /v1/account/requirements/:name Remove a saved provider key. ```bash curl -X DELETE https://api.toolrouter.com/v1/account/requirements/openai \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## How do I submit reviews? ### POST /v1/reviews Rate a tool 1-5 stars with optional feedback. Free, no credits charged. One review per tool (re-submitting updates it). ```bash curl -X POST https://api.toolrouter.com/v1/reviews \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "tool": "web-search", "rating": 4, "review": "Fast and reliable" }' ``` ## Assets ### GET /v1/assets/:assetId Download a file produced by a tool call (screenshots, exports). ## What are the rate limits? Default limits per API key are 60 requests per minute, 1,000 per hour, and 5 concurrent. Rate limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`) are included on every response. Default limits per API key: | Window | Limit | |--------|-------| | Per minute | 60 requests | | Per hour | 1,000 requests | | Concurrent | 5 requests | Response headers on every request: - `X-RateLimit-Limit` — requests allowed in the current window - `X-RateLimit-Remaining` — requests remaining - `X-RateLimit-Reset` — seconds until the window resets ## What do error responses look like? All errors return a consistent JSON shape with `code`, `type`, `message`, and `resolution_hint`. Agents can branch on stable error types like `auth`, `billing`, `rate_limit`, `validation`, `provider`, and `not_found`. All errors follow a consistent shape: ```json { "error": { "code": "INSUFFICIENT_CREDITS", "type": "billing", "message": "Not enough credits for this call", "resolution_hint": "Add credits at toolrouter.com/billing or via toolrouter keys add-credits" } } ``` | HTTP | Type | Codes | When | |------|------|-------|------| | 404 | `not_found` | TOOL_NOT_FOUND, SKILL_NOT_FOUND | Bad tool/skill reference | | 400 | `validation` | INVALID_INPUT | Missing or malformed params | | 401 | `auth` | AUTH_REQUIRED, AUTH_FAILED | Missing or invalid API key | | 401 | `auth` | MISSING_CREDENTIALS | Tool credential not configured | | 402 | `billing` | INSUFFICIENT_CREDITS | Out of credits | | 429 | `rate_limit` | RATE_LIMIT_EXCEEDED | Too many requests | | 429 | `rate_limit` | SPENDING_LIMIT_EXCEEDED | Period limit exceeded | | 502 | `provider` | HANDLER_ERROR | Handler error | All errors include `resolution_hint` — agents can read this to self-recover.