Jobs API
Create, monitor, and manage AI inference jobs.
Endpoints
/v1/models/{model}/runRun a model/v1/jobs/{id}Get job status & result/v1/jobs/{id}Cancel a jobRun a Model
Execute inference on a model. By default, this endpoint waits for the result and returns it directly in the response (synchronous mode).
/v1/models/{model}/runRequest Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| input | object | Yes | Model-specific input parameters |
| sync | boolean | No | Wait for result (default: true). Set to false for async mode. |
| webhook_url | string | No | URL to receive the completed result via POST. Recommended for slow models. |
Example: Fast Model (Sync)
For fast models, the result is returned directly in the response:
curl -X POST https://api.abstrakt.one/v1/models/flux-schnell/run \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"prompt": "A beautiful sunset over mountains",
"image_size": "square_hd",
"num_images": 1
}
}'Response (200 - Completed)
{
"job_id": "job_abc123xyz",
"request_id": "fal_req_456",
"status": "completed",
"model_id": "flux-schnell",
"output": {
"type": "image",
"items": [
{
"type": "image",
"url": "https://cdn.abstrakt.one/outputs/abc123.png"
}
]
},
"duration_ms": 1823,
"credits_used": 1
}Handling Slow Models
Important for integrations
Some models (image editing, video generation, etc.) take longer to process. When a model takes more than ~55 seconds, the API returns a 202 response instead of blocking indefinitely. Your integration should handle both 200 and 202 responses.
Response (202 - Still Processing)
When a model needs more time, you receive a 202 with the job ID:
{
"job_id": "job_abc123xyz",
"request_id": "fal_req_456",
"status": "processing",
"model_id": "nano-banana-pro-edit",
"message": "Model is still generating. Poll GET /v1/jobs/job_abc123xyz for the completed result."
}Option 1: Poll for the Result
After receiving a 202, poll GET /v1/jobs/{job_id} until the status is succeeded:
# Poll every 5 seconds until complete
while true; do
RESPONSE=$(curl -s https://api.abstrakt.one/v1/jobs/job_abc123xyz \
-H "Authorization: Bearer YOUR_API_KEY")
STATUS=$(echo $RESPONSE | jq -r '.data.status')
if [ "$STATUS" = "succeeded" ]; then
echo "Done! Output:"
echo $RESPONSE | jq '.data.output'
break
elif [ "$STATUS" = "failed" ]; then
echo "Failed:"
echo $RESPONSE | jq '.data.error'
break
fi
echo "Status: $STATUS - waiting..."
sleep 5
doneOption 2: Use a Webhook (Recommended)
Pass a webhook_url in your request. When the job completes, the result is POSTed directly to your URL -- no polling needed:
curl -X POST https://api.abstrakt.one/v1/models/nano-banana-pro-edit/run \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"prompt": "A cat wearing sunglasses",
"image_url": "https://example.com/cat.jpg"
},
"webhook_url": "https://your-server.com/webhooks/abstrakt"
}'Your webhook endpoint will receive a POST with the completed result:
{
"job_id": "job_abc123xyz",
"status": "succeeded",
"output": {
"type": "image",
"items": [
{
"type": "image",
"url": "https://cdn.abstrakt.one/outputs/abc123.png"
}
]
},
"credits_used": 1,
"completed_at": "2026-02-08T10:30:45Z"
}Tip: Your webhook handler should return a 2xx status quickly. If it fails, the delivery will not be retried, so make sure your endpoint is reliable. You can always fall back to polling GET /v1/jobs/{id} as a backup.
Get Job Status
Retrieve the current status and result of a job. When a job is still processing, this endpoint checks the provider for completion and returns the result if ready.
/v1/jobs/{id}Path Parameters
| Parameter | Description |
|---|---|
| id | The job ID returned from the run endpoint (job_id field) |
Example
curl https://api.abstrakt.one/v1/jobs/job_abc123xyz \
-H "Authorization: Bearer YOUR_API_KEY"Job Statuses
| Status | Description |
|---|---|
| queued | Job is queued and waiting to be processed |
| processing | Job is currently being processed by the model |
| succeeded | Job finished successfully. Output is included in the response. |
| failed | Job failed with an error |
| cancelled | Job was cancelled by the user |
Async Mode
For jobs where you don't want to wait at all, set sync: false to return immediately with a job ID. The job runs in the background and you can retrieve the result later via polling or webhook.
curl -X POST https://api.abstrakt.one/v1/models/minimax-video-01/run \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"prompt": "A timelapse of clouds moving over a city"
},
"sync": false,
"webhook_url": "https://your-server.com/webhooks/abstrakt"
}'Response
{
"job_id": "job_def456uvw",
"request_id": "fal_req_789",
"status": "queued",
"model_id": "minimax-video-01"
}Then poll GET /v1/jobs/{job_id} or wait for the webhook to receive the result when ready.
Cancel a Job
Cancel a queued or processing job. Credits are not charged for cancelled jobs.
/v1/jobs/{id}Example
curl -X DELETE https://api.abstrakt.one/v1/jobs/job_abc123xyz \
-H "Authorization: Bearer YOUR_API_KEY"Recommended Integration Pattern
For a robust integration that handles both fast and slow models:
import requests
import time
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.abstrakt.one"
def run_model(model_id, input_params, webhook_url=None):
"""Run a model and handle both instant and delayed results."""
body = {"input": input_params}
if webhook_url:
body["webhook_url"] = webhook_url
response = requests.post(
f"{BASE_URL}/v1/models/{model_id}/run",
headers={"Authorization": f"Bearer {API_KEY}"},
json=body,
)
data = response.json()
# Fast model: result returned immediately (200)
if response.status_code == 200 and data.get("status") == "completed":
return data["output"]
# Slow model: poll for result (202)
job_id = data.get("job_id")
if not job_id:
raise Exception(f"Unexpected response: {data}")
# Poll until complete (skip if using webhook_url)
if not webhook_url:
for _ in range(60): # up to 5 minutes
time.sleep(5)
status_resp = requests.get(
f"{BASE_URL}/v1/jobs/{job_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
)
status_data = status_resp.json().get("data", {})
if status_data.get("status") == "succeeded":
return status_data.get("output")
if status_data.get("status") == "failed":
raise Exception(status_data.get("error"))
return {"job_id": job_id, "status": "processing"}
# Usage
result = run_model("flux-schnell", {"prompt": "A sunset"})