Skip to content
kenari.

Models and pricing

List every model you can call, with what it can do and what it costs. The list is public, so you do not need an API key, and it changes over time, so read it from the endpoint instead of hardcoding ids.

GET /v1/models

ParameterTypeRequiredDescription
modalitystringNoList one specialized kind of model instead of the default list. One of embedding, rerank, moderation or systemone. See Filter by modality.

Without modality, the list holds chat, image, text to speech, transcription, music and video models. It does not hold embedding, rerank, moderation or System One models. Each entry’s endpoints says which API it serves, so a tool that only wants chat models should keep the entries whose endpoints include chat. Music models are in the default list too, and there is no ?modality=music filter. The kenari/auto entry, when listed, has no endpoints, because the model that serves a request differs each time. A missing endpoints means no metadata is recorded, not that the model lacks a capability, so the examples below treat it as an empty list.

The response is an OpenAI-style list: {"object": "list", "data": [...]}. This is one entry:

{
"id": "step-3-7-flash",
"object": "model",
"owned_by": "stepfun",
"name": "step-3-7-flash",
"context_length": 262144,
"max_output_tokens": 65536,
"modalities": { "input": ["text", "image", "video"], "output": ["text"] },
"endpoints": ["chat"],
"protocols": ["openai-chat", "openai-responses", "anthropic-messages"],
"reasoning": true,
"reasoning_options": ["low", "medium", "high"],
"reasoning_toggle": false,
"tool_call": true,
"pricing": {
"input": 4200000000,
"output": 24000000000,
"cache_read": 840000000,
"cache_write": null,
"free": false,
"currency": "IDR",
"unit": "micro_idr_per_1m_tokens"
},
"pricing_lines": [
{ "endpoint": "chat", "billable": "input", "unit": "token_1m", "variant": null, "micro_idr": 4200000000 },
{ "endpoint": "chat", "billable": "output", "unit": "token_1m", "variant": null, "micro_idr": 24000000000 },
{ "endpoint": "chat", "billable": "cache_read", "unit": "token_1m", "variant": null, "micro_idr": 840000000 }
],
"sunset_at": null
}

A field kenari has no value for is left out instead of being set to null. id, object, owned_by, name and sunset_at are always there. The rest depends on the kind of entry, as the tables below show.

FieldTypeDescription
idstringThe id to send as model.
objectstringAlways model.
owned_bystringThe vendor that makes the model, for example anthropic.
namestringA display name. Every entry has one. When a model has no separate display name, name is the same as id.
context_lengthintegerThe context window in tokens.
max_input_tokensintegerThe most input tokens one request can carry, when the model limits input below its context window. A request with a larger input is refused with context_length_exceeded. Left out when the context window is the only limit. Not on ?modality= entries.
max_output_tokensintegerThe longest output the model can produce in one response, in tokens. Left out when unknown, which means nothing is recorded, not that the model has no limit. Not on ?modality= entries.
modalitiesobjectinput and output arrays. The values are text, image, pdf, file, audio and video. pdf means the model reads PDFs itself. Every chat model lists file, because kenari reads attached documents for any model. Only the native engine depends on the model reading files itself. See Images and files as input.
endpointsarrayThe APIs the model serves: chat, images, videos, audio_speech, audio_transcription, music, embeddings, rerank, moderations or systemone.
protocolsarrayThe API formats you can call the model with: openai-chat for Chat completions, openai-responses for Responses and anthropic-messages for Messages. Only on chat models and kenari/auto, and every one of them lists all three. Left out on image, speech, video, music and ?modality= entries.
reasoningbooleanWhether the model produces reasoning. See Reasoning.
reasoning_optionsarrayThe levels reasoning_effort accepts for this model, such as low, medium and high.
supported_reasoning_levelsarraySame values as reasoning_options, in the field name some agent gateways read. Omitted when the model has no effort levels.
reasoning_togglebooleanPresent on entries of the default list, but not on ?modality= entries. true when you can switch reasoning on or off per request, false when you cannot.
tool_callbooleanWhether the model supports function calling. See Function calling.
pricingobjectThe price card. See Prices in the list.
pricing_linesarrayOne entry per billable item. Left out when the model has none, as on most :free models.
sunset_atinteger or nullThe time, in epoch seconds, when kenari plans to stop serving the model. null when none is planned.
modalitystringOnly on ?modality= results. The kind of model.

Most media fields below are left out when no value is recorded for the model. A missing field means nothing is recorded, not that the model has no limit.

FieldApplies toDescription
voicestext to speechVoice names, case sensitive. The first one is the default when a request has no voice.
formatstext to speech, musicAudio formats the model can return, such as mp3. The first one is the default when a request has no response_format. On a music model it also tells the two kinds of music model apart, see Music.
max_input_charstext to speechThe longest input the model accepts, in characters. A longer one returns 400.
max_prompt_charsmusicThe longest prompt, in characters.
max_lyrics_charsmusicThe longest lyrics, in characters.
max_duration_secsmusicThe longest song the model makes, in seconds. For information only, because you cannot request a length.
video_durationsvideoThe clip lengths you can request, in seconds.
video_resolutionsvideoThe resolutions you can request, such as 720p.
max_reference_imagesvideoThe most reference images one request can carry in input_images. 0 means the model takes none. Left out when no figure is published for the model, which does not mean it takes none. See Reference images.
video_extensionsvideotrue when the model can extend a clip through POST /v1/videos/extensions. Present only when true, and left out otherwise.

