SciFig

API reference

Jobs and bounded waiting

Read job status, credits and outputs, and wait for a job without polling.

Read a job#

GET /jobs/{id} (scope jobs:read) returns the same job object as the create request. Jobs of other accounts and unknown IDs both return 404 NOT_FOUND. GET /jobs?limit=10&cursor=… lists your jobs, newest first (1–20 per page, follow next_cursor).

{
  "id": "5f4a9a5e-fc45-4eae-9f9c-56b5f686cba5",
  "kind": "chart",
  "status": "succeeded",
  "created_at": "2026-10-14T11:20:05.000Z",
  "credits": { "reserved": 50, "charged": 50, "refunded": 0 },
  "outputs": [
    {
      "file_id": "0b7c…",
      "format": "png",
      "width": 2126,
      "height": 1417,
      "download_url": "https://scifig.ai/api/v1/files/0b7c…?exp=…&sig=…",
      "expires_at": "2026-10-14T12:21:40.000Z",
      "editor_url": "https://scifig.ai/app/datachart?conversation=…"
    }
  ],
  "error": null
}

kind is image_generation, image_edit, image_upscale, image_conversion, chart or flowchart. Responses never include your prompt, your inputs or internal identifiers.

Output fieldPresentMeaning
file_idalwaysPass it to another endpoint or to GET /files/{file_id}
formatalwaysFile extension of the output, such as png, svg or pdf
width, heightPNG outputsPixel size
download_url, expires_atalwaysSigned link, valid for one hour
editor_urlchart and flowchart jobsOpens the result in its website workspace; illustrations and conversions have none

Status lifecycle#

statusMeaning
queuedAccepted and waiting for capacity
processingRunning
succeededDone; outputs are ready and credits charged
failedDid not produce a result; error.code says why and the reservation is refunded
canceledStopped before finishing; refunded
`error.code` of a failed jobMeaningWhat to do
TASK_TIMED_OUTThe task timed out and was refunded. An illustration generation or edit may carry late_delivery_until: until then the result can still arrive for free.Keep reading the job until late_delivery_until; otherwise send a new request with a new key
CONTENT_REJECTEDThe content policy refused the result while the task ran; refunded. The same code is returned as 422 when the request itself is refused at creation.Change the prompt or the input and use a new key
ADMISSION_INCOMPLETEThe job was never started because a retryable error stopped it. No credits were used.Send the same request with the same Idempotency-Key
TASK_NOT_FOUNDThe job was admitted but its task can no longer be found.Send a new request with a new key
TASK_FAILEDThe task failed and was refunded. Every engine failure without a public code of its own becomes TASK_FAILED; the engine code is in details.reason.Send a new request with a new key
INTERNAL_ERRORThe task failed without reporting a reason; refunded.Send a new request with a new key

succeeded, failed and canceled are final, with one exception: an illustration generation or edit that failed with TASK_TIMED_OUT carries late_delivery_until. Until then the result may still arrive, for free, and the job turns succeeded; keep reading it instead of creating a new one.

If any job in the list cannot be read, GET /jobs returns 503 SERVICE_UNAVAILABLE with Retry-After: 3; retry the list request. It does not replace that job with a failed result.

Bounded waiting#

  • Prefer: wait=N (1–30) on a create request holds the response until the job is final or N seconds pass. Final jobs return 200; jobs still running return 202 with Location: /api/v1/jobs/{id} and Retry-After.
  • Waiting does not change the job: a 202 is not an error, and the job keeps running after the response.
  • Poll GET /jobs/{id} no faster than Retry-After (3 seconds). Illustrations usually finish in 20–90 seconds, charts and flowcharts in 30–120 seconds.
  • A failed job may also hold a refused request: a create request refused with an error such as 402 INSUFFICIENT_CREDITS or 422 CONTENT_REJECTED stays in GET /jobs as a failed job with that code and no credits.
  • Server integrations should store the job ID before waiting, so that a dropped connection never leads to a second job.

cURL#

curl https://scifig.ai/api/v1/jobs/<job_id> \
  -H "Authorization: Bearer $SCIFIG_API_KEY"

JavaScript#

const response = await fetch('https://scifig.ai/api/v1/jobs/<job_id>', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SCIFIG_API_KEY}`,
  },
});
const result = await response.json();
console.log(response.status, result);

Python#

import os

import requests

headers = {
    "Authorization": f"Bearer {os.environ['SCIFIG_API_KEY']}",
}
response = requests.get(
    "https://scifig.ai/api/v1/jobs/<job_id>",
    headers=headers,
    timeout=60,
)
print(response.status_code, response.json())