Connection and usage
Connection and usage
Which base URL should I use?
https://api.beatapi.io. Whether a /v1 belongs on the end depends on what the client appends for you.
Getting this wrong produces a 404 on every request, which most clients report as “cannot connect” rather than as a bad URL.
Everything returns 404
In order of likelihood:
- A doubled or missing
/v1. See the table above./v1/v1/chat/completionsdoes not exist. - A trailing slash on the base URL, which some clients concatenate literally.
- An endpoint that is not part of the published surface. BeatAPI publishes a deliberate list — text, tasks, files, usage, webhooks, realtime. Endpoints outside it return
404rather than an error, on purpose./v1/embeddings,/v1/rerank,/v1/moderations, and/v1/audio/*are not served. - A model ID that does not exist. IDs are case-sensitive and carry no vendor prefix —
claude-fable-5-1, notanthropic/claude-fable-5-1.
401 unauthorized
The key is missing, malformed, revoked, or inactive.
- The header is
Authorization: Bearer <key>. A missingBearerprefix reads as a malformed key. - Whitespace pasted around the key counts as part of the key.
- Confirm the key is still active in Dashboard → API Keys. A revoked key fails immediately and permanently.
- Some clients send an
x-api-keyorx-goog-api-keyheader instead; that is fine — all of them identify the same account and the same balance.
403 forbidden
Authentication succeeded but the operation is not allowed for this account or this key. Check the key’s own restrictions and the account’s status before looking at the request.
402 insufficient_credits
The balance is exhausted. Every paid operation on the account fails until credits are added — this is not per-key. Worth alerting on if anything you run is user-facing.
429 rate_limit_exceeded
Two different limits return a 429, and they need opposite responses:
- Request rate — too many requests per minute for this key. Honour
Retry-Afterorretry_after_seconds. The allowance rises with lifetime top-ups. user_concurrency_exceeded— too many tasks processing at once. Retrying immediately makes it worse; wait for a running task to finish.GET /v1/usagereportsconcurrency.limitandconcurrency.active.
A polling loop is the usual cause of the first. The task endpoint allows up to 120 requests per minute per key, which a fixed one-second poll across a few tasks will exhaust on its own — see Development Guide.
A request times out
Text calls with stream: false return nothing until the model has finished, and a long reasoning response can take a while. Two things help:
- Stream. With
stream: truethe first bytes arrive quickly and the connection stays active throughout. - Raise the client timeout. Many SDKs default to 30 or 60 seconds, which is short for a long non-streaming completion.
A task never finishes
Check the status rather than the clock. GET /v1/tasks/{task_id} returns one of a fixed set of states, and two of them are not “still working”:
storyboard_readyandrequires_actionon Music Video tasks are waiting for you, not for the model. Polling them forever will not advance them.
Everything else is either terminal (succeeded, failed) or genuinely in progress. See the Quick Guide for the full table.
Connections fail from a server but work from my laptop
Test from the machine that actually makes the call. Self-hosted platforms — Dify, AnythingLLM in Docker, CI runners — have their own egress rules. Confirm the container or host can reach api.beatapi.io, and allow it through any corporate proxy.
What do I include in a bug report?
The request_id from the failing response. Every BeatAPI error carries one, and it identifies the exact call in the logs. Add the model ID, the endpoint, and the approximate time. Open the ticket from the dashboard.

