Models & modalities
Discover models and use embeddings, speech and transcription.
GET https://api.roar-ai.com/v1/models returns the catalogue your key can use — and it is the answer, not this page. Model names change as the catalogue does; a name written into a guide is a name that goes stale.
Each entry lists its roar_modalities, the request types it serves:
| Modality | Endpoint | In the catalogue today |
|---|---|---|
chat | POST /v1/chat/completions | Yes — most of the catalogue |
embedding | POST /v1/embeddings | Yes |
tts | POST /v1/audio/speech (text to audio bytes) | Not yet — ask us if you need one |
stt | POST /v1/audio/transcriptions (multipart audio upload, max 50MB) | Not yet — ask us if you need one |
image | POST /v1/images/generations (prompt to images, billed per image) | Not yet — ask us if you need one |
The endpoints are live; the last three have nothing published behind them yet. GET /v1/models is what settles it for your account — if a modality returns no models there, that request type has nowhere to go and will answer 404 model_not_found. Tell us what you need and we will add it.
Cheaper ways to run a model
Each entry also tells you which discounted tiers it supports and what they cost, so you can decide before building around one:
{
"id": "claude-haiku-4-5",
"roar_modalities": ["chat"],
"roar_batch": true,
"roar_pricing": {
"batchInputPer1M": 0.575,
"batchOutputPer1M": 2.875,
"cachedInputPer1M": 0.115,
"cacheWriteInputPer1M": 1.4375
}
}
| Field | Meaning |
|---|---|
roar_batch | The model can be sent to batch — roughly half price, results within 24h. |
cachedInputPer1M | Rate for prompt tokens served from cache. Applied automatically when a prompt repeats a long prefix; no flag to set. |
cacheWriteInputPer1M | What it costs to write the cache the first time, where a model charges for that. Absent means writes are free. |
batchInput/OutputPer1M | The batch rate, when roar_batch is true. |
priorityInput/OutputPer1M | Rate when a request sets "service_tier": "priority". Asking for it on a model without one returns 400. |
flexInput/OutputPer1M | Rate when a request sets "service_tier": "flex" — cheaper, and may queue behind standard traffic. Still answers on the same request, unlike batch. |
An absent key means no such rate is offered, and nothing is silently substituted — cache hits simply bill at the normal input rate.
Rates are in USD per million tokens and hold until we republish them. All prices are the same for every account.
Embeddings
Turn text into vectors for search and similarity. Same call shape as any OpenAI-compatible client:
emb = client.embeddings.create(
model="bge-m3", # whichever embedding model GET /v1/models lists for you
input=["first passage", "second passage"],
)
print(len(emb.data[0].embedding))
Speech and transcription
The endpoints are OpenAI-compatible and take the usual shape — POST /v1/audio/speech for text to audio, POST /v1/audio/transcriptions for a multipart upload back to text:
curl https://api.roar-ai.com/v1/audio/speech \
-H "Authorization: Bearer roar_live_..." \
-H "Content-Type: application/json" \
-d '{"model": "<a tts model from /v1/models>", "input": "Hello there", "voice": "alloy"}' \
--output hello.mp3
curl https://api.roar-ai.com/v1/audio/transcriptions \
-H "Authorization: Bearer roar_live_..." \
-F file=@meeting.mp3 \
-F model="<an stt model from /v1/models>"
No speech or transcription model is published yet, so these calls have nothing to name today. The samples are here because the endpoints are real and the shape will not change — get in touch if you need one and we will publish it.
How a model is served
You never pick a server, and neither does the request. Each model in the catalogue is served one chosen way, and it keeps being served that way — the same model name gives you the same behaviour on every call.
That is a deliberate promise rather than an implementation detail. A model whose serving changed from request to request would change with it: a parameter accepted on one call and rejected on the next, prompt caching that works some of the time, a max_tokens ceiling that moves. Anything you build on top has to be built for the worst case. Fixing how a model is served removes that whole class of surprise.
It is not a single point of failure. If the chosen path is unhealthy we fail over automatically and the request still succeeds; what does not happen is picking a different one because it was momentarily cheaper or quicker. Cost is settled when we set a model's published price — not per request, out of your control, and never by changing what you get.
Nothing to configure, and nothing you can set per request. If your account keeps traffic inside a region, a model with no route there returns 404 no_regional_route rather than being served from outside it — see the error reference.