Home/Resolve/The resolve chain ENУКРРУС API Reference (ReDoc) ↗

The resolve chain

USER → ORGANIZATION → PLATFORM — how a runtime gets the one key it should use, plaintext included.

POST /internal/v1/credentials/resolve is what translation runtimes call before every job: give me the credential to use for user X, provider P. It is a service-plane endpoint requiring the provider-credentials.invoke scope (Service Plane Tokens) — and, together with reveal, one of only two places plaintext ever leaves the service.

The request

{
  "user_id": "b6a4f6cd-…",
  "org_id": "0d1e2f3a-…",
  "provider_code": "deepl_api",
  "purpose": "translation",
  "allow_platform_fallback": true,
  "correlation_id": "req-01J8…"
}

user_id and org_id must come from a validated user token of your own plane — never from client input. Membership is deliberately not re-checked here: supplying a trustworthy pair is the caller's half of the contract. org_id is optional; without it the organization level is simply skipped. purpose names the workload the key is resolved for — translation, glossary, or tag_fix; any other value is a 400. correlation_id is yours, travels into the audit trail, and comes back in X-Correlation-ID.

The walk

Within the provider's credential_resolution policy (Vendors and Providers), the service walks a fixed chain and returns the first active default it finds:

  1. USER — the user's own default for the provider.
  2. ORGANIZATION — when org_id is present and the provider admits the level: the organization's default. (Audited with reason USER_NOT_CONFIGURED_ORG_SELECTED.)
  3. PLATFORM — when the policy and your allow_platform_fallback both permit: the shared platform default.

Nothing found → 404 CREDENTIAL_NOT_CONFIGURED (the provider exists; nobody configured a key — distinct from 404 PROVIDER_NOT_FOUND). A disabled/removed provider → 409 PROVIDER_DISABLED. Every hit and miss is recorded in the audit trail.

The response

{
  "credential_id": "…",
  "provider_code": "deepl_api",
  "credential_source": "organization",
  "owner_type": "organization",
  "owner_id": "0d1e2f3a-…",
  "credentials": {"api_key": "the-actual-plaintext-key"},
  "configuration": {},
  "catalog_version": "2026.08.24",
  "resolved_at": "2026-08-12T12:30:00Z"
}

credential_source tells you whose key you hold — surface it to the user ("running on your organization's key"). Treat credentials as radioactive: use immediately, never persist, never log; the response arrives with Cache-Control: no-store.

No fallback on runtime errors — by design

If the resolved key turns out broken at the vendor (401, quota exhausted), the service will not hand you the next level on retry: resolution depends only on stored state, so you will get the same key again. Surface the failure to whoever owns the key; do not silently burn someone else's quota. allow_platform_fallback: false exists for the reverse discipline — contracts that require customer-owned keys only.

Worked end-to-end walk (user hit → org fallback → platform fallback → miss): cookbook scenario 06. What a UI should show before submitting a job: Credential Status.