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: startedprogress (handler logs) → rate_limitresult (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:

WindowLimit
Per minute60 requests
Per hour1,000 requests
Concurrent5 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"
  }
}
HTTPTypeCodesWhen
404not_foundTOOL_NOT_FOUND, SKILL_NOT_FOUNDBad tool/skill reference
400validationINVALID_INPUTMissing or malformed params
401authAUTH_REQUIRED, AUTH_FAILEDMissing or invalid API key
401authMISSING_CREDENTIALSTool credential not configured
402billingINSUFFICIENT_CREDITSOut of credits
429rate_limitRATE_LIMIT_EXCEEDEDToo many requests
429rate_limitSPENDING_LIMIT_EXCEEDEDPeriod limit exceeded
502providerHANDLER_ERRORHandler error

All errors include resolution_hint — agents can read this to self-recover.