Models
The model catalog is public: GET /v1/models and GET /v1/models/{id} work without an API key. Use them to list model ids, read current prices and fetch the input schema for /v1/generate. The same data powers the models page.
List models
GET https://jantaris.com/v1/models| Query parameter | Values | Description |
|---|---|---|
category | image, video, audio, chat, tool | Filter by category |
currency | USD, PLN | Currency of prices in the response |
curl "https://jantaris.com/v1/models?category=video¤cy=USD"import requests
models = requests.get(
"https://jantaris.com/v1/models",
params={"category": "video", "currency": "USD"},
timeout=30,
).json()["data"]
for m in models:
print(m["id"], m["pricing"]["display"])const res = await fetch("https://jantaris.com/v1/models?category=video¤cy=USD");
const { data } = await res.json();
for (const m of data) console.log(m.id, m.pricing.display);Response (shortened, amounts from the price list of October 2, 2026, the API returns current ones):
{
"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" }
]
}
}
]
}The list does not include input_schema. Only GET /v1/models/{id} returns the schema.
Model object
| Field | Type | Description |
|---|---|---|
id | string | Stable id you pass as model |
name | string | Display name |
vendor | string | Company that makes the model |
category | string | image, video, audio, chat or tool |
object | string | Always model |
modes | array | The model's working modes, described below |
pricing | object | Price, shape depends on category (below) |
input_schema | object | Parameters accepted in input (media models only, and only in GET /v1/models/{id}) |
context_window, max_output_tokens, anthropic_compatible | number, number, boolean | Chat models only |
The modes field
modes lists the modes the model works in. Use it to pick a model before you read input_schema. Example values:
text-to-image,text-to-video- generate from a prompt alone;image-to-image,image-edit,inpainting- edit an image passed inimage_urls;image-to-video- animate a still passed as the first frame (image_url);first-last-frame- video between a first and a last frame;reference-to-video,multi-image-reference- generate from reference images or clips;video-edit,video-extend- edit or extend an existing clip;lyrics-to-music- a song from lyrics;stem-separation,vocal-isolation- split a recording into tracks;chat- a chat model.
A mode describes what the model can do, it is not a request parameter. You pick it through input fields, for example passing image_url to a model with image-to-video animates the image.
Pricing for media models
| Field | Description |
|---|---|
unit | What one unit is, for example one image or one second of video |
amount | Price per unit as a decimal string |
currency | USD or PLN |
display | Ready-to-show text, for example $0.587 / second |
variants | Per-unit prices for each value of the parameter the price depends on (for example resolution). Empty when there is a single price |
vat_included | true for PLN prices (they include 23% VAT); absent for USD |
Pricing for chat models
| Field | Description |
|---|---|
input_per_mtok | Price per 1M input tokens |
output_per_mtok | Price per 1M output tokens |
currency | USD or PLN |
vat_included | true for PLN prices |
Prices in PLN include 23% VAT. Current prices for popular models: GPT Image 2.5 $0.0432 per image, FLUX.2 [pro] from $0.0688 per image, Veo 3.1 (Quality) from $2.53 per video, Claude Opus 5.5 $5.40 / $27.00 per 1M tokens.
Get one model
curl https://jantaris.com/v1/models/seedance-2.5model = requests.get("https://jantaris.com/v1/models/seedance-2.5", timeout=30).json()
print(model["input_schema"])const model = await (await fetch("https://jantaris.com/v1/models/seedance-2.5")).json();
console.log(model.input_schema);An unknown id returns 404 not_found.
Input schema
input_schema describes what /v1/generate accepts in input. It follows JSON Schema conventions. An abridged example (read the live schema for real values):
{
"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"]
}| Keyword | Meaning |
|---|---|
type | string, integer, number, boolean, array |
enum | Only these values are accepted |
minimum, maximum | Numeric range, inclusive |
default | Value used when you omit the field |
required | Fields that must be present |
Validation is strict. A field that is not in properties, a wrong type, a value outside enum or out of range returns 422 invalid_request and no task is created, so no funds are held.
Building a valid input in code
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://jantaris.com/v1/models/seedance-2.5", timeout=30).json()["input_schema"]
payload = {"model": "seedance-2.5", "input": build_input(schema, prompt="Waves at dusk", duration=5)}The server validates anyway. Checking on your side gives users clear messages before a request leaves your app.
Cost before you call
- Media: price per unit times units, for example seconds of video times the per-second price. The exact figure comes back as
estimated_costfrom/v1/generate, and that amount is held until the task finishes. - Chat: tokens from the
usagefield timesinput_per_mtokandoutput_per_mtok, divided by 1,000,000.
More in Billing.









