---
title: "Update an LLM provider (owner-only) · 0 credits"
method: PATCH
path: "/api/v1/llm-providers/{id}"
tags: ["BYO-LLM"]
---

# Update an LLM provider (owner-only) · 0 credits

`PATCH /api/v1/llm-providers/{id}`

## Request

- Base URL: `https://legal.nexusquantum.legal`
- URL: `https://legal.nexusquantum.legal/api/v1/llm-providers/{id}`
- Auth: HTTP bearer

PARTIAL update of non-secret fields (label, base_url, model_default, model_map, extra_headers, routing_policy, billing_mode, enabled). The credential (`api_key` / `aws:{…}`) is WRITE-ONLY: if sent, it is re-encrypted and the `key_fingerprint` is recomputed; otherwise it is kept. It re-validates SSRF on `base_url` if it changes. Firm-scoped OWNER-ONLY. No charge. Scope: mcp | * (NOT cases).

## Path parameters

- `id` string, uuid, required

## Request body

- UpdateLlmProviderRequest: PARTIAL update: send only the fields to change. The credential (`api_key` / `aws`) is WRITE-ONLY: if provided, it is re-encrypted and `key_fingerprint` is recomputed; if omitted, it is kept.
  - `label` string
  - `base_url` string: Does not apply to bedrock. Re-validated against SSRF if it changes.
  - `model_default` string
  - `model_map` object: Role→model map, no silent defaults. Recommendation (not a default): A → `claude-fable-5` · B → `claude-opus-4-8` · C → `claude-opus-4-8` or an equally strong reasoning model; any model of the 3 kinds works in any node. `B` ≠ `A` recommended.
  - `extra_headers` object
  - `routing_policy` 'own_only' | 'own_then_platform'
  - `role` 'A' | 'B' | 'C', nullable: Node this engine is assigned to: 'A' (primary analysis), 'B' (adversarial audit) or 'C' (adversarial counterparty). Omit or null = the firm's DEFAULT engine, which serves every node and role (consulta, chat, draft…). Precedence: node engine → default engine → (when the policy forbids platform) Node A engine → platform. Allows a DIFFERENT engine per node: B and C should not share a model with A, or the cross-audit loses its value. Send null to revert to the default engine.
  - `billing_mode` string
  - `enabled` boolean
  - `api_key` string: New credential (openai_compatible/anthropic). WRITE-ONLY.
  - `aws` AwsCredentials: AWS credentials for kind bedrock. WRITE-ONLY: `secretAccessKey` is never returned in responses.
    - `accessKeyId` string, required
    - `secretAccessKey` string, required
    - `region` string, required

## Response `200`

Provider updated (non-secret projection).

- LlmProvider: Firm BYO-LLM configuration (your own LLM engine, firm-level). NON-SECRET projection: the credential (`api_key` / `aws.secretAccessKey`) is WRITE-ONLY and NEVER appears here — only `key_fingerprint` is exposed (non-secret). Once `enabled`, the engine applies to ALL of the firm's generative flows (analyze included).
  - `id` string, uuid
  - `label` string: Human-readable name, unique within the firm.
  - `kind` 'openai_compatible' | 'anthropic' | 'bedrock': Adapter family.
  - `base_url` string, nullable: Endpoint (openai_compatible: required; anthropic: optional; bedrock: null, derived from region). Validated against SSRF.
  - `model_default` string: Default model.
  - `model_map` object: Role→model map (e.g. { "A": "claude-opus-4-8", "B": "gpt-4o" }). No silent defaults: each node uses exactly the declared model (or `model_default` when the role is not mapped). Recommendation (not a default): Node A → `claude-fable-5` · Node B → `claude-opus-4-8` · Node C → `claude-opus-4-8` or another equally strong reasoning model; any model of the 3 kinds works in any node. `B` ≠ `A` is recommended to preserve the independence of the audit.
  - `key_fingerprint` string, nullable: NON-secret, NON-reversible fingerprint of the credential (hash, e.g. `sha256:a1b2c3d4e5f6`; older rows may show the legacy format `sk-p…a1b2`). The ONLY representation of the key that leaves the API.
  - `extra_headers` object: Optional extra headers for the provider.
  - `routing_policy` 'own_only' | 'own_then_platform': own_then_platform leaves the platform chain as a fallback if your provider fails recoverably.
  - `role` 'A' | 'B' | 'C', nullable: Node this engine is assigned to: 'A' (primary analysis), 'B' (adversarial audit) or 'C' (adversarial counterparty). Omit or null = the firm's DEFAULT engine, which serves every node and role (consulta, chat, draft…). Precedence: node engine → default engine → (when the policy forbids platform) Node A engine → platform. Allows a DIFFERENT engine per node: B and C should not share a model with A, or the cross-audit loses its value. Additive (per-node BYO, 2026-07-24).
  - `billing_mode` string: Billing mode (default platform).
  - `enabled` boolean: Whether it is active for routing firm traffic.
  - `last_verified_at` string, date-time, nullable: Last successful /test health check.
  - `created_at` string, date-time
  - `updated_at` string, date-time
  - `secret_at_rest` 'encrypted_aes_256_gcm' | 'plaintext': Creation response only: at-rest encryption status of the credential.

## Other responses

- `400`: INVALID_JSON | VALIDATION_ERROR (field validation or nothing to update)
- `404`: NOT_FOUND (does not exist or does not belong to your firm)
- `409`: PROVIDER_LABEL_TAKEN (duplicate label within the firm)
- `422`: INVALID_PROVIDER_URL (base_url fails the SSRF filter)

---

[API](https://skmtc.dev/nexusquantum/apis/nexus-legal-api.md) · [All operations](https://skmtc.dev/nexusquantum/apis/nexus-legal-api/llms.txt) · [OpenAPI document](https://skmtc.dev/nexusquantum/apis/nexus-legal-api/revisions/4084d8d4eb0b?raw)
