Search

↑↓ to move↵ to openesc to closetop 6 documentation results

Book a demoTry TokenTriage

In development · Explore the product preview. Join the launch list or book a walkthrough.

Browse docs

Embeddings, rerank, images and audio

Configure the providers that serve one surface each, from embeddings to image edits, and read the three non-token units their rows bill in.

How-to guideLast updated

On this page

Most of a gateway’s traffic is chat, and most of its documentation follows. But a retrieval pipeline calls embeddings and rerank far more often than it calls a chat model, and an image or audio pipeline never calls one at all. Those calls cost money that belongs in the same total.

Fifteen of the 95 built-in provider descriptors declare no chat endpoint. This page covers the earlier specialist set; fireworks_ai_embeddings and vertex_ai_embedding are also listed in the current provider reference. Where a test gates one of these descriptors’ endpoints, the generated provider matrix names it: the test drives a request through the descriptor against a mock shaped like that provider and asserts the ledger row’s own provider and endpoint stamps. The verification is against mocks, not the providers’ live endpoints. Three of the eleven, black_forest_labs, fal_ai and runwayml, carry no gated cell at all; the matrix prints declared (no e2e gate) against them and calls that not a support claim, which is worth knowing before you put one of the three in front of production traffic.

They are configured like any other upstream, and what changes is the unit on the row.

Some of them answer later

Seven descriptors take a job and answer out of band: replicate, fal_ai, black_forest_labs, runwayml, stability, assemblyai and soniox. Six answer only that way; stability answers 15 of its 17 operations inside the call and polls for the other two.

A job is two rows, not one. The submit lands on the ledger immediately, terminal and unpriced, with the typed reason settlement_pending. A settlement companion row arrives minutes later, joined by req_id, and its figure replaces the pending zero rather than adding to it. Turning the plane on is one key, and it is off unless you say otherwise:

jobs:
  enabled: true

Your client still speaks the provider’s own async contract: take the job id off the row and poll the provider through the gateway. Providers that take a job and answer later is where that mechanism is explained, including what happens to a job nobody ever answers.

Embeddings

Fifteen descriptors serve /v1/embeddings. Most are chat providers that also carry priced embedding models; one, voyage, exists for retrieval and nothing else.

upstreams:
  voyage:
    provider: voyage
    base_url: https://api.voyageai.com   # host only — your client already sends /v1
    api_key_env: VOYAGE_API_KEY

Embeddings bill in tokens, like chat, with one difference: there is no output. The rate applied is the input rate, and the output rate is zero.

PREFIX   MODEL      ENDPOINT    RESULT  KEY                       RATE
voyage   voyage-3   embeddings  PRICED  voyage/voyage/voyage-3    in=$0.06/M
openai   gpt-4o     embeddings  UNPRICED                          endpoint_unpriced

The second line is worth noticing. gpt-4o has a rate, but not one that serves the embeddings endpoint, so the answer is endpoint_unpriced rather than the chat rate applied to an embedding call. The endpoint is part of the lookup, not decoration on it.

The full list of fifteen is in endpoints and cost shapes.

Rerank

Three descriptors serve /v1/rerank: jina_ai, voyage and novita.

upstreams:
  jina:
    provider: jina_ai
    base_url: https://api.jina.ai
    api_key_env: JINA_API_KEY

Rerank bills in tokens over the documents you submitted.

Descriptor Model in the catalog Input rate
novita baai/bge-reranker-v2-m3 $0.010 / M
jina_ai jina-reranker-v2-base-multilingual $0.018 / M
voyage rerank-2 $0.050 / M

Cohere serves rerank too, and is not claimed here. Its pricing is per search unit rather than per token, and the vendored catalog carries no per-token rate for it, so a Cohere rerank call would have to be either unpriced or guessed. It is left out rather than guessed.

Images

Seven descriptors serve /v1/images/generations: openai, aiml, recraft, stability, fal_ai, black_forest_labs and runwayml. Three of those also serve /v1/images/edits: openai, stability and black_forest_labs. Both surfaces bill per image returned.

upstreams:
  recraft:
    provider: recraft
    base_url: https://external.api.recraft.ai
    api_key_env: RECRAFT_API_KEY

  stability:
    provider: stability
    base_url: https://api.stability.ai
    api_key_env: STABILITY_API_KEY

recraft is image-only on the OpenAI wire and answers in the call. stability speaks its own /v2beta stable-image wire: multipart in, image bytes out, and one path (generate/sd3) serving seven catalog rows priced from $0.035 to $0.065. It tells those seven apart by reading the model field out of the multipart form, which is a third place a model string can live beside the URL path and the URL query.

Where a model carries a flat per-image rate, it is used directly: recraftv3 is $0.04 per image and aiml‘s dall-e-3 entry is $0.052. Where the wire reports no quantity at all, as Stability’s and Black Forest Labs’ do, the row bills one image per request and says so rather than inferring a count.

