PL Log inOpen Studio
Preview version. Model catalog, prices, calculator and docs are live. Generation goes live at launch.

Models

Docs: every page

You can read the model catalog without any key. GET /v1/models and GET /v1/models/{id} are public and give you model ids, today's prices and, for media models, the input schema that /v1/generate checks against. The models page on the site is built from the same data.

Listing the catalog

http
GET https://kadraris.com/v1/models
Query parameterAllowed valuesEffect
categoryimage, video, audio, chat, toolReturn only one category
currencyUSD, PLNShow prices in this currency
bash
curl "https://kadraris.com/v1/models?category=video&currency=USD"
python
import requests

models = requests.get(
    "https://kadraris.com/v1/models",
    params={"category": "video", "currency": "USD"},
    timeout=30,
).json()["data"]

for m in models:
    print(m["id"], m["pricing"]["display"])
javascript
const res = await fetch("https://kadraris.com/v1/models?category=video&currency=USD");
const { data } = await res.json();
for (const m of data) console.log(m.id, m.pricing.display);

A trimmed response follows. The amounts were valid on October 2, 2026; a live call shows the current ones.

json
{
  "object": "list",
  "data": [
    {
      "id": "seedance-2.5",
      "object": "model",
      "name": "Seedance 2.5",
      "vendor": "ByteDance",
      "category": "video",
      "modes": ["text-to-video", "image-to-video", "first-last-frame", "reference-to-video", "video-edit", "video-extend"],
      "pricing": {
        "unit": "second",
        "amount": "0.58701",
        "currency": "USD",
        "display": "$0.587 / second",
        "variants": [
          { "resolution": "480p", "amount": "0.2609" },
          { "resolution": "720p", "amount": "0.58701" },
          { "resolution": "1080p", "amount": "1.01608" }
        ]
      }
    }
  ]
}

Schemas are left out of the list to keep it small. Request a single model with GET /v1/models/{id} to get input_schema.

Fields of a model

FieldTypeContent
idstringThe value to send as model; it does not change
namestringHuman-readable name
vendorstringThe company behind the model
categorystringimage, video, audio, chat or tool
objectstringAlways the string model
modesarrayWhat the model can do (see below)
pricingobjectPrice data; its shape differs between media and chat
input_schemaobjectAccepted input parameters; media models only, single-model endpoint only
context_window, max_output_tokens, anthropic_compatiblenumber, number, booleanPresent on chat models

Reading modes

modes tells you which jobs a model handles, which helps you shortlist models before looking at their schemas. Values you may meet:

  • text-to-image, text-to-video - output from a text prompt only;
  • image-to-image, image-edit, inpainting - changes to an image sent in image_urls;
  • image-to-video - a still image, sent as image_url, becomes the opening frame of a clip;
  • first-last-frame - a clip that moves from one given frame to another;
  • reference-to-video, multi-image-reference - output guided by reference images or clips;
  • video-edit, video-extend - changing or lengthening a clip you supply;
  • lyrics-to-music - a song built from lyrics;
  • stem-separation, vocal-isolation - splitting audio into separate tracks;
  • chat - a conversational model.

You never send a mode in the request. The mode follows from the input fields you fill in: for example, a model with image-to-video animates a picture once you pass image_url.

pricing on media models

FieldContent
unitThe thing you pay for, such as one image or one second of video
amountUnit price as a decimal string
currencyUSD or PLN
displayFormatted text you can show to users, e.g. $0.587 / second
variantsUnit price for each value of the parameter that changes the price, often resolution; empty if there is only one price
vat_includedtrue on PLN prices, which contain 23% VAT; missing on USD

pricing on chat models

FieldContent
input_per_mtokCost of one million input tokens
output_per_mtokCost of one million output tokens
currencyUSD or PLN
vat_includedtrue on PLN prices

PLN prices always include 23% VAT. A few current examples: GPT Image 2.5 $0.05 per image, FLUX.2 [pro] from $0.0688 per image, Veo 3.1 (Quality) from $2.53 per video, Claude Opus 5.5 $3.78 / $18.90 per 1M tokens.

One model and its schema

bash
curl https://kadraris.com/v1/models/seedance-2.5
python
model = requests.get("https://kadraris.com/v1/models/seedance-2.5", timeout=30).json()
print(model["input_schema"])
javascript
const model = await (await fetch("https://kadraris.com/v1/models/seedance-2.5")).json();
console.log(model.input_schema);

Ask for an id that does not exist and you get 404 not_found.

How input_schema works

The schema lists every parameter /v1/generate will take inside input, written in the style of JSON Schema. Here is a shortened example; always check the live schema for actual values:

json
{
  "type": "object",
  "properties": {
    "prompt":         { "type": "string" },
    "duration":       { "type": "integer", "minimum": 4, "maximum": 10, "default": 5 },
    "resolution":     { "type": "string", "enum": ["480p", "720p"], "default": "720p" },
    "aspect_ratio":   { "type": "string", "enum": ["16:9", "9:16", "1:1"], "default": "16:9" },
    "image_url":      { "type": "string" },
    "generate_audio": { "type": "boolean", "default": false }
  },
  "required": ["prompt"]
}
KeywordWhat it tells you
typestring, integer, number, boolean or array
enumThe complete set of allowed values
minimum, maximumLowest and highest allowed number, both included
defaultWhat the server uses if you skip the field
requiredFields you must always send

The server does not tolerate anything outside the schema. Extra fields, wrong types, values not in enum and numbers out of range all produce 422 invalid_request. In that case no task exists and nothing is reserved on your balance.

Validating on your side first

python
def build_input(schema: dict, **values) -> dict:
    props = schema.get("properties", {})
    unknown = set(values) - set(props)
    if unknown:
        raise ValueError(f"unknown fields: {unknown}")
    missing = [f for f in schema.get("required", []) if f not in values]
    if missing:
        raise ValueError(f"missing fields: {missing}")
    for name, value in values.items():
        rule = props[name]
        if "enum" in rule and value not in rule["enum"]:
            raise ValueError(f"{name} must be one of {rule['enum']}")
        if "minimum" in rule and value < rule["minimum"]:
            raise ValueError(f"{name} must be >= {rule['minimum']}")
        if "maximum" in rule and value > rule["maximum"]:
            raise ValueError(f"{name} must be <= {rule['maximum']}")
    return values

schema = requests.get("https://kadraris.com/v1/models/seedance-2.5", timeout=30).json()["input_schema"]
payload = {"model": "seedance-2.5", "input": build_input(schema, prompt="Fog over a harbor", duration=5)}

The API will run the same checks regardless. Doing them in your app lets you show users a clear message before any request is sent.

Working out the cost in advance

  • Media: unit price multiplied by the number of units, for instance seconds of video times the per-second rate. /v1/generate returns the precise number as estimated_cost and reserves it until the task ends.
  • Chat: take the token counts from usage, multiply them by input_per_mtok and output_per_mtok, and divide by 1,000,000.

See Billing for the rest.