Docs
Quickstart
Every API on API Runner is reached through one base URL with one Bearer token. Learn it once and you know all of them.
1. Base URL
All requests go to a single host. The path picks the provider and resource.
base url
https://api.apirunner.dev/v1/{provider}/{resource}2. Authentication
Create a key in the dashboard and send it in the Authorization header. Keys start with apr_live_. Keep them server-side.
header
Authorization: Bearer apr_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3. Your first request
Current weather for New York, in your language of choice:
curl "https://api.apirunner.dev/v1/weather/current?lat=40.7128&lon=-74.0060&units=metric" \
-H "Authorization: Bearer YOUR_RUNNER_KEY"4. Switching providers
Same host, same header — only the path and body change. Here's Claude with the identical setup:
curl -X POST "https://api.apirunner.dev/v1/anthropic/messages" \
-H "Authorization: Bearer YOUR_RUNNER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet",
"system": "You are a terse senior engineer.",
"prompt": "Explain what a 429 means and how to back off.",
"max_tokens": 300
}'| Route | API | Status |
|---|---|---|
| GET/v1/weather/current | Weather | live |
| GET/v1/weather/forecast | Weather | live |
| GET/v1/weather/geocode | Weather | live |
| POST/v1/fitness/steps | Pedometer & Fitness | live |
| GET/v1/fitness/stride | Pedometer & Fitness | live |
| POST/v1/fitness/devices/sync | Pedometer & Fitness | live |
| POST/v1/openai/chat/completions | OpenAI Chat | live |
| POST/v1/openai/images/generations | OpenAI Images | live |
| POST/v1/openai/audio/speech | OpenAI Voice & Whisper | live |
| POST/v1/openai/audio/transcriptions | OpenAI Voice & Whisper | live |
| POST/v1/gemini/generate | Google Gemini | live |
| POST/v1/gemini/multimodal | Google Gemini | live |
| POST/v1/anthropic/messages | Anthropic Claude | live |
| POST/v1/email/send | soon | |
| GET/v1/email/messages/{id} | soon | |
| POST/v1/push/send | Push & Webhooks | soon |
| POST/v1/webhooks | Push & Webhooks | soon |
| POST/v1/mistral/chat/completions | Mistral | live |
| POST/v1/llama/chat/completions | Meta Llama | live |
| POST/v1/deepseek/chat/completions | DeepSeek | live |
| POST/v1/perplexity/ask | Perplexity Sonar | soon |
| POST/v1/embeddings | Text Embeddings | live |
| POST/v1/translate | Translate | live |
| POST/v1/stability/generate | Stable Diffusion | live |
| POST/v1/vision/ocr | OCR & Documents | live |
| POST/v1/voice/clones | Voice Cloning | soon |
| POST/v1/vision/detect | Object Detection | live |
| POST/v1/vision/remove-background | Background Removal | live |
| GET/v1/geo/forward | Address Geocoding | live |
| GET/v1/geo/reverse | Address Geocoding | live |
| GET/v1/ip/lookup | IP Geolocation | live |
| GET/v1/fx/convert | Currency Rates | live |
| POST/v1/qr | QR Codes | live |
| GET/v1/air-quality/current | Air Quality | live |
| GET/v1/fitness/heart/daily | Heart Rate & Sleep | soon |
| POST/v1/links | URL Shortener | live |
| POST/v1/sms/send | SMS | soon |
| POST/v1/messaging/post | Slack & Discord | soon |
5. Status codes
Errors share one shape, whatever the upstream provider:
error body
{
"error": {
"type": "rate_limit_exceeded",
"message": "Limit of 8 requests per 10s reached. Retry after 4s.",
"request_id": "req_8kq2m4v7xz1p"
}
}- 200OK
- Request succeeded. Body is the provider's response, normalized where noted.
- 400Bad Request
- Malformed JSON or unsupported content type.
- 401Unauthorized
- Missing, revoked or invalid Bearer token.
- 422Unprocessable Entity
- Validation failed. `error.fields` lists what to fix.
- 429Too Many Requests
- Rate limit hit. Wait `Retry-After` seconds, then retry with backoff.
- 502Bad Gateway
- Upstream provider failed. Safe to retry idempotent requests.
6. Rate limits & response headers
Every response carries these headers so you can debug without guessing:
response headers
x-request-id: req_8kq2m4v7xz1p
x-runner-latency: 142ms
x-runner-upstream: anthropic
x-ratelimit-limit: 8
x-ratelimit-remaining: 6
retry-after: 4 # only on 429The playground enforces 8 requests per 10 seconds — click Run quickly a few times to see a real 429.