Route an image question to a capable model
Section ID: Guide/j8qfgsv52q#filter-candidate-models
Let a customer ask what is in an uploaded image and require image-capable candidates for that request. Use a per-send filter for this occasional attachment; keep a thread default for workloads that always have the same requirement.
The recipe finishes with a correlated answer from the accepted run or a clear selection failure. Catalog metadata filters candidate models; it does not validate the image or guarantee correct interpretation.
Before you start
Section ID: Guide/j8qfgsv52q#get-started
Use an existing authenticated conversation, permitted image content and named model candidates available to your account. Replace research-001 and <base64_image> with the actual thread and input.
Wait for any unresolved turn to settle. The current queue path does not retain overrideGenerationConfig, so an override-dependent image request must not be queued behind an active run.
If the thread already has a routing filter, copy every constraint this image request must keep into the per-send filter. That filter replaces the whole base filter; adding image support alone does not preserve a prior context or price constraint.
Choose the filter’s lifetime
Section ID: Guide/j8qfgsv52q#where-to-set-the-filter
The per-send recipe below serves one image request. Use the persistent research-thread variant when every turn has the same requirement. A per-send filter replaces the entire base filter, so include every constraint the current request must keep.
Step 1: send the image with its required capability
Section ID: Guide/j8qfgsv52q#2-per-message-override
Set via send-message in overrideGenerationConfig.modelRoutingFilter. Applies to a single message only.
Request example: Send a message to a conversation. Example identifiers and values are illustrative; substitute authorized values.
Example request headers: X-API-Key: $API_KEY; Authorization: Bearer $JWT; Content-Type: application/json. Replace the credential and user placeholders with your own authorized values.
Note: The override merges — it does not replace
overrideGenerationConfigis merged field-by-field onto the config the thread would otherwise use. Send only what you want to change; everything you leave out is inherited.The granularity is the top-level config field. A field you do set replaces the base value wholesale rather than merging into it, so a partial
modelRoutingFilterin an override replaces the thread's filter entirely — it does not combine with it.Two details worth knowing:
Explicit zeros count. Scalars are presence-aware, so
"temperature": 0overrides the base rather than reading as "unset".Empty lists do not. Repeated and map fields have no presence, so an empty list is indistinguishable from an absent one and inherits instead.
clearTools: trueclears inherited statictoolsonly when the override's owntoolslist is empty; a non-empty list replaces the inherited list. It never clearsclientTools. When MCP discovery returns a result, it replacestoolsafter the merge, including when discovery returns no tools. Discovery normally runs even with no configured servers; it is skipped for a profile that disables default tools and has no nonblank server references. The flag therefore does not disable MCP discovery or guarantee a turn without tool calls.
Retain the returned run ID. If all candidates are rejected, show the routing error; do not quietly drop the image requirement to obtain an answer.
Step 2: inspect the accepted run and its answer
Section ID: Guide/j8qfgsv52q#how-filters-combine
Follow generation to a correlated outcome, then inspect the image answer and actual returned model. Use these rules to diagnose why a candidate or constraint was selected.
Finished result: the request either has a completed image answer for its accepted run or a visible failure. If the user asks a later text-only question, omit this per-send override to use the thread's default configuration again.
Variant: keep a capability requirement for a long research thread
Section ID: Guide/j8qfgsv52q#1-thread-level-default
Set via create-thread in defaultGenerationConfig.modelRoutingFilter. Applies to every message in the thread.
Request example: Create a new conversation thread. Example identifiers and values are illustrative; substitute authorized values.
Example request headers: X-API-Key: $API_KEY; Authorization: Bearer $JWT; Content-Type: application/json. Replace the credential and user placeholders with your own authorized values.
Keep the returned thread ID and send the research material to that thread. Inspect the first run and later context size; requiring a 128k catalog window does not make an arbitrarily long history fit. Use compaction when the material grows.
Choose the additional constraints the task needs
Section ID: Guide/j8qfgsv52q#modelroutingfilter-fields
Add a constraint only when it serves the customer task, then repeat the request and inspect its outcome. For a longer answer, require the needed output capacity. For a tool-using structured answer, require the supported parameters. Multiple constraints are ANDed; every specified requirement must pass.
For price constraints, use the variant below and track actual usage separately.
Variant: narrow catalog prices while tracking actual cost
Section ID: Guide/j8qfgsv52q#price-filters-are-not-spending-budgets
Use catalog-price filters to narrow candidates, then track the task’s actual usage. Set separately enforced spending limits before increasing paid traffic.
Document ID: Guide/j8qfgsv52q