EN ZalogujOtwórz Studio
Wersja podglądowa. Katalog modeli, ceny, kalkulator i dokumentacja działają. Generowanie uruchomimy po starcie serwisu.

Zadania

Dokumentacja: spis stron

Zadanie powstaje przy każdym wywołaniu POST /v1/generate. Jego stan odczytujesz przez GET /v1/tasks/{id} - w trakcie zobaczysz status, a po zakończeniu listę plików i końcowy koszt.

Wywołanie

bash
curl https://kadraris.com/v1/tasks/task_8f2k... \
  -H "Authorization: Bearer $KADRARIS_API_KEY"

Nie musisz składać adresu sam - odpowiedź z /v1/generate ma gotowy link w polu poll_url.

Co zwraca serwer

json
{
  "id": "task_8f2k...",
  "status": "succeeded",
  "model": "seedance-2.5",
  "output": [
    { "type": "video", "url": "https://...",
      "duration": 5, "width": 1280, "height": 720 }
  ],
  "cost": { "amount": "3.10", "currency": "PLN" },
  "error": null,
  "created_at": "2026-09-27T10:15:02Z",
  "completed_at": "2026-09-27T10:16:41Z"
}
PoleTypZawartość
idstringIdentyfikator zadania
statusstringqueued, running, succeeded lub failed
modelstringIdentyfikator modelu
outputarrayPliki z wynikiem; puste, dopóki nie ma succeeded
costobject{amount, currency} - ile pobraliśmy; 0 przy failed
errorobject lub null{type, message}, gdy zadanie się nie udało
created_atstringCzas utworzenia w ISO 8601
completed_atstring lub nullCzas zakończenia w ISO 8601

Cykl życia zadania

StatusCo oznaczaStan końcowy
queuedZadanie przyjęte, czeka w kolejce; środki już zamrożonenie
runningModel pracujenie
succeededWynik gotowy, pobrana kwota z costtak
failedModel nie dał rady; blokada zdjęta, koszt 0tak

Pola w output

PoleDlaZawartość
typekażdego plikuimage, video lub audio
urlkażdego plikuLink do pobrania, ważny ograniczony czas
width, heightobrazu i wideoWymiary w pikselach
durationwideo i audioDługość w sekundach

Tak wygląda zadanie, które się nie powiodło:

json
{
  "id": "task_3xq1...",
  "status": "failed",
  "model": "kling-3.0",
  "output": [],
  "cost": { "amount": "0.00", "currency": "PLN" },
  "error": { "type": "upstream_error",
    "message": "The model could not complete this request." },
  "created_at": "2026-09-27T10:20:00Z",
  "completed_at": "2026-09-27T10:21:12Z"
}

Pętla odpytywania

Pytaj o zadanie co kilka sekund i kończ, gdy status jest końcowy. Obraz zwykle zamyka się w kilku sekundach, wideo w kilku minutach, więc odstęp między pytaniami wydłużaj stopniowo.

python
import os, time, requests

API = "https://kadraris.com/v1"
HEADERS = {"Authorization":
           f"Bearer {os.environ['KADRARIS_API_KEY']}"}

def wait_for_task(task_id, timeout=900):
    delay, deadline = 2, time.time() + timeout
    while time.time() < deadline:
        task = requests.get(f"{API}/tasks/{task_id}",
                            headers=HEADERS, timeout=30).json()
        if task["status"] in ("succeeded", "failed"):
            return task
        time.sleep(delay)
        delay = min(delay * 1.5, 15)  # najwyżej co 15 s
    raise TimeoutError(f"{task_id}: brak wyniku po {timeout} s")

task = requests.post(
    f"{API}/generate",
    headers=HEADERS,
    json={"model": "kling-3.0",
          "input": {"prompt": "A lighthouse beam sweeping fog",
                    "duration": 5}},
    timeout=30,
).json()

done = wait_for_task(task["id"])
print(done["status"], done["cost"], done["output"] or done["error"])
javascript
const API = "https://kadraris.com/v1";
const headers = {
  Authorization: `Bearer ${process.env.KADRARIS_API_KEY}`,
};
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function waitForTask(id, timeoutMs = 900_000) {
  let delay = 2000;
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const res = await fetch(`${API}/tasks/${id}`, { headers });
    const task = await res.json();
    if (task.status === "succeeded" || task.status === "failed") {
      return task;
    }
    await sleep(delay);
    delay = Math.min(delay * 1.5, 15000);
  }
  throw new Error(`${id}: wciąż bez wyniku`);
}

const res = await fetch(`${API}/generate`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({
    model: "kling-3.0",
    input: { prompt: "A lighthouse beam sweeping fog", duration: 5 },
  }),
});
const started = await res.json();
const done = await waitForTask(started.id);
console.log(done.status, done.cost, done.output ?? done.error);

Kiedy zadań jest dużo albo trwają długo, wygodniej przejść na webhooki i w ogóle nie odpytywać.

Zapis plików u siebie

Adresy z output po czasie wygasają. Ściągnij pliki, które mają przetrwać, i przechowuj je we własnym magazynie.

python
import pathlib

def download_outputs(task, folder="out"):
    ext = {"image": "png", "video": "mp4", "audio": "mp3"}
    out = pathlib.Path(folder)
    out.mkdir(exist_ok=True)
    paths = []
    for i, item in enumerate(task["output"]):
        path = out / f"{task['id']}_{i}.{ext[item['type']]}"
        with requests.get(item["url"], stream=True,
                          timeout=120) as r:
            r.raise_for_status()
            with open(path, "wb") as f:
                for chunk in r.iter_content(1 << 20):
                    f.write(chunk)
        paths.append(path)
    return paths
javascript
import { writeFile, mkdir } from "node:fs/promises";

async function downloadOutputs(task, folder = "out") {
  await mkdir(folder, { recursive: true });
  for (const [i, item] of task.output.entries()) {
    const res = await fetch(item.url);
    const buf = Buffer.from(await res.arrayBuffer());
    await writeFile(`${folder}/${task.id}_${i}`, buf);
  }
}

W przykładzie rozszerzenie wynika tylko z typu pliku. Jeżeli zależy ci na dokładnym formacie, sprawdź nagłówek Content-Type w odpowiedzi przy pobieraniu.

Błędy tego endpointu

Koderror.typeSytuacja
401authentication_errorKlucz błędny albo go brak
404not_foundZadania nie ma albo należy do innego konta

Wszystkie kody: Błędy.