> For the complete documentation index, see [llms.txt](https://docs.fastrouter.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fastrouter.ai/api-reference/virtual-models.md).

# Virtual Models

## Create Virtual Model

> Creates a virtual model — a named list of \[provider, model, weight] entries plus a routing strategy — and returns its model\_list\_id, which updateVirtualModel and deleteVirtualModel need.\
> \
> \*\*Access:\*\* createVirtualModel with project\_id — org owner or project admin. createVirtualModel without project\_id (org-level) — org owner only.\
> \
> \*\*Rules:\*\* the key must be valid and belong to org\_id; a key works only on its own project's virtual models; the key's creator must still be a member of the org and project.\
> \
> \*\*Known issue:\*\* a project member's key calling create is rejected with \`500 An internal error occurred\` instead of a 403.

```json
{"openapi":"3.1.0","info":{"title":"FastRouter API Reference","version":"1.0.0"},"tags":[{"name":"Virtual Models","description":"Manage virtual models (named lists of [provider, model, weight] entries plus a routing strategy) on a FastRouter API key. Served from a separate base path, https://api.fastrouter.ai/prod, authenticated the same way as the rest of the API."}],"servers":[{"url":"https://api.fastrouter.ai","description":"Production API"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"FastRouter API Key. Get yours at https://fastrouter.ai\n\nFormat: `Authorization: Bearer YOUR_API_KEY`"}},"schemas":{"CreateVirtualModelRequest":{"type":"object","required":["org_id","model_list_name","default_strategy_name","model_provider_list"],"properties":{"org_id":{"type":"string","description":"Must match the key's org."},"project_id":{"type":"string","description":"Must be the key's project. Leave out to create an org-level model (org owner key only)."},"model_list_name":{"type":"string","description":"Unique within the project."},"default_strategy_name":{"type":"string","description":"Hyphen forms (e.g. `lowest-price`) are accepted and stored with underscores.","enum":["random_shuffle","lowest_latency","highest_throughput","lowest_price","lowest_usage","priority_routing","category_based_routing"]},"model_provider_list":{"type":"array","items":{"type":"array","description":"[provider, model, weight]. The model must exist and the provider must actively serve it. Provider may be a provider id, or one of `All Providers` / `ALL` / `all` / `all_providers` (any case) to mean any active provider of the model — stored as `ALL`.","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"minItems":3,"maxItems":3},"description":"For `category_based_routing`, this is instead an array of categories, each `{\"id\", \"sub_strategy\", \"model_provider_list\"}`."},"model_list_id":{"type":"string","description":"Must not be sent on create; returns 400."}}},"VirtualModelSummaryResponse":{"type":"object","properties":{"model_list_id":{"type":"string"},"model_list_name":{"type":"string"},"project_id":{"type":"string","nullable":true}}},"VirtualModelErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}}},"responses":{"VirtualModelBadRequestError":{"description":"Bad Request. Includes: unknown strategy (`default_strategy_name must be one of: ...`), missing model_list_id on update/delete (`model_list_id is required`), wrong model_list_id (`Virtual model not found for model_list_id: ...`), unknown project_id (`Project not found for org_id=..., project_id=...`), model_list_id sent on create (`model_list_id` not allowed), unknown model (`Invalid model 'x': model not found`), or provider not serving the model (`Invalid provider 'x' for model 'y'`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}},"VirtualModelUnauthorizedError":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}},"VirtualModelForbiddenError":{"description":"Forbidden. Includes: key from another org (`API key does not belong to this organization`), another project's model or project_id (`API key does not belong to this project`), or an org-level action without an org owner's key (`API key must belong to an organization owner to perform this operation`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}}}},"paths":{"/prod/createVirtualModel":{"post":{"operationId":"createVirtualModel","tags":["Virtual Models"],"summary":"Create Virtual Model","description":"Creates a virtual model — a named list of [provider, model, weight] entries plus a routing strategy — and returns its model_list_id, which updateVirtualModel and deleteVirtualModel need.\n\n**Access:** createVirtualModel with project_id — org owner or project admin. createVirtualModel without project_id (org-level) — org owner only.\n\n**Rules:** the key must be valid and belong to org_id; a key works only on its own project's virtual models; the key's creator must still be a member of the org and project.\n\n**Known issue:** a project member's key calling create is rejected with `500 An internal error occurred` instead of a 403.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVirtualModelRequest"}}}},"responses":{"200":{"description":"Virtual model created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelSummaryResponse"}}}},"400":{"$ref":"#/components/responses/VirtualModelBadRequestError"},"401":{"$ref":"#/components/responses/VirtualModelUnauthorizedError"},"403":{"$ref":"#/components/responses/VirtualModelForbiddenError"}}}}}}
```

## Show Virtual Models

> Returns the virtual models of the key's project plus org-level ones, newest first. Any role (org owner, project admin, project member) can call it.

```json
{"openapi":"3.1.0","info":{"title":"FastRouter API Reference","version":"1.0.0"},"tags":[{"name":"Virtual Models","description":"Manage virtual models (named lists of [provider, model, weight] entries plus a routing strategy) on a FastRouter API key. Served from a separate base path, https://api.fastrouter.ai/prod, authenticated the same way as the rest of the API."}],"servers":[{"url":"https://api.fastrouter.ai","description":"Production API"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"FastRouter API Key. Get yours at https://fastrouter.ai\n\nFormat: `Authorization: Bearer YOUR_API_KEY`"}},"schemas":{"ShowVirtualModelsRequest":{"type":"object","required":["org_id"],"properties":{"org_id":{"type":"string","description":"Must match the key's org."},"project_id":{"type":"string","description":"Optional. If sent, must exist (else 400 Project not found) and be the key's project (else 403). If omitted, returns the key's project's models plus org-level ones."}}},"VirtualModel":{"type":"object","properties":{"org_id":{"type":"string"},"project_id":{"type":"string","description":"\"NULL\" for org-level models."},"model_list_id":{"type":"string"},"model_list_name":{"type":"string"},"default_strategy_name":{"type":"string"},"model_provider_list":{"type":"array","items":{"type":"array"}},"model_provider_list_jsonb":{"type":"object","nullable":true},"created_by":{"type":"string"},"created_on":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_on":{"type":"string","format":"date-time"}}},"VirtualModelErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}}},"responses":{"VirtualModelBadRequestError":{"description":"Bad Request. Includes: unknown strategy (`default_strategy_name must be one of: ...`), missing model_list_id on update/delete (`model_list_id is required`), wrong model_list_id (`Virtual model not found for model_list_id: ...`), unknown project_id (`Project not found for org_id=..., project_id=...`), model_list_id sent on create (`model_list_id` not allowed), unknown model (`Invalid model 'x': model not found`), or provider not serving the model (`Invalid provider 'x' for model 'y'`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}},"VirtualModelUnauthorizedError":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}},"VirtualModelForbiddenError":{"description":"Forbidden. Includes: key from another org (`API key does not belong to this organization`), another project's model or project_id (`API key does not belong to this project`), or an org-level action without an org owner's key (`API key must belong to an organization owner to perform this operation`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}}}},"paths":{"/prod/showVirtualModels":{"post":{"operationId":"showVirtualModels","tags":["Virtual Models"],"summary":"Show Virtual Models","description":"Returns the virtual models of the key's project plus org-level ones, newest first. Any role (org owner, project admin, project member) can call it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShowVirtualModelsRequest"}}}},"responses":{"200":{"description":"List of virtual models.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VirtualModel"}}}}},"400":{"$ref":"#/components/responses/VirtualModelBadRequestError"},"401":{"$ref":"#/components/responses/VirtualModelUnauthorizedError"},"403":{"$ref":"#/components/responses/VirtualModelForbiddenError"}}}}}}
```

## Update Virtual Model

> Replaces a virtual model's name, strategy and entries. The full model\_provider\_list is sent each time; it is not merged with the old one. project\_id is not needed — it comes from the saved virtual model, and a different project\_id returns 400 (a model can't be moved to another project).\
> \
> \*\*Access:\*\* project-level model — org owner or project admin. org-level model — org owner only.\
> \
> \*\*Known issue:\*\* a project member's key calling update is rejected with \`500 An internal error occurred\` instead of a 403.

```json
{"openapi":"3.1.0","info":{"title":"FastRouter API Reference","version":"1.0.0"},"tags":[{"name":"Virtual Models","description":"Manage virtual models (named lists of [provider, model, weight] entries plus a routing strategy) on a FastRouter API key. Served from a separate base path, https://api.fastrouter.ai/prod, authenticated the same way as the rest of the API."}],"servers":[{"url":"https://api.fastrouter.ai","description":"Production API"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"FastRouter API Key. Get yours at https://fastrouter.ai\n\nFormat: `Authorization: Bearer YOUR_API_KEY`"}},"schemas":{"UpdateVirtualModelRequest":{"type":"object","required":["org_id","model_list_id"],"description":"Replaces a virtual model's name, strategy and entries. The full model_provider_list is replaced, not merged with the old one.","properties":{"org_id":{"type":"string","description":"Must match the key's org."},"model_list_id":{"type":"string","description":"Must exist in the org, else 400 Virtual model not found. project_id is derived from the saved model and cannot be changed here."},"model_list_name":{"type":"string","description":"New name. The old name is read from the saved row, so old_model_list_name is not needed."},"default_strategy_name":{"type":"string","description":"Hyphen forms (e.g. `lowest-price`) are accepted and stored with underscores.","enum":["random_shuffle","lowest_latency","highest_throughput","lowest_price","lowest_usage","priority_routing","category_based_routing"]},"model_provider_list":{"type":"array","items":{"type":"array","description":"[provider, model, weight]. The model must exist and the provider must actively serve it. Provider may be a provider id, or one of `All Providers` / `ALL` / `all` / `all_providers` (any case) to mean any active provider of the model — stored as `ALL`.","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"minItems":3,"maxItems":3}}}},"VirtualModelSummaryResponse":{"type":"object","properties":{"model_list_id":{"type":"string"},"model_list_name":{"type":"string"},"project_id":{"type":"string","nullable":true}}},"VirtualModelErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}}},"responses":{"VirtualModelBadRequestError":{"description":"Bad Request. Includes: unknown strategy (`default_strategy_name must be one of: ...`), missing model_list_id on update/delete (`model_list_id is required`), wrong model_list_id (`Virtual model not found for model_list_id: ...`), unknown project_id (`Project not found for org_id=..., project_id=...`), model_list_id sent on create (`model_list_id` not allowed), unknown model (`Invalid model 'x': model not found`), or provider not serving the model (`Invalid provider 'x' for model 'y'`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}},"VirtualModelUnauthorizedError":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}},"VirtualModelForbiddenError":{"description":"Forbidden. Includes: key from another org (`API key does not belong to this organization`), another project's model or project_id (`API key does not belong to this project`), or an org-level action without an org owner's key (`API key must belong to an organization owner to perform this operation`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}}}},"paths":{"/prod/updateVirtualModel":{"post":{"operationId":"updateVirtualModel","tags":["Virtual Models"],"summary":"Update Virtual Model","description":"Replaces a virtual model's name, strategy and entries. The full model_provider_list is sent each time; it is not merged with the old one. project_id is not needed — it comes from the saved virtual model, and a different project_id returns 400 (a model can't be moved to another project).\n\n**Access:** project-level model — org owner or project admin. org-level model — org owner only.\n\n**Known issue:** a project member's key calling update is rejected with `500 An internal error occurred` instead of a 403.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVirtualModelRequest"}}}},"responses":{"200":{"description":"Virtual model updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelSummaryResponse"}}}},"400":{"$ref":"#/components/responses/VirtualModelBadRequestError"},"401":{"$ref":"#/components/responses/VirtualModelUnauthorizedError"},"403":{"$ref":"#/components/responses/VirtualModelForbiddenError"}}}}}}
```

## Delete Virtual Model

> Deletes a virtual model. Only an org owner's key can call it, and the model must be in the key's project or org-level. project\_id is not needed.

```json
{"openapi":"3.1.0","info":{"title":"FastRouter API Reference","version":"1.0.0"},"tags":[{"name":"Virtual Models","description":"Manage virtual models (named lists of [provider, model, weight] entries plus a routing strategy) on a FastRouter API key. Served from a separate base path, https://api.fastrouter.ai/prod, authenticated the same way as the rest of the API."}],"servers":[{"url":"https://api.fastrouter.ai","description":"Production API"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"FastRouter API Key. Get yours at https://fastrouter.ai\n\nFormat: `Authorization: Bearer YOUR_API_KEY`"}},"schemas":{"DeleteVirtualModelRequest":{"type":"object","required":["org_id","model_list_id"],"properties":{"org_id":{"type":"string","description":"Must match the key's org."},"model_list_id":{"type":"string"}}},"VirtualModelErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}}},"responses":{"VirtualModelBadRequestError":{"description":"Bad Request. Includes: unknown strategy (`default_strategy_name must be one of: ...`), missing model_list_id on update/delete (`model_list_id is required`), wrong model_list_id (`Virtual model not found for model_list_id: ...`), unknown project_id (`Project not found for org_id=..., project_id=...`), model_list_id sent on create (`model_list_id` not allowed), unknown model (`Invalid model 'x': model not found`), or provider not serving the model (`Invalid provider 'x' for model 'y'`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}},"VirtualModelUnauthorizedError":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}},"VirtualModelForbiddenError":{"description":"Forbidden. Includes: key from another org (`API key does not belong to this organization`), another project's model or project_id (`API key does not belong to this project`), or an org-level action without an org owner's key (`API key must belong to an organization owner to perform this operation`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualModelErrorResponse"}}}}}},"paths":{"/prod/deleteVirtualModel":{"post":{"operationId":"deleteVirtualModel","tags":["Virtual Models"],"summary":"Delete Virtual Model","description":"Deletes a virtual model. Only an org owner's key can call it, and the model must be in the key's project or org-level. project_id is not needed.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteVirtualModelRequest"}}}},"responses":{"200":{"description":"Virtual model deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"model_list_id":{"type":"string"},"deleted":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/VirtualModelBadRequestError"},"401":{"$ref":"#/components/responses/VirtualModelUnauthorizedError"},"403":{"$ref":"#/components/responses/VirtualModelForbiddenError"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.fastrouter.ai/api-reference/virtual-models.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
