Generowanie
Obraz, klip wideo, piosenkę albo obróbkę audio zamawiasz jednym endpointem: POST /v1/generate. Serwer nie każe ci czekać na koniec pracy - od razu odsyła zadanie z kodem 202. Gotowy wynik dostaniesz na jeden z trzech sposobów: odpytując zadanie, dopisując do adresu ?wait=N albo przez webhook.
Budowa zapytania
POST https://kadraris.com/v1/generate
Authorization: Bearer sk-kd-...
Content-Type: application/json| Pole | Typ | Obowiązkowe | Do czego służy |
|---|---|---|---|
model | string | tak | Id modelu mediów, np. seedance-2.5, gpt-image-2.5, mureka-v9 |
input | object | tak | Ustawienia generacji, sprawdzane względem input_schema modelu |
webhook_url | string | nie | Adres, na który wyślemy POST po sukcesie albo porażce zadania |
| Parametr w adresie | Typ | Do czego służy |
|---|---|---|
wait | integer, 1-120 | Liczba sekund, przez które serwer wstrzyma odpowiedź w oczekiwaniu na koniec zadania |
Odpowiedź serwera
Gdy nie podasz wait albo zadanie nie skończy się w tym czasie, wraca 202 Accepted:
{
"id": "task_8f2k...",
"object": "task",
"status": "queued",
"model": "seedance-2.5",
"estimated_cost": { "amount": "16.9204", "currency": "PLN" },
"poll_url": "https://kadraris.com/v1/tasks/task_8f2k..."
}Kwota w tym przykładzie odpowiada zapytaniu z przykładu wideo niżej (Seedance 2.5, 5 sekund, 720p) według cennika z 2 października 2026 dla konta w złotówkach, z VAT. Bieżącą wartość zawsze podaje API w polu estimated_cost. Sposób liczenia:
- dla wideo rozliczanego sekundowo mnożysz stawkę za sekundę w danej rozdzielczości przez
duration, - stawki za sekundę dla każdej rozdzielczości są w
pricing.variantsodpowiedziGET /v1/models/{id}, - w przykładzie: stawka dla 720p razy 5 sekund.
Jeżeli dodasz ?wait=N i zadanie zamknie się w N sekund, dostaniesz 200 OK z zakończonym zadaniem - tym samym obiektem, który zwraca GET /v1/tasks/{id}. Zakończone nie znaczy udane: status może brzmieć succeeded albo failed, więc zawsze go sprawdzaj.
Pieniądze w trakcie zadania
- Przed startem na saldzie zamrażamy kwotę z
estimated_cost. Gdy środki dostępne (available) są niższe, dostajesz402 insufficient_balancei zadanie nie rusza. - Po
succeededpobieramy kwotę z polacosti rozliczamy blokadę. - Po
failedcała blokada wraca. Koszt wynosi 0.
Kwoty przychodzą jako tekst z walutą: PLN dla konta polskiego, USD dla globalnego. Więcej w Rozliczeniach.
Co wpisać w input
Każdy model ma swój schemat. Przed wysłaniem zapytania pobierz go z GET /v1/models/{id} (pole input_schema). Pole spoza schematu, zły typ albo wartość spoza zakresu dają 422 invalid_request, a komunikat wskaże, które pole jest nie tak.
Pola spotykane najczęściej (pojedynczy model może obsługiwać tylko część z nich):
| Rodzaj | Pola |
|---|---|
| Obraz | prompt, negative_prompt, aspect_ratio (1:1, 16:9, 9:16, 4:3, 3:4), num_images (1-4, wyłącznie tam, gdzie pokazuje je GET /v1/models/{id}), image_urls (edycja lub referencje), seed |
| Wideo | prompt, duration (w sekundach), resolution (480p, 720p, 1080p zależnie od modelu), aspect_ratio, image_url (klatka otwierająca), generate_audio |
| Audio i muzyka | lyrics (obowiązkowe w mureka-v9), prompt (opis stylu); duration oraz instrumental tylko tam, gdzie są w schemacie |
Czego nie podasz, to przyjmie wartość default zapisaną w schemacie.
Przykład: obraz w jednym wywołaniu
Obraz zwykle powstaje w mniej niż minutę, więc z ?wait=60 całą robotę załatwia pojedyncze zapytanie.
curl "https://kadraris.com/v1/generate?wait=60" \
-H "Authorization: Bearer $KADRARIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-2-pro",
"input": {
"prompt": "Packshot szklanej butelki oliwy na lnianym obrusie",
"aspect_ratio": "4:3"
}
}'import os, requests
API = "https://kadraris.com/v1"
HEADERS = {"Authorization":
f"Bearer {os.environ['KADRARIS_API_KEY']}"}
r = requests.post(
f"{API}/generate",
params={"wait": 60},
headers=HEADERS,
json={
"model": "flux-2-pro",
"input": {
"prompt": "Packshot szklanej butelki oliwy "
"na lnianym obrusie",
"aspect_ratio": "4:3",
},
},
timeout=130, # musi być dłuższy niż wait
)
r.raise_for_status()
task = r.json()
if task["status"] == "succeeded":
for item in task["output"]:
print(item["url"], item.get("width"), item.get("height"))
elif task["status"] == "failed":
print("nie wyszło:", task["error"])
else:
print("jeszcze się liczy:", task["poll_url"])const res = await fetch("https://kadraris.com/v1/generate?wait=60", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KADRARIS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "flux-2-pro",
input: {
prompt: "Packshot szklanej butelki oliwy na lnianym obrusie",
aspect_ratio: "4:3",
},
}),
});
const task = await res.json();
if (task.status === "succeeded") {
task.output.forEach((o) => console.log(o.url));
} else {
console.log(task.status, task.poll_url ?? task.error);
}Limit czasu w kliencie HTTP musi być dłuższy niż wait. W przeciwnym razie klient rozłączy się, zanim serwer zdąży odpowiedzieć.
Przykład: edycja istniejącego zdjęcia
Jeśli model przyjmuje obrazy wejściowe (sprawdź input_schema), podajesz je w image_urls:
curl "https://kadraris.com/v1/generate?wait=60" \
-H "Authorization: Bearer $KADRARIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana-pro",
"input": {
"prompt": "Przenieś produkt na plażę o zachodzie słońca",
"image_urls": ["https://example.com/produkt.jpg"]
}
}'Przykład: wideo z powiadomieniem
Klip liczy się dłużej niż obraz, więc tu lepiej zlecić zadanie i poczekać, aż Kadraris sam wyśle wynik na twój serwer.
curl https://kadraris.com/v1/generate \
-H "Authorization: Bearer $KADRARIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"input": {
"prompt": "Slow dolly shot through a neon-lit night market in the rain",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9"
},
"webhook_url": "https://twoj-serwer.example.com/kadraris-hook"
}'r = requests.post(
f"{API}/generate",
headers=HEADERS,
json={
"model": "seedance-2.5",
"input": {
"prompt": "Slow dolly shot through a neon-lit "
"night market in the rain",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9",
},
"webhook_url":
"https://twoj-serwer.example.com/kadraris-hook",
},
timeout=30,
)
task = r.json()
print(task["id"], task["estimated_cost"])const res = await fetch("https://kadraris.com/v1/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KADRARIS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "seedance-2.5",
input: {
prompt: "Slow dolly shot through a neon-lit night market in the rain",
duration: 5,
resolution: "720p",
aspect_ratio: "16:9",
},
webhook_url: "https://twoj-serwer.example.com/kadraris-hook",
}),
});
const task = await res.json();
console.log(task.id, task.estimated_cost);Za większość modeli wideo płacisz od sekundy materiału: Seedance 2.5 to od 1,51 zł za sekundę, Kling 3.0 to od 0,546 zł za sekundę. Veo 3.1 (Quality) wyceniamy za cały klip: od 14,61 zł za film (zobacz jednostki rozliczenia). Film ze zdjęcia zrobisz, dodając image_url jako klatkę otwierającą, o ile schemat modelu zna to pole.
Przykład: piosenka
curl https://kadraris.com/v1/generate \
-H "Authorization: Bearer $KADRARIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mureka-v9",
"input": {
"lyrics": "[Verse]\nKlatka po klatce składam ten dzień\n[Chorus]\nJeszcze jedno ujęcie, zanim zgaśnie flesz",
"prompt": "indie pop, bright guitars, upbeat drums, male vocal"
}
}'Mureka V9 śpiewa twój tekst, więc lyrics musi być wypełnione. Części utworu oznaczasz znacznikami [Verse] i [Chorus], a nowe linie w JSON-ie zapisujesz jako \n. Opcjonalne prompt opisuje brzmienie: gatunek, tempo, instrumenty, typ głosu. Parametrów duration i instrumental ten model nie ma. Płacisz za utwór: 0,88 zł za utwór.
Kody błędów
| Kod | error.type | Kiedy się pojawia |
|---|---|---|
| 401 | authentication_error | Klucz błędny albo nieobecny |
| 402 | insufficient_balance | Środki dostępne poniżej estimated_cost |
| 403 | permission_error | Klucz doszedł do limitu wydatków |
| 404 | not_found | Nie ma modelu o takim id |
| 422 | invalid_request | input niezgodny ze schematem |
| 429 | rate_limit | Więcej niż 60 zapytań na minutę na klucz (domyślnie) |
| 429 | rate_limit_error | 25 nieudanych generacji na koncie w 24 h; ile czekać, mówi Retry-After |
Porażka zadania, które już wystartowało, nie daje błędu HTTP. Zobaczysz ją jako status: "failed" z obiektem error (szczegóły w Zadaniach). Wszystkie kody: Błędy.























