---
title: "Validate BYOK LLM credentials and persist on success."
method: POST
path: "/v1/workspace/llm/test"
tags: ["workspace"]
---

# Validate BYOK LLM credentials and persist on success.

`POST /v1/workspace/llm/test`

## Request

- Base URL: `https://api.andish.ru` (the document declares no server; this is the origin it was published from)
- URL: `https://api.andish.ru/v1/workspace/llm/test`
- Auth: none declared

ADR-013 §5.3: instantiates a throw-away provider with the supplied credentials, issues a minimal ping (max_tokens=1), and persists the encrypted key only on success. Supports: openrouter_byok (sk-or-v1-...), polza_byok (any format), and ollama_byok (self-hosted Ollama; uses base_url field; no key persisted). Rate-limited: 5 attempts per tenant per 10 minutes. Plaintext key is NEVER logged or returned (ADR-019). Requires 'admin' scope.

## Request body

- LlmTestRequest: Request body for POST /v1/workspace/llm/test. ADR-013 §5.3: throw-away provider validation before key persistence. Validates that the supplied credentials work for the given provider, then persists the encrypted key on success. Rate-limited: 5 attempts per tenant per 10 minutes (Redis counter). Provider-specific fields: openrouter_byok / polza_byok: api_key is required; base_url is ignored. ollama_byok: base_url is the Ollama endpoint (default localhost:11434); api_key is not required (pass empty string or omit). No key is persisted — only reachability is verified.
  - `provider` 'openrouter_byok' | 'polza_byok' | 'ollama_byok', required: BYOK provider type. 'openrouter_byok': OpenRouter (key format sk-or-v1-...). 'polza_byok': polza.ai RU gateway (Bearer token, any format). 'ollama_byok': self-hosted Ollama (no auth; use base_url field).
  - `api_key` string: Plaintext API key for the selected provider. Required for openrouter_byok and polza_byok. Not used for ollama_byok (pass empty string or omit). Stored AES-256-GCM encrypted on success (ADR-036). Plaintext is never logged or echoed back (ADR-019).
  - `base_url` string, nullable: Ollama base URL for ollama_byok provider. Example: 'http://localhost:11434' or 'http://192.168.1.10:11434'. Ignored for openrouter_byok and polza_byok.
  - `model` string, nullable: Optional model override for the validation ping. If omitted, a provider-appropriate default is used. polza.ai example: 'openai/gpt-4o-mini'. ollama_byok example: 'llama3' or 'mistral'.

## Response `200`

Validation result. See status field for outcome.

- LlmTestResponse: Response for POST /v1/workspace/llm/test. On success the key is persisted; on rejection nothing is written. ADR-013 §5.3: reason strings are masked to avoid echoing credentials or leaking provider-internal error messages. ollama_byok-specific fields: version: Ollama server version string when status='ok' (e.g. '0.5.4'). warning: Non-fatal advisory message (e.g. localhost-on-managed warning).
  - `status` 'ok' | 'rejected', required: 'ok' — provider accepted credentials and key is now stored. 'rejected' — provider rejected credentials; nothing was written.
  - `provider` 'openrouter_byok' | 'polza_byok' | 'ollama_byok', required: Provider type that was tested.
  - `reason` string, nullable: Human-readable rejection reason (masked — never echoes plaintext key). Present only when status='rejected'.
  - `version` string, nullable: Ollama server version string (e.g. '0.5.4'). Only populated for ollama_byok when status='ok'.
  - `warning` string, nullable: Non-fatal advisory message. For ollama_byok: emitted when the base_url points to localhost but Andish is running in managed (remote) mode — in that case the endpoint won't be reachable in production.

## Other responses

- `403`: Insufficient scope — requires 'admin'.
- `412`: The workspace's spend is stopped by the operator: the client's own model key cannot be connected. Answered before any external request and before the attempt counter.
- `422`: Request body invalid.
- `429`: Rate limit exceeded — 5 attempts per tenant per 10 minutes.
- `503`: AES L1 encryption not enabled — cannot persist key.

---

[API](https://skmtc.dev/andish/apis/mnemo-api.md) · [All operations](https://skmtc.dev/andish/apis/mnemo-api/llms.txt) · [OpenAPI document](https://skmtc.dev/andish/apis/mnemo-api/revisions/d5449f23414c?raw)
