---
title: "Register YOUR sanctions-screening provider (owner-only) · 0 credits"
method: POST
path: "/api/v1/screening-providers"
tags: ["BYO-Screening"]
---

# Register YOUR sanctions-screening provider (owner-only) · 0 credits

`POST /api/v1/screening-providers`

## Request

- Base URL: `https://legal.nexusquantum.legal`
- URL: `https://legal.nexusquantum.legal/api/v1/screening-providers`
- Auth: HTTP bearer

Registers a screening provider under YOUR contract. Why it has to be yours and not ours: screening needs the parties' REAL names, before anonymisation — a sanctions list does not match `[PERSON_1]`. Sending those names to a third party is a transfer of personal data, and whoever contracts it has to be whoever answers for it. There is therefore NO provider of ours that calls a third party, and its absence is the design. The credential is WRITE-ONLY (AES-256-GCM, never returned). `base_url` is validated against SSRF. Scope: mcp | * (NOT cases).

## Request body

- CreateScreeningProviderRequest: Registers YOUR screening provider, under YOUR contract. `api_key` is WRITE-ONLY: it travels in the body, is encrypted AES-256-GCM and is never returned. Sending it under any other name (`apiKey`, `token`, `key`…) is rejected with MISPLACED_CREDENTIAL rather than stored without it: the row would be created credential-less and fail on its first call with a transport error that says nothing about why.
  - `label` string, required: Required, 1–60 characters.
  - `kind` 'opensanctions_compatible': Default `opensanctions_compatible`.
  - `base_url` string, required: Required; validated against SSRF.
  - `api_key` string, required: WRITE-ONLY. Required. Never returned.
  - `lists` string[]: Up to 20 entries, 80 characters each.
  - `enabled` boolean: Default true.

## Response `201`

Provider created (no credential in the response).

- ScreeningProvider: The firm's OWN sanctions-screening provider (BYO). Non-secret projection: it NEVER returns the credential, only `key_fingerprint`. Firm-scoped, bound to the key's `firm_owner_id`.
  - `id` string, uuid
  - `label` string: How you will recognise this provider later (1–60).
  - `kind` 'opensanctions_compatible': Shape of the provider's API. Covers any endpoint exposing an equivalent /match.
  - `base_url` string: Your provider's endpoint (validated against SSRF).
  - `key_fingerprint` string, nullable: NON-reversible hash of the credential (e.g. `sha256:a1b2c3d4`). Not head+tail: on a short key, showing start and end reveals almost all of it. The credential itself NEVER leaves.
  - `lists` string[]: The lists YOU declare as contracted. Shown to the reader verbatim. We do NOT verify them: the report says 'according to what your provider covers', never 'this is covered'.
  - `enabled` boolean
  - `last_verified_at` string, date-time, nullable
  - `created_at` string, date-time
  - `updated_at` string, date-time

## Other responses

- `400`: MISSING_LABEL · MISSING_BASE_URL · MISSING_API_KEY · UNSUPPORTED_KIND · UNSAFE_BASE_URL · INVALID_LISTS · MISPLACED_CREDENTIAL (the credential was sent under another name) · INVALID_JSON
- `409`: LABEL_ALREADY_EXISTS (a provider with that label already exists for this firm)
- `503`: CIPHER_UNAVAILABLE — credential encryption is not configured on this deployment. The secret is NOT stored in the clear 'until it is configured'.

---

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