API documentation
API Many exposes every model through one base URL and one key. Text endpoints follow the OpenAI and Anthropic formats, so official SDKs work unchanged; image, video and music run as asynchronous tasks.
Base URL https://apimany.com/v1
Quickstart
curl https://apimany.com/v1/chat/completions \
-H "Authorization: Bearer $APIMANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "claude-sonnet-5-5", "messages": [{"role": "user", "content": "Hello"}]}'Authentication
Send your key in the Authorization header as a Bearer token. Keys are secret: call the API from your server, never from a browser or mobile app.
Authorization: Bearer sk_apimany_xxxxxxxxxxxxxxxx
# Anthropic-style clients may send the key as:
x-api-key: sk_apimany_xxxxxxxxxxxxxxxxSDKs
Use the official OpenAI SDK (Python, Node.js, Go, Java, .NET) with base_url https://apimany.com/v1, or the official Anthropic SDK with base_url https://apimany.com. Any HTTP client works for media endpoints.
Billing
Every request reserves its maximum cost from your balance when it starts and is settled when it finishes:
- Text: billed by the input, cached and output tokens the model reports, at the per-million prices on its page.
- Images: billed per image at the chosen resolution or quality; token-priced image models settle on reported usage.
- Video: billed per second at the chosen resolution (or per clip for fixed-length models).
- Failed, rejected and timed-out requests are not charged: the reserve is returned in full.
Send an Idempotency-Key header (1–200 characters) to make retries safe: a repeated key returns the original record instead of running again.
Chat completions POST/v1/chat/completions
OpenAI-compatible chat for every language model, including Claude, Gemini, DeepSeek, Grok, Qwen and Kimi. Streaming, tools, JSON mode and image inputs follow the OpenAI format. Streamed responses include usage in the final chunk.
curl https://apimany.com/v1/chat/completions \
-H "Authorization: Bearer $APIMANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4.1-flash",
"stream": true,
"messages": [
{"role": "system", "content": "You are concise."},
{"role": "user", "content": "Summarize HTTP/3 in two sentences."}
]
}'Anthropic Messages POST/v1/messages
Claude models also accept the native Anthropic Messages API, including streaming, tool use, extended thinking and prompt caching. The anthropic-version and anthropic-beta headers are forwarded.
import anthropic
client = anthropic.Anthropic(base_url="https://apimany.com", api_key="YOUR_API_KEY")
message = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Write a haiku about APIs."}],
)
print(message.content[0].text)Responses POST/v1/responses
The OpenAI Responses API for models that support it.
curl https://apimany.com/v1/responses \
-H "Authorization: Bearer $APIMANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gpt-6.1-sol", "input": "Explain recursion to a child."}'Embeddings POST/v1/embeddings
curl https://apimany.com/v1/embeddings \
-H "Authorization: Bearer $APIMANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "text-embedding-3-small", "input": ["first text", "second text"]}'Images POST/v1/images/generations
Text-to-image and image editing. Each model documents its own fields (size, resolution, quality, reference images) on its model page; send them as listed there. The call returns a task immediately:
curl https://apimany.com/v1/images/generations \
-H "Authorization: Bearer $APIMANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A watercolor fox in a snowy forest",
"size": "16:9",
"resolution": "2k",
"image_urls": ["https://example.com/style-reference.png"]
}'{
"id": "2c7f9a8e-0d1b-4b5e-9a5d-6f0c1e2d3a4b",
"object": "generation.task",
"model": "seedance-2.5",
"status": "pending",
"reserved_usd": 2.16,
"task_id": "2c7f9a8e-0d1b-4b5e-9a5d-6f0c1e2d3a4b"
}Videos POST/v1/videos/generations
Text-to-video, image-to-video, references, edits and extensions — depending on the model. Per-second models reserve the requested duration and settle on the delivered clip.
curl https://apimany.com/v1/videos/generations \
-H "Authorization: Bearer $APIMANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"prompt": "Slow dolly-in on a neon alley after rain",
"resolution": "720p",
"duration": 8,
"size": "16:9",
"callback_url": "https://your-app.com/webhooks/apimany"
}'Music POST/v1/music/generations
curl https://apimany.com/v1/music/generations \
-H "Authorization: Bearer $APIMANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "suno", "custom": false, "version": "v6", "prompt": "Late-night lo-fi piano with soft rain"}'Tasks & polling GET/v1/tasks/{id}
Poll every 3–10 seconds until status is completed or failed. Statuses: pending, processing, completed, failed. Completed tasks list signed file URLs that stay valid for 30 days; download anything you need to keep.
curl https://apimany.com/v1/tasks/TASK_ID -H "Authorization: Bearer $APIMANY_API_KEY"Webhooks
Add callback_url (public HTTPS) to any media request and we POST the finished task to it, retrying with backoff for up to six attempts. Verify X-Apimany-Signature with the webhook secret from your API keys page.
import crypto from 'node:crypto'
// Express-style handler; keep the raw body for the signature check.
export function verify(rawBody, headers, secret) {
const timestamp = headers['x-apimany-timestamp']
const expected = crypto.createHmac('sha256', secret.replace(/^whsec_/, ''))
.update(`${timestamp}.${rawBody}`).digest('hex')
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(headers['x-apimany-signature']))
}
// Payload: { "event": "task.completed" | "task.failed", "data": { ...task, "record": { ... } } }Transcription POST/v1/audio/transcriptions
OpenAI-compatible speech-to-text with multipart upload (up to 25 MB).
curl https://apimany.com/v1/audio/transcriptions \
-H "Authorization: Bearer $APIMANY_API_KEY" \
-F model=gpt-4o-transcribe \
-F [email protected] \
-F response_format=jsonModels GET/v1/models
Public list of every model with type, endpoint and pricing; filter with ?kind=chat|image|video|audio|embedding.
# Every model with its pricing (no key needed)
curl https://apimany.com/v1/models
# Only video models
curl "https://apimany.com/v1/models?kind=video"
# One model with its parameters
curl https://apimany.com/v1/models/seedance-2.5Records GET/v1/records
Every call you make — text, media and audio — has a record with status, usage, cost and outputs. Filter by model, kind, status, api_key_id or since.
curl "https://apimany.com/v1/records?limit=20&kind=video&status=completed" \
-H "Authorization: Bearer $APIMANY_API_KEY"
curl https://apimany.com/v1/records/RECORD_ID -H "Authorization: Bearer $APIMANY_API_KEY"Balance GET/v1/account/balance
curl https://apimany.com/v1/account/balance -H "Authorization: Bearer $APIMANY_API_KEY"
# { "object": "balance", "currency": "usd", "balance_usd": 42.17, "debt_usd": 0 }Errors
Errors use the OpenAI error shape, so SDK exceptions work as usual.
{
"error": {
"message": "Your balance is too low for this request. Top up and try again.",
"type": "insufficient_quota",
"param": null,
"code": "insufficient_balance"
}
}| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_request | A parameter is missing or not allowed for this model. Nothing was charged. |
| 401 | invalid_api_key | The key is missing, malformed or revoked. |
| 402 | insufficient_balance | Your balance cannot cover the reserve for this request. |
| 404 | model_not_found | The model id does not exist. List models with GET /v1/models. |
| 409 | idempotency_replay | This Idempotency-Key was already used; fetch the earlier record instead. |
| 413 | request_too_large | The request body is over the size limit. Send media as URLs. |
| 429 | rate_limited | Too many requests per minute for this key. Retry with backoff. |
| 502 | generation_failed | Every channel for this model failed. Nothing was charged; retry shortly. |
| 503 | model_unavailable | The model is temporarily unavailable. |
Limits
- Request body: up to 25 MB for text and 40 MB for media requests. Pass large files as HTTPS URLs.
- Playground uploads: images up to 10 MB, video up to 100 MB, audio up to 50 MB.
- Rate limit: 120 requests per minute per account by default. Contact us for higher limits.
- Generated files are kept for 30 days. Tasks that never finish are reviewed and refunded.
- Model capabilities and per-model limits follow the model maker.