6ioAPI

Background jobs

POST /v1/jobs starts an operation in the background. You get a 202 answer and a job ID at once, then ask for the state yourself and collect the finished result. It is handy when a request is long or you do not want to keep a connection open.

For now there is one operation, chat.completions (chat of the op and vn groups). Images and video through fal and sixio already work as tasks: see fal models and Sixio models.

A full example

import time
import requests

API = "https://api.6io.io/v1"
H = {"Authorization": "Bearer sixio_sk_..."}

job = requests.post(f"{API}/jobs", headers=H, json={
    "model": "op/openai/gpt-4o-mini",
    "operation": "chat.completions",
    "input": {"messages": [{"role": "user", "content": "Hello!"}], "max_tokens": 200},
}).json()

while True:
    state = requests.get(job["status_url"], headers=H).json()
    if state["status"] != "running":
        break
    time.sleep(2)

if state["status"] == "succeeded":
    result = requests.get(job["result_url"], headers=H).json()
    print(result["choices"][0]["message"]["content"])
else:
    print(state["status"], state.get("error"))

Create a job

input is the body of an ordinary chat request without the model field (the model goes next to operation). Streaming (stream) is not supported in jobs: use POST /v1/chat/completions for it. Paid tools and non-text input are refused just as in ordinary chat. The Idempotency-Key header works as everywhere. To avoid polling the state, add webhook_url: when the job ends, we send a notification to that address (webhooks).

The answer is 202, and the Location header points to the state:

{
  "id": "req_8fK2xQ1mZpVwT9sJdL4nAg",
  "object": "job",
  "operation": "chat.completions",
  "model": "op/openai/gpt-4o-mini",
  "status": "running",
  "status_url": "https://api.6io.io/v1/jobs/req_8fK2xQ1mZpVwT9sJdL4nAg",
  "result_url": "https://api.6io.io/v1/jobs/req_8fK2xQ1mZpVwT9sJdL4nAg/result"
}

The job ID equals X-Sixio-Request-Id, so its money is visible in GET /v1/requests/{id} as well. If there is no free place, the answer comes at once (429): the job does not wait for one. While the service restarts, new jobs get 503 with Retry-After.

State

GET /v1/jobs/{id} returns status:

status Meaning
running the job is in progress
succeeded done, the result can be collected
failed not done, the reason is in error, no money is charged
unknown the provider did not confirm the outcome (a dropped connection, overload): there is no result, the money is checked and closed later

The billing field holds the state of the money and the charged amount in credits.

The result

GET /v1/jobs/{id}/result returns an ordinary chat answer. Reading starts nothing and charges nothing.

  • While the job is running, the answer is 202 with a link to the state and Retry-After.
  • The result is kept for a limited time (a day by default). Collect it in that time: after that, 410 result_expired.
  • For failed and unknown the answer is 409 with the code job_failed or job_outcome_unknown.
  • Sometimes the outcome was unknown and the check showed that the provider did the work. The job becomes succeeded and is paid for, but we have no answer: 409 result_unavailable.
  • An answer larger than 4 MB is also paid for but not stored: 409 result_too_large. Send such requests as an ordinary POST /v1/chat/completions.
  • If the result cannot be read for the moment, the answer is 503 with Retry-After: read again.

Cancel

Jobs cannot be cancelled: a chat cannot be cancelled once it is sent to the provider, and closing the connection does not stop it.

Money

As in ordinary chat: a reserve before the start, a charge by the actual cost after the answer.

  • The provider refused because of your request: the reserve is returned.
  • The provider refused because of the request rate (429) or could not be reached: no work was done, the reserve is returned, and the job ends with the error upstream_busy. You can send it again.
  • The outcome is unknown (a timeout, 5xx, a drop after sending): the reserve stays while we check the cost. A paid request is not sent again. The same happens to a job that did not finish within the provider's timeout, for example when the service restarts.

What to do on failures is in Retries and failures.