Authentication
Every /v1 request carries an API key:
Authorization: Bearer vk_k3x9Qm2a_7fG...Keys are not accepted in the address or as a cookie. A signed-in browser session does not work on /v1, and a key does not work on the console.
The key
A key looks like vk_<prefix>_<secret>: vk_, eight characters of public prefix, an underscore and a long random secret. The prefix is shown in the console so you can tell keys apart; the whole string is the secret to send.
- The secret is shown once, when the key is created. voao pro keeps only a one-way hash, so it cannot show it again. If you lose it, make a new key.
- Treat it like a password: keep it on your server, never in a browser, a mobile app or a repository.
- To rotate without downtime, create a second key with the same name, workspace and scopes, switch your systems to it, then revoke the first.
- A key can have an expiry date. After it, the key stops working.
Workspace binding
A key belongs to one workspace of your organization, chosen when it is created. Everything the key makes (jobs, uploads, results) belongs to that workspace, and the key can see nothing outside it. An id from another workspace or organization answers 404 not_found, exactly as if it did not exist.
A key acts as its maker
A key acts as the person who created it:
- Jobs made with the key are that person's. Their spending limits and your workspace's limits apply, and credits are reserved from your organization's balance as for any job.
- The key can never do more than both its scopes and its maker's present rights in the workspace allow. If the maker is made a viewer, a key with
jobs:writecan no longer submit. - If the maker leaves the organization, loses their role in the workspace or deletes their account, the key stops working at once. The console shows it as inactive, with the reason.
- A key cannot create, list or revoke keys or webhook endpoints, change members or billing, or reach any console route.
Scopes
Choose the fewest scopes a system needs.
| Scope | Allows |
|---|---|
models:read | GET /v1/models, GET /v1/tools, POST /v1/price |
jobs:read | GET /v1/jobs, GET /v1/jobs/{jobId} |
jobs:write | POST /v1/jobs, POST /v1/jobs/{jobId}/cancel, and POST /v1/price |
assets:read | GET /v1/assets/{assetId}, GET /v1/assets/{assetId}/download |
assets:write | POST /v1/assets/uploads, POST /v1/assets/{assetId}/upload/parts, POST /v1/assets/{assetId}/complete |
usage:read | GET /v1/usage |
A typical job runner needs models:read, jobs:write, jobs:read and assets:read (plus assets:write if it uploads inputs).
Refusals
| Status | Code | When |
|---|---|---|
| 401 | unauthenticated | The key is missing, malformed, unknown, revoked or expired; its maker lost access; the plan has no API access; or the organization awaits deletion. The answer is the same for all of these and does not say which, so it cannot be used to probe for keys. The console's key list shows the reason. |
| 403 | not_allowed | The key is valid but its scopes do not allow the operation, or its maker may not do it. |
| 403 | model_locked | The model is above your plan (it is listed with locked: true). |
| 404 | not_found | The object does not exist, or belongs to another workspace or organization. |
| 409 | org_read_only | The organization is read-only: reads still work, submitting and uploading do not. |
Errors use the standard shape.
Example
curl -sS https://api.example.com/v1/models \
-H "Authorization: Bearer $VOAO_API_KEY"Replace https://api.example.com with the API address of your organization's voao pro deployment. The samples in these guides use $VOAO_API for it.