Vision: Analyzing Images with AI
Send images to vision-capable models for analysis, description, and understanding. This example shows how to analyze an image from a URL using GPT-4o with high detail processing for better accuracy.Image Generation: Generating Images with AI
Generate images from text prompts using OpenAI-compatible image generation models.Basic Image Generation
Generate an image from a text prompt usingdall-e-3.
Audio Understanding: Analyzing Audio with AI
If your chat application supports text input, you can add audio input and output-just include audio in the modalities array and use an audio model, like gpt-4o-audio-preview.Audio Input to Model
Audio Output from Model
Text-to-Speech: Converting Text to Audio
Convert text into natural-sounding speech using AI voice models. This example demonstrates generating an MP3 audio file from text using the “alloy” voice. The result is returned as binary audio data.Speech-to-Text: Transcribing Audio Files
Convert audio files into text using AI transcription models. This example shows how to transcribe an MP3 file using OpenAI’s Whisper model, with an optional context prompt to improve accuracy.Advanced Vision Examples
Multiple Images
Send multiple images in a single request for comparison or analysis. This is useful for comparing products, analyzing changes over time, or understanding relationships between different visual elements.Base64 Images
Process local images by encoding them as base64 data URLs. This approach is ideal when you need to analyze images stored locally on your system without uploading them to external URLs first.Audio Configuration Options
Voice Selection for Speech Synthesis
OpenAI provides six distinct voice options, each with different characteristics:alloy- Balanced, natural voiceecho- Deep, resonant voicefable- Expressive, storytelling voiceonyx- Strong, confident voicenova- Bright, energetic voiceshimmer- Gentle, soothing voice
Audio Formats
Generate audio in different formats depending on your use case. MP3 for general use, Opus for web streaming, AAC for mobile apps, and FLAC for high-quality audio applications.Transcription Options
Language Specification
Improve transcription accuracy by specifying the source language. This is particularly helpful for non-English audio or when the audio contains technical terms or specific domain vocabulary.Response Formats
Choose between simple text output or detailed JSON responses with timestamps. The verbose JSON format provides word-level and segment-level timing information, useful for creating subtitles or analyzing speech patterns.Multimodal Embeddings
Bifrost supports multimodal embeddings — generating vector representations that capture text, images, audio, video, and documents together.POST /v1/embeddings accepts every shape it always did (a string, an array of strings, token arrays) plus a multimodal form where each entry in input is an array of typed parts. All the parts in one entry produce one vector.
Content parts
Every media part is the same object:
Validation runs before plugins and before the provider is called: each part must set exactly one modality, a media part must set exactly one of
data or url, and an empty entry returns 400.
Request parameters
These top-level fields apply to every entry unless an entry overrides them (see Per-Item Parameters):
Any other top-level field (for example Cohere’s
input_type, Nova’s embeddingMode, or Gemini’s embedContentConfig) is forwarded to the provider as-is.
encoding_format: "base64" works on every provider. Where the model has a native base64 output (OpenAI, Cohere Embed v4) it is forwarded; everywhere else Bifrost encodes the float vector as little-endian float32 base64, the same layout OpenAI uses.
Response fields
Each entry indata has index, object and embedding, plus three optional fields that are present only when a provider needs them:
Provider support
A part the target model cannot carry returns
400 naming the modality. Bifrost never drops a part silently.
Text Embedding (all providers)
The simplest form — pass a string or array of strings directly ininput:
Gemini
gemini-embedding-2-preview accepts text, image, audio, video and file (PDF) parts, in any combination, in one entry. gemini-embedding-001 is text-only.
file part type:
- Inline
datais sent asinlineData. - A
urlis sent asfileData.fileUri. The Gemini API only resolves Files API URIs (https://generativelanguage.googleapis.com/v1beta/files/...) there, so upload large media first or send it inline.gs://URIs are rejected with400on the Gemini provider; use Vertex for Cloud Storage media. - Multiple entries are sent as one
:batchEmbedContentscall, andtask_type/titleare applied to every entry. This is also the only provider that honours per-itemparams. documentOcrandaudioTrackExtractiongo underembedContentConfig, the only place Gemini accepts them:
usageMetadata.
Vertex AI
Vertex has three embedding APIs, and Bifrost picks the right one from the model name. Project and region come from the Vertex key configuration, not the request body.gemini-embedding-2-preview on Vertex
Everything in the Gemini section applies, with one addition: gs:// URIs are accepted on image, audio, video and file parts, because Vertex resolves Cloud Storage itself. https:// URLs work when Vertex can fetch them; prefer gs:// for anything large.
multimodalembedding@001
This model returns a separate 1408-dimension vector per modality, all in the same embedding space. Image and video URLs must be gs://; inline base64 data URIs are also accepted.
video_config to the video part:
video_segment:
dimensions maps to the model’s parameters.dimension. This model does not report token usage, so usage is null.
Cohere
Cohere’s API has three mutually exclusive input fields, and Bifrost picks one from the content:- Images must be inline. Pass a data URI in
urlordata, or raw base64 indatawithmime_typeset; Cohere does not fetch remote URLs. input_typedefaults tosearch_documentand is forwarded when set.encoding_formatmaps to Cohere’sembedding_typesunless you passembedding_typesyourself. When Cohere returns several representations for one input, each is a separatedataentry labelled with itsencoding_format.- Image inputs bill on Cohere’s image counter, surfaced as
usage.prompt_tokens_details.image_tokensand counted intototal_tokens, notprompt_tokens.
/cohere/v2/embed route accepts Cohere’s native texts / images / inputs body for any provider and returns Cohere’s native envelope (embeddings, response_type: "embeddings_by_type", meta.billed_units).
Bedrock
Bedrock embedding models are routed by family, and each family has its own wire format and constraints.Titan
amazon.titan-embed-image-v1 accepts one entry with text and at most one image. The image must be inline in the data field (a data URI or raw base64); Titan cannot fetch URLs, so a url returns 400.
dimensions(256, 384 or 1024) maps toembeddingConfig.outputEmbeddingLength.- The text models
amazon.titan-embed-text-v1andv2:0take one entry per request; a batch returns400rather than being collapsed into one vector.encoding_format: "binary"is forwarded as Titan’sembeddingTypeson v2.
Cohere on Bedrock
cohere.embed-english-v3, cohere.embed-multilingual-v3 and cohere.embed-v4 follow the same texts[] / images[] / inputs[] selection as direct Cohere, with one Bedrock-specific rule: Embed v3 only accepts images[] when input_type is image. Image-only requests therefore go out as images[] with input_type defaulting to image, which both v3 and v4 accept. A caller-supplied input_type is always kept. Mixed text + image entries use inputs[] and need Embed v4.
Amazon Nova
amazon.nova-2-multimodal-embeddings-v1:0 embeds text, image, audio or video, one modality per entry and one entry per request. Mixing modalities returns 400.
- Sources: inline
data, or ans3://bucket/keyURL that Nova reads directly. Any other URL returns400. - Format: Nova requires a declared format per media part and checks it against the bytes. Bifrost derives it from
mime_type, or from the S3 key’s extension, and returns400when it cannot. Supported:png,jpeg,webp,gifimages;mp3,wav,oggaudio;mp4,mov,mkv,webm,flv,mpeg,wmv,3gpvideo (sent to AWS asthree_gp). task_typemaps toembeddingPurpose:GENERIC_INDEX(default),GENERIC_RETRIEVAL,TEXT_RETRIEVAL,IMAGE_RETRIEVAL,VIDEO_RETRIEVAL,AUDIO_RETRIEVAL,DOCUMENT_RETRIEVAL,CLASSIFICATION,CLUSTERING.dimensions: 256, 384, 1024 or 3072 (default).- Nova-specific top-level fields:
truncationMode(ENDdefault,START,NONE),detailLevel(STANDARD_IMAGEdefault,DOCUMENT_IMAGEfor text-heavy pages; image parts only),embeddingMode(video only, below).
audio_video vector by default. Set embeddingMode to AUDIO_VIDEO_SEPARATE to get an audio vector and a video vector from one input:
usage.
The native /bedrock/model/{modelId}/invoke route accepts Titan (inputText + inputImage), Nova (SINGLE_EMBEDDING) and Cohere (texts / images / inputs) bodies and returns each family’s own envelope.
OpenAI-compatible providers
OpenAI, Azure OpenAI, Mistral, Parasail and every other provider that speaks the OpenAI embeddings dialect accepttext and tokens parts only, and the two cannot be mixed in one request. Only encoding_format and dimensions are sent on the wire; task_type, title and auto_truncate are not part of the OpenAI format and are not forwarded.
Per-Item Parameters
Every entry ininput may instead be an object carrying its own params, which override the
request-level ones for that entry alone. Use it when the items need different parameters —
a query embedded with RETRIEVAL_QUERY alongside documents embedded with
RETRIEVAL_DOCUMENT, say. Plain entries and entries with params can be mixed freely.
params replaces the request-level params rather than merging field by field,
so repeat any request-level value you still want (as dimensions is repeated above).
Requests arriving on the GenAI drop-in routes (:embedContent, :batchEmbedContents) get the reverse treatment: when every requests[] entry carries the same taskType / outputDimensionality, those are hoisted to request level so the call works against non-Gemini providers too.
Things to know
- Token usage is uneven across multimodal models. Vertex
multimodalembedding@001returnsusage: null, Titan image-only inputs report zero tokens, and Cohere image tokens live underprompt_tokens_details. Budgets and cost metered onprompt_tokensdo not see those inputs. - Semantic cache keys include
task_type,titleandauto_truncate, so aRETRIEVAL_QUERYrequest is never served a cachedRETRIEVAL_DOCUMENTvector. - Logs store the full
inputin a dedicatedembedding_inputcolumn and render it in the log detail view. Inline media above the large-payload threshold is redacted.
Check the Supported Providers page for more information on multimodal capabilities supported by each provider.
Next Steps
Now that you understand multimodal capabilities, explore these related topics:Essential Topics
- Streaming Responses - Real-time multimodal processing
- Tool Calling - Combine with external tools
- Provider Configuration - Multiple providers for different capabilities
- Integrations - Drop-in compatibility with existing SDKs
Advanced Topics
- Core Features - Advanced Bifrost capabilities
- Architecture - How Bifrost works internally
- Deployment - Production setup and scaling

