Authentication
Every call that runs a model or reads your requests needs an API key. The catalog (GET /models,
GET /categories), POST /quote and the OpenAPI document are public.
API keys
Create and revoke keys at https://doitong.com/developers/dashboard#keys. A key looks
like doitong_ followed by 64 hex characters and is shown only once, when you create it. Send it in the
Authorization header:
curl https://api.doitong.com/v1/account -H "Authorization: Bearer $DOITONG_API_KEY"
X-API-Key: <key> works as well.
A request without a key gets 401 with code missing_api_key; an unknown, revoked or expired key gets 401 as well.
Scopes
Each key carries scopes. The model API checks these:
| Action | Scope needed |
|---|---|
| Run a model, cancel a request, delete a request's files, change the storage setting | models:run (keys with the older images:create or videos:create also work) |
| Create an upload URL | models:run or media:upload |
| Read requests, account | models:read (a key that may run models reads too) |
New keys get models:read and models:run by default. A call without the right scope gets 403 with code
insufficient_scope.
Credit budgets
A key can carry its own budget in API credits (1,000 API credits = $1), set by the account owner: a total budget, a
daily budget (last 24 hours), or both. Before a run is charged, the cost is checked against what the key has already
spent through this API (net of refunds). A run that would exceed it is refused with 402 budget_exceeded and nothing
is charged.
A key without a budget can
spend up to the API balance. Separately, a run that the API balance cannot cover gets 402 insufficient_credits
with a top_up_url.
GET https://api.doitong.com/v1/account shows the API balance and the key's remaining budget (both in API credits):
{
"object": "account",
"credits": 125000,
"balance": { "credits": 125000, "usd": "125.00" },
"top_up_url": "https://doitong.com/developers/dashboard#balance",
"key": {
"name": "Production server",
"prefix": "doitong_3fa9c1e...",
"scopes": ["models:read", "models:run"],
"budget_remaining": 50000,
"rate_limit": 3600,
"rate_limit_remaining": 3571
},
"webhook_signing_secret": "whsec_..."
}
budget_remaining is null when the key has no budget of its own.
Rate limits
Each key may make 3600 requests per hour unless its limit was set differently. Every authenticated response carries the current state:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Requests allowed in the current window |
X-RateLimit-Remaining |
Requests left in the current window |
X-RateLimit-Reset |
Unix time when the window resets |
Over the limit you get 429 with a Retry-After header (seconds). Long polling with ?wait= counts as one request
per call, so waiting is cheaper than polling quickly.
There is also a limit of 10 requests in progress (queued or running) per account. Starting one more returns
429 too_many_inflight; start it again after one finishes.