Text-to-speech

Three descriptors serve /v1/audio/speech: openai, elevenlabs and runwayml. ElevenLabs speaks its own wire, with the voice id in the URL path and opaque binary audio coming back.

upstreams:
  elevenlabs:
    provider: elevenlabs
    base_url: https://api.elevenlabs.io
    api_key_env: ELEVENLABS_API_KEY

Speech bills per character of the text you sent, which means the figure is known from the request and does not depend on the response at all.

Descriptor Model Rate
openai tts-1 $0.000015 / character
elevenlabs eleven_multilingual_v2 $0.00018 / character

The response body is audio and is relayed byte for byte. Nothing parses it, and nothing needs to.

Speech-to-text

Four descriptors serve /v1/audio/transcriptions: openai, deepgram, assemblyai and soniox. Deepgram answers in the call, with the model in the URL query and a Token prefix on the credential; AssemblyAI and Soniox upload, submit and poll.

upstreams:
  deepgram:
    provider: deepgram
    base_url: https://api.deepgram.com
    api_key_env: DEEPGRAM_API_KEY

Transcription bills per second of audio, taken from the provider’s own response metadata.

Descriptor Model Rate
deepgram nova-3 $0.00007167 / second
openai whisper-1 $0.0001 / second
assemblyai best $0.00003333 / second
soniox stt-async-v4 no rate in the catalog

That direction matters. Because the duration comes from the response, a reply that omits it produces no cost figure rather than an estimate from the file size.

AssemblyAI’s two catalog rows are its deprecated speech_model values, best and nano. A present-day request naming a universal-* model settles model_unknown, with the measured seconds still on the row, because no primary AssemblyAI document maps today’s ids onto those two.

Covered is not priced

Binding a provider means its traffic is routed, governed, journaled, polled and settled. It does not mean every model produces a dollar, and the gap between those two claims is widest here.

soniox is the mirror image, and the wire is not the reason. Soniox reports a measured audio duration in milliseconds, which is what a per-second rate consumes, and the driver settles with it and infers nothing. Both of its catalog rows carry no rate at all, so the key resolves and then has nothing to apply, which is what unit_missing means. One per_second rate on those two rows would make it priceable with no driver change: a pricing-data gap rather than a driver gap.

Six image rows measure their quantity and then decline to bill it, because the catalog’s unit is not the vendor’s unit. Five fal models carry a per_image rate while fal publishes them per megapixel or per quality tier, and Runway’s gen4_image carries a flat rate for the 720p tier while Runway charges more for 1080p with no tier derivable from the wire.

Model The catalog says The vendor publishes
fal-ai/flux/schnell per_image: 0.003 $0.003 per megapixel
fal-ai/flux-pro/v1.1 per_image: 0.04 $0.04 per megapixel
fal-ai/stable-diffusion-v35-medium per_image: 0.0398 $0.02 per megapixel
fal-ai/recraft/v3/text-to-image per_image: 0.0398 $0.04 per image, $0.08 for a vector style
fal-ai/ideogram/v3 per_image: 0.06 $0.03 turbo, $0.06 balanced, $0.09 quality
runwayml/gen4_image per_image: 0.05 5 credits at 720p, 8 credits at 1080p

The job still succeeds and the row still lands; what is withheld is the number, and the row carries the vendor’s own published wording in its error field so you can price those calls yourself. Do not read a missing dollar there as a free call. The withholding list is matched exactly rather than by prefix, so a sibling id one character different, fal-ai/flux-pro/v1.1-ultra, prices normally. Runway’s other unpriced row is a different problem. The vendored catalog carries a key called runwayml/eleven_multilingual_v2, which is the same model name the speech table above lists under elevenlabs/ and at a different rate. It bills per character, and Runway’s task object carries no character count anywhere, so this is a missing quantity rather than a mismatched unit.

What can go wrong

Symptom Cause Fix
endpoint_unpriced the model has rates, but not for this endpoint use a model the provider prices for that surface
unit_missing on an image call no size or quality in the request, or a withheld unit send the dimensions your provider expects; check the row’s error field
a submit row with no settlement_pending and no later row the job plane is off, so nothing recognises the submission set jobs.enabled: true and restart
a transcription row with no cost the response carried no duration check the provider’s response shape
an embeddings call is not routed only chat, responses and embeddings are routable, and no rule matched confirm the tier targets an embeddings-capable upstream
a rerank tier fails validation with allow_cross_dialect on, a tier’s upstream must serve chat point the tier at a chat-capable upstream
What is not claimed here

AWS Polly for audio speaks a bespoke wire with no verifiable contract, and is published as refused rather than pending. Cohere’s rerank is left out for the reason above. Video generation has no endpoint kind at all, so no descriptor can declare one: Runway is bound for images and speech only.

The coverage page carries the full uncovered set with the blocker for each, and it records the class that once held these image and audio job providers, now standing at zero.