For how to use these values, see Text to speech, Music and Videos.

pricing and pricing_lines give prices in micro-Rupiah, which is Rupiah times 1,000,000. Divide by 1,000,000 to get Rupiah. In the example above, an input of 4200000000 is Rp 4,200 per 1 million tokens.

pricing fieldDescription
input, output, cache_read, cache_writeThe price per 1 million tokens. null when the model has no such price.
freetrue when the model costs nothing to call. Prices that are still shown on a free model are the list price of its paid version, and are not charged.
currency, unitAlways IDR and micro_idr_per_1m_tokens.

Models that are not priced per token, such as image, speech and video models, show 0 for input and output. Read their price from pricing_lines instead. Each line has these fields:

FieldDescription
endpointThe API the price belongs to, such as chat or audio_speech.
billableWhat is billed: input, output, cache_read, cache_write, input_audio, output_audio, output_image or output_video.
unittoken_1m for 1 million tokens, 1k_chars for 1,000 characters, second, image or song (music).
variantA tier of the price, such as a video resolution like 720p. null when there is none.
micro_idrThe price in micro-Rupiah for one unit.

A model with a sunset_at keeps being listed and served until that time. After it passes, the model leaves the list. Requests for its id are then served by a successor model when kenari has set one, and rejected with model_not_found when it has not. If you keep a copy of the list, check this field so you can move to another model before the date. Scheduled retirements also appear on Model changes.

Accounts with a verified email that called a model in the last 30 days get an email when its retirement is scheduled, and again a day before it retires.

This header is present only when you call a model that kenari has retired and that model has a successor. The request is served by the successor and billed at the successor’s price, the response model field names the successor, and the header records the forward as <model you sent>-><model that served>:

x-kenari-model-forwarded: deepseek-v4-flash->deepseek-v4-1-flash

It appears on Chat completions, Messages, Responses and the media endpoints (images, audio, speech, transcription, music, video, embeddings, rerank and moderations). Browsers cannot read it from JavaScript, because CORS does not expose it. Server-side clients and SDKs can.

Embedding, rerank, moderation and System One models are listed only when you ask for them with ?modality=.

modalityListsExample idsUsed by
embeddingEmbedding modelsbge-m3, text-embedding-3-smallEmbeddings
rerankRerank modelsbge-reranker-baseRerank
moderationModeration modelsids from this callModerations
systemoneSystem One modelsclef:freeSystem One
Terminal window
curl "https://kenari.id/v1/models?modality=embedding"

The entries carry id, object, owned_by, name, sunset_at, modality and pricing, and endpoints, context_length and pricing_lines when recorded. They have no reasoning_toggle, and pricing has only input, free, currency and unit, with pricing.input holding the price per 1 million tokens. A modality value that is not one of the four, including an empty one, returns 400.

{
"error": {
"message": "unknown modality 'foo'. Accepted values: embedding, rerank, moderation, systemone.",
"type": "bad_request",
"param": null,
"code": "bad_request"
}
}

A model’s free version has the same id with a :free suffix, is listed with pricing.free set to true, and costs nothing. See Free models.

Terminal window
curl https://kenari.id/v1/models
import requests
models = requests.get("https://kenari.id/v1/models").json()["data"]
chat_models = [m["id"] for m in models if "chat" in m.get("endpoints", [])]
print(chat_models)
const response = await fetch("https://kenari.id/v1/models");
const { data } = await response.json();
const chatModels = data.filter((m) => (m.endpoints ?? []).includes("chat")).map((m) => m.id);
console.log(chatModels);

GET /api/public/pricing is a second public feed, made for price pages. It needs no key and returns {"items": [...], "usd_idr_rate": ..., "free_tier": {...}}.

  • Each item has model, provider (the vendor), free, subscriber_only, endpoints, pricing_lines, input_modalities, output_modalities, sunset_at and upcoming_price, the next scheduled price change, or null when there is none.
  • The per-token prices are named price_in_micro_idr_per_1m, price_out_micro_idr_per_1m, price_cached_micro_idr_per_1m and price_cache_write_micro_idr_per_1m, and image_micro_idr_per_image is the price of one image. market_in_micro_idr_per_1m and market_out_micro_idr_per_1m hold a reference market price, only when kenari’s price is lower.
  • subscriber_only is true when only accounts with an active subscription can call the model. See Subscriptions.
  • It lists every model that is for sale, including the :free versions and older versions of a family. It leaves out embedding, rerank, moderation and System One models.
  • usd_idr_rate is the exchange rate in use, and free_tier describes what a free account gets. For free-tier limits, read Free models.

To find what you can call and what it costs, use GET /v1/models.

To see what changed over time, read Model changes.

StatusCodeWhen
400bad_requestmodality is not embedding, rerank, moderation or systemone.

The other errors are in Errors.

The table below is loaded live from GET /v1/models, so it shows what is billed today. Token prices are in Rupiah per 1 million tokens. Image, speech, video and the other models that are not priced per token have their own tables underneath, each with its unit. For how a request is billed, see How billing works.

Live model pricing

Loading prices...