Read one partner model's input schema as an OpenAPI document.
The per-model input schema for a single Comfy Router model, served as a standalone OpenAPI document, so a caller - an SDK, a codegen tool, or an agent - can discover a model’s arguments without reading Comfy’s prose docs. It mirrors fal’s per-model schema endpoint, and it is the discovery mechanism the SDK quickstart depends on.
The document served is the SAME source the server validates a call against before the request reaches the provider. That is the property that makes it worth trusting: what Comfy publishes and what Comfy enforces are one document, not two copies that drift. Both read the schema through a single accessor (routerschema.Source.InputSchema), so they cannot diverge without deleting it.
The path prefix is the SAME canonical {provider}/{model}[/{variant}] model ID that POST /v1/models/{provider}/{model} invokes, with /openapi.json appended - a caller reads an ID out of the catalog, appends one literal segment, and gets that model’s schema. provider and model are governed by the same RouterProvider / RouterModel parameters, with the same alphabet.
One constraint this puts on the still-unsettled {variant} segment: openapi.json is itself a legal value under the RouterModel alphabet, so whatever spelling addresses a variant must not make /v1/models/{provider}/{model}/openapi.json ambiguous with a variant literally named openapi.json. Reserving that one literal is the cheapest resolution, and it is noted here rather than resolved, because how the variant segment is addressed is not settled by this contract.
Only the model’s INPUT is described. M1 returns the provider’s native output unchanged, so there is no Comfy-owned output shape to describe and the document deliberately does not invent one.
A model whose schema has not been authored yet is served a MINIMAL PERMISSIVE document with 200, NOT a 404: the model exists, GET /v1/models/{provider}/{model} reports it and POST runs it, so 404 here would have two Router routes disagreeing about whether the same model exists. The permissive document says the true thing instead - this model takes a JSON object and Comfy has not yet narrowed which fields - and flags itself with x-comfy-input-schema-authored: false so a caller can tell “unconstrained” from “constrained to an open object”. A 404 on this route means only what it means everywhere else in Router: model_not_found, the ID names nothing.
The response is cacheable. It carries a strong ETag over the document bytes and honours If-None-Match with a 304, because an SDK re-fetches this document far more often than the document changes.
This operation is deliberately tagged Comfy Router and NOT API Nodes, for the reason given on the invocation route.
Authorizations
Bearer token authentication. Normally a Firebase or Cloud JWT. A 'comfyui-' prefixed API key is ALSO accepted here on operations served by the comfyFirebase auth middleware: the prefix classifies the value as an API key and it is validated exactly as if sent in X-API-Key (BE-9720, parity with ingest).
Headers
The ETag a caller holds from an earlier 200. When it matches the current document (RFC 9110 weak comparison; * matches any current document) the answer is a bodyless 304 carrying the same ETag, otherwise the full document.
Path Parameters
Lowercase provider segment of the canonical {provider}/{model}[/{variant}] model ID - the partner whose model is being run.
The schema is RouterProviderSegment, the SAME component a catalog entry's provider field references, so an ID GET /v1/models lists cannot drift from the ids this route accepts. Its pattern is a CONTRACT statement, not enforcement: comfy-api installs no OpenAPI request validator and oapi-codegen binds path parameters as plain strings, so the handler must re-validate this segment itself before using it to select a provider or compose an upstream URL.
Lowercase provider segment of the canonical {provider}/{model}[/{variant}] model ID - the partner whose model is being addressed. The invocation route's provider path parameter and a catalog entry's provider field both reference this one schema, which is what keeps the listed IDs and the accepted IDs from drifting apart.
The pattern is a CONTRACT statement, not enforcement: comfy-api installs no OpenAPI request validator and oapi-codegen binds path parameters as plain strings, so a handler must re-validate the segment itself before using it to select a provider or compose an upstream URL. The alphabet deliberately admits no /, no percent-encoding, and no repeated separator, so no accepted value can contain a . or .. path segment.
64^[a-z0-9]+([._-][a-z0-9]+)*$"fal-ai"
Lowercase model segment of the canonical {provider}/{model}[/{variant}] model ID - the model to run within that provider.
As with provider, the schema is the shared RouterModelSegment component and its pattern documents the contract rather than enforcing it - see RouterProvider.
Lowercase model segment of the canonical {provider}/{model}[/{variant}] model ID - the model to run within that provider. Shared by the invocation route's model path parameter and a catalog entry's model field, for the same no-drift reason as RouterProviderSegment.
As with the provider segment, the pattern documents the contract and does not enforce it. Dots are permitted inside the segment because partner model IDs use them for versions (flux-1.1-pro), but a repeated separator is not, so .. cannot appear.
128^[a-z0-9]+([._-][a-z0-9]+)*$"flux-pro"
Response
OK - the model's input schema, as a standalone OpenAPI document.
A standalone OpenAPI document describing ONE Comfy Router model's input - the body POST /v1/models/{provider}/{model} accepts for that model. It is what GET /v1/models/{provider}/{model}/openapi.json returns.
It is a full OpenAPI document rather than a bare JSON Schema because that is what the tools this endpoint exists for consume: an SDK generator takes an OpenAPI document, and fal's per-model schema endpoint - the surface this one mirrors - returns one too. The document is STANDALONE: every schema component its request body references travels with it under its own components.schemas, so nothing in it points at a section the caller does not have.
The shape is left open here on purpose. Its concrete contents are an OpenAPI document, and restating the OpenAPI meta-schema inside this spec would be a second copy of a specification Comfy does not own - the exact publish-versus-enforce drift this endpoint exists to prevent, one level up. It is a named component (never an inline anonymous object) because ComfyUI's spec-driven codegen needs a class to generate.
Two Comfy extensions are carried at the document root and are part of this contract. x-comfy-router-model-id repeats the canonical model ID, so a document saved to disk still names the model it describes. x-comfy-input-schema-authored is a boolean reporting whether the embedded schema was authored for this model (true) or is the permissive fallback served until one is (false); the two are indistinguishable from the schema alone, and a caller that cannot tell them apart would read "any JSON object" as a narrowed contract.