curl --request POST \
--url https://apistable.com/v1/tasks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "prism-image-2",
"input": {
"prompt": "<string>",
"duration_seconds": 123,
"resolution": "<string>",
"seed": 1,
"generate_audio": true,
"instrumental": true,
"lyrics": "<string>"
},
"output_count": 1,
"fallback": false,
"max_credits": 1
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'prism-image-2',
input: {
prompt: '<string>',
duration_seconds: 123,
resolution: '<string>',
seed: 1,
generate_audio: true,
instrumental: true,
lyrics: '<string>'
},
output_count: 1,
fallback: false,
max_credits: 1
})
};
fetch('https://apistable.com/v1/tasks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://apistable.com/v1/tasks"
payload = {
"model": "prism-image-2",
"input": {
"prompt": "<string>",
"duration_seconds": 123,
"resolution": "<string>",
"seed": 1,
"generate_audio": True,
"instrumental": True,
"lyrics": "<string>"
},
"output_count": 1,
"fallback": False,
"max_credits": 1
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "provider_not_configured",
"message": "Live model providers are not connected in this build. No credits were reserved or charged."
}
}Your first request
From one API key to a clear, traceable generation flow.
curl --request POST \
--url https://apistable.com/v1/tasks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "prism-image-2",
"input": {
"prompt": "<string>",
"duration_seconds": 123,
"resolution": "<string>",
"seed": 1,
"generate_audio": true,
"instrumental": true,
"lyrics": "<string>"
},
"output_count": 1,
"fallback": false,
"max_credits": 1
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'prism-image-2',
input: {
prompt: '<string>',
duration_seconds: 123,
resolution: '<string>',
seed: 1,
generate_audio: true,
instrumental: true,
lyrics: '<string>'
},
output_count: 1,
fallback: false,
max_credits: 1
})
};
fetch('https://apistable.com/v1/tasks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://apistable.com/v1/tasks"
payload = {
"model": "prism-image-2",
"input": {
"prompt": "<string>",
"duration_seconds": 123,
"resolution": "<string>",
"seed": 1,
"generate_audio": True,
"instrumental": True,
"lyrics": "<string>"
},
"output_count": 1,
"fallback": False,
"max_credits": 1
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "provider_not_configured",
"message": "Live model providers are not connected in this build. No credits were reserved or charged."
}
}API preview: generation providers are not connected. An authenticated request can return 503 without creating a task or charging credits.
Start with the preview
APIstable is being built in two stages: the website, account system, and execution architecture first; real model providers next. The model catalog and prices currently illustrate the contract. They are not a claim that paid inference is available. Examples on these pages describe the API preview. A provider-not-configured response is expected until a route is enabled. Copying a code example does not execute it or spend credits. Explore the model catalogWhat works in this build
| Endpoint | Current behavior |
|---|---|
| GET /v1/models | Public preview catalog; no key required. |
| POST /v1/quotes | Public input validation and sample pricing; no key required and no credit reservation. |
| GET /v1/balance | Requires a valid key with usage:read and a connected database. |
| GET /v1/tasks and /v1/tasks/ | Reads stored account tasks with usage:read; an unknown ID returns 404. |
| POST /v1/tasks and /v1/chat/completions | After authentication and applicable validation: HTTP 503 provider_not_configured; no live generation or credit charge. |
1. Create an API key
Sign in and open Console → API Keys. Save the complete key when it is created; it is only revealed once. Use a separate key for each app or environment.export APISTABLE_BASE_URL="https://api.example.com"
export APISTABLE_API_KEY="YOUR_API_KEY"
export APISTABLE_IDEMPOTENCY_KEY="YOUR_UNIQUE_OPERATION_KEY"
Replace the example origin with your APIstable deployment. API keys belong in your server environment, never in browser code, query strings, or public repositories.Manage API keys
2. Quote, then submit
Choose an exact model ID and validate the input. A quote shows the eligible low-cost and official routes, the price per result, and the maximum reservation for the whole request. Direct API clients may submit without a separate quote call; the server still calculates and validates the price. For images and videos, output_count creates 1–4 result items. fallback is off by default. When enabled, each item can independently try the official route after a confirmed eligible failure. Create a task Understand credits3. Keep the task ID
An accepted media request returns HTTP 202 and a stable task_id. Keep it and query that task instead of submitting again. A network timeout does not tell you whether the supplier accepted the generation.- Poll at a sensible interval and respect Retry-After. Check queued, running, falling_back, and reconciliation_required as non-final states.
- Read each item, including successful results in a partially completed task. Download files before expires_at.
- A failed notification does not invalidate a completed generation or repeat its charge.
Authorizations
API key beginning as_. Keep on the server. Scope permissions are checked separately.
Headers
Reserved for live acceptance. No task is currently created or deduplicated by this header.
Body
1"prism-image-2"
Current preview input. Supported fields vary by modality and exact catalog model. No live provider mapping is implied.
Show child attributes
Show child attributes
Target result count. Images/videos accept 1–4; music and LLM must remain 1. Not a concurrency guarantee. / 目标结果数,非同时并发保证。
1 <= x <= 4Authorizes a higher-priced compatible official fallback after an eligible confirmed failure. Live execution is disabled in this build.
Whole-request reservation cap. Reject the entire request when max_reserved_credits exceeds it.
x >= 0Response
Invalid or unsupported input
Show child attributes
Show child attributes