---
title: "Set a BYOK LLM provider API key for this workspace."
method: POST
path: "/v1/workspace/byok-key"
tags: ["workspace"]
---

# Set a BYOK LLM provider API key for this workspace.

`POST /v1/workspace/byok-key`

## 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/byok-key`
- Auth: none declared

Encrypts and persists a bring-your-own-key (BYOK) provider API key for the authenticated workspace (AES-256-GCM, ADR-036). ADR-049: multi-provider BYOK — now accepts provider type + api_key + optional model. Requires AES L1 encryption to be enabled on this deployment (ANDISH_ENCRYPTION_L1_ENABLED=true). Supported providers: openrouter_byok, polza_byok, ollama_byok. Plaintext key is NEVER logged or returned (ADR-019). Requires 'admin' scope.

## Request body

- ByokKeySetRequest: Request body for POST /v1/workspace/byok-key. ADR-049: multi-provider BYOK — provider type, api_key, and optional model are now required/accepted fields. The old single-field {api_key} body is replaced by {provider, api_key, model} to support polza_byok and ollama_byok. ADR-013 §5.3 log hygiene: the api_key value is a bearer credential — it is encrypted on write, never logged, and never returned in any response. Provider-specific validation: openrouter_byok — api_key must match ^sk-or-v1-[a-zA-Z0-9_-]+$ (OpenRouter format). polza_byok — api_key must be non-empty (any Bearer token format). ollama_byok — api_key may be empty or omitted (Ollama has no auth token); model is stored for display; base_url deferred (Phase A).
  - `provider` 'openrouter_byok' | 'polza_byok' | 'ollama_byok', required: BYOK provider type. 'openrouter_byok': OpenRouter (key must start with sk-or-v1-). 'polza_byok': polza.ai RU gateway (any non-empty Bearer token). 'ollama_byok': self-hosted Ollama (no API key required).
  - `api_key` string: Plaintext API key for the selected provider. Required and validated for openrouter_byok and polza_byok. May be empty or omitted for ollama_byok (Ollama has no auth token). Stored AES-256-GCM encrypted per ADR-036. Plaintext is never logged or echoed back (ADR-019).
  - `model` string, nullable: Optional model identifier to persist with the BYOK key. Used by build_llm_provider_for_tenant to route requests to the correct model without re-prompting. polza.ai example: 'google/gemini-2.5-flash-lite' (catalog ids always carry a vendor prefix — a bare 'gpt-4o-mini' is invalid on polza.ai). openrouter example: 'google/gemini-2.5-flash-lite'. If omitted, provider default is used.

## Response `204`

Key accepted and encrypted. No content returned.

## 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.
- `422`: Request body invalid or api_key format rejected.
- `503`: AES L1 encryption is not enabled on this deployment.

---

[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)
