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

# Providers

## List Providers

> List static metadata for every configured provider.\
> \
> Operator-facing: reports each provider's capabilities, documentation and\
> pricing links, and display name from the bundled any-llm and models.dev\
> datasets. No provider is contacted, so this is cheap and always available.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"ProvidersResponse":{"description":"Metadata for every configured provider.","properties":{"providers":{"items":{"$ref":"#/components/schemas/ProviderInfoSchema"},"title":"Providers","type":"array"}},"required":["providers"],"title":"ProvidersResponse","type":"object"},"ProviderInfoSchema":{"description":"Static, network-free metadata for one configured provider instance.","properties":{"capabilities":{"$ref":"#/components/schemas/ProviderCapabilitiesSchema"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"doc_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doc Url"},"env_key":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Env var the credential is read from.","title":"Env Key"},"instance":{"description":"Configured provider key (may differ from the type).","title":"Instance","type":"string"},"name":{"description":"Human-friendly provider name.","title":"Name","type":"string"},"pricing_urls":{"items":{"type":"string"},"title":"Pricing Urls","type":"array"},"provider_type":{"description":"Underlying any-llm provider type.","title":"Provider Type","type":"string"},"source":{"const":"config","default":"config","description":"Where the instance is defined: 'config' for config.yml (or OTARI_CONFIG_YAML).","title":"Source","type":"string"}},"required":["instance","provider_type","name","capabilities"],"title":"ProviderInfoSchema","type":"object"},"ProviderCapabilitiesSchema":{"description":"Curated capability flags for a provider.","properties":{"audio":{"title":"Audio","type":"boolean"},"embeddings":{"title":"Embeddings","type":"boolean"},"image_generation":{"title":"Image Generation","type":"boolean"},"list_models":{"title":"List Models","type":"boolean"},"moderation":{"title":"Moderation","type":"boolean"},"pdf":{"title":"Pdf","type":"boolean"},"reasoning":{"title":"Reasoning","type":"boolean"},"rerank":{"title":"Rerank","type":"boolean"},"responses_api":{"title":"Responses Api","type":"boolean"},"streaming":{"title":"Streaming","type":"boolean"},"vision":{"title":"Vision","type":"boolean"}},"required":["streaming","reasoning","vision","pdf","embeddings","image_generation","audio","rerank","responses_api","moderation","list_models"],"title":"ProviderCapabilitiesSchema","type":"object"}}},"paths":{"/api/v1/providers":{"get":{"description":"List static metadata for every configured provider.\n\nOperator-facing: reports each provider's capabilities, documentation and\npricing links, and display name from the bundled any-llm and models.dev\ndatasets. No provider is contacted, so this is cheap and always available.","operationId":"providers-list_providers","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvidersResponse"}}},"description":"Successful Response"}},"summary":"List Providers","tags":["providers"]}}}}
```

## Provider Catalog

> List every known provider for the add-provider picker: id and name only.\
> \
> Lightweight by design so the picker never lags: provider ids come from the\
> any-llm registry and names from the models.dev catalog, so no\
> provider SDK is imported. The autofill hints for a chosen provider come from\
> GET /api/v1/providers/catalog/{provider\_id}, which imports only that one SDK.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"KnownProviderSummarySchema":{"description":"A provider offered in the add-provider picker: id and display name only.","properties":{"id":{"description":"any-llm provider id, used as the default instance name.","title":"Id","type":"string"},"name":{"description":"Human-friendly display name.","title":"Name","type":"string"}},"required":["id","name"],"title":"KnownProviderSummarySchema","type":"object"}}},"paths":{"/api/v1/providers/catalog":{"get":{"description":"List every known provider for the add-provider picker: id and name only.\n\nLightweight by design so the picker never lags: provider ids come from the\nany-llm registry and names from the models.dev catalog, so no\nprovider SDK is imported. The autofill hints for a chosen provider come from\nGET /api/v1/providers/catalog/{provider_id}, which imports only that one SDK.","operationId":"providers-provider_catalog","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/KnownProviderSummarySchema"},"title":"Response Providers-Provider Catalog","type":"array"}}},"description":"Successful Response"}},"summary":"Provider Catalog","tags":["providers"]}}}}
```

## Provider Catalog Detail

> Autofill hints for one provider the add-provider form has selected.\
> \
> Imports only the selected provider's any-llm module (not the whole catalog)\
> to report its credential env var, default endpoint, whether a key is required,\
> and whether that env var is already set on the server. Returns 404 for an\
> unknown provider id.\
> \
> The SDK import is offloaded to a worker thread: the first fetch for a given\
> provider imports that provider's module, which would otherwise block the event\
> loop (and thus every concurrent request) for the import's duration.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"KnownProviderSchema":{"description":"A selected provider's autofill hints for the add-provider form.","properties":{"default_api_base":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Built-in endpoint; blank means the SDK's default.","title":"Default Api Base"},"env_key":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Env var the SDK reads this provider's key from.","title":"Env Key"},"env_key_present":{"default":false,"description":"True when env_key is set on the server. Informational: a stored provider never reads it, so a key the provider requires must still be supplied.","title":"Env Key Present","type":"boolean"},"id":{"description":"any-llm provider id, used as the default instance name.","title":"Id","type":"string"},"name":{"description":"Human-friendly display name.","title":"Name","type":"string"},"requires_api_key":{"description":"False for providers that need no key: keyless local backends (Ollama, llama.cpp) and ambient cloud credentials (Bedrock, Vertex AI).","title":"Requires Api Key","type":"boolean"}},"required":["id","name","requires_api_key"],"title":"KnownProviderSchema","type":"object"},"HTTPValidationError":{"properties":{"code":{"const":"invalid_request","description":"Stable error code, also sent as the Otari-Error-Code header.","title":"Code","type":"string"},"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"ValidationError":{"properties":{"ctx":{"title":"Context","type":"object"},"input":{"title":"Input"},"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"}}},"paths":{"/api/v1/providers/catalog/{provider_id}":{"get":{"description":"Autofill hints for one provider the add-provider form has selected.\n\nImports only the selected provider's any-llm module (not the whole catalog)\nto report its credential env var, default endpoint, whether a key is required,\nand whether that env var is already set on the server. Returns 404 for an\nunknown provider id.\n\nThe SDK import is offloaded to a worker thread: the first fetch for a given\nprovider imports that provider's module, which would otherwise block the event\nloop (and thus every concurrent request) for the import's duration.","operationId":"providers-provider_catalog_detail","parameters":[{"in":"path","name":"provider_id","required":true,"schema":{"title":"Provider Id","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnownProviderSchema"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Provider Catalog Detail","tags":["providers"]}}}}
```

## Provider Health

> Report every configured provider's reachability, with a last-checked time.\
> \
> Covers the configured provider instances and every hosted provider switched\
> on, each hosted provider under its provider name. A hosted provider that a\
> configured instance of the same name shadows is not reported. One whose\
> stored key cannot be decrypted with the configured \`OTARI\_SECRET\_KEY\` is\
> reported unreachable with that reason.\
> \
> Reuses the per-provider model-discovery test path, so a provider is healthy\
> when its credentials can list models. Results are served from the discovery\
> cache (cheap enough to poll), so \`\`checked\_at\`\` reflects when each provider\
> was actually dialed. Pass \`\`refresh=true\`\` to force a live re-dial of every\
> provider.\
> \
> A provider whose backend serves no model-listing endpoint cannot be verified\
> this way, but it is not unreachable either: it is reported with\
> \`\`discovery\_unsupported\`\` and counted under \`\`degraded\`\` rather than as a\
> reachability failure.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"ProviderHealthResponse":{"description":"Provider connectivity across the whole gateway, for the health monitor.\n\nCarries per-provider results plus the ``healthy`` / ``total`` counts and the\nmost recent ``checked_at`` so the overview page can render a summary tile\nwithout re-deriving them.","properties":{"checked_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 time of the most recent per-provider check (null if none yet).","title":"Checked At"},"degraded":{"default":0,"description":"How many providers are not counted as reachable only because model discovery is unavailable for them. These may still serve requests.","title":"Degraded","type":"integer"},"healthy":{"description":"How many providers are currently reachable.","title":"Healthy","type":"integer"},"providers":{"items":{"$ref":"#/components/schemas/ProviderHealthSchema"},"title":"Providers","type":"array"},"total":{"description":"How many providers are configured.","title":"Total","type":"integer"}},"required":["providers","healthy","total"],"title":"ProviderHealthResponse","type":"object"},"ProviderHealthSchema":{"description":"One provider instance's reachability, from the model-discovery test path.","properties":{"checked_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 wall-clock time the provider's reachability was last checked (null if never).","title":"Checked At"},"discovery_unsupported":{"default":false,"description":"True when the check failed only because this backend serves no model-listing endpoint. The provider may still handle requests; only model discovery is unavailable.","title":"Discovery Unsupported","type":"boolean"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sanitized provider error when unreachable.","title":"Error"},"instance":{"title":"Instance","type":"string"},"model_count":{"description":"Number of models the last successful listing returned.","title":"Model Count","type":"integer"},"ok":{"description":"True when the provider's credentials could list models.","title":"Ok","type":"boolean"}},"required":["instance","ok","model_count"],"title":"ProviderHealthSchema","type":"object"},"HTTPValidationError":{"properties":{"code":{"const":"invalid_request","description":"Stable error code, also sent as the Otari-Error-Code header.","title":"Code","type":"string"},"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"ValidationError":{"properties":{"ctx":{"title":"Context","type":"object"},"input":{"title":"Input"},"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"}}},"paths":{"/api/v1/providers/health":{"get":{"description":"Report every configured provider's reachability, with a last-checked time.\n\nCovers the configured provider instances and every hosted provider switched\non, each hosted provider under its provider name. A hosted provider that a\nconfigured instance of the same name shadows is not reported. One whose\nstored key cannot be decrypted with the configured `OTARI_SECRET_KEY` is\nreported unreachable with that reason.\n\nReuses the per-provider model-discovery test path, so a provider is healthy\nwhen its credentials can list models. Results are served from the discovery\ncache (cheap enough to poll), so ``checked_at`` reflects when each provider\nwas actually dialed. Pass ``refresh=true`` to force a live re-dial of every\nprovider.\n\nA provider whose backend serves no model-listing endpoint cannot be verified\nthis way, but it is not unreachable either: it is reported with\n``discovery_unsupported`` and counted under ``degraded`` rather than as a\nreachability failure.","operationId":"providers-provider_health","parameters":[{"in":"query","name":"refresh","required":false,"schema":{"default":false,"title":"Refresh","type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderHealthResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Provider Health","tags":["providers"]}}}}
```


---

# 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.otari.ai/otari/for-integrators/api-reference/providers.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.
