# Greylist-Belarus API

> Programmatic KYC lookup against the para2022 / luka.zone register of persons
> involved in political repressions in Belarus and crimes against humanity in
> Ukraine. Intended for KYC partners (banks, fintechs, exchanges, brokerages,
> payment service providers, online platforms) to flag onboarding requests.
> The API returns a confidence-scored match with the evidence behind it; it
> does not auto-block. Final compliance decisions remain the partner's
> responsibility.

## Conventions for AI agents

- Base URL: `https://api.luka.zone`
- All endpoints are versioned under `/v1/`.
- Authentication: every authenticated endpoint requires the header
  `Authorization: Api-Key <prefix>.<secret>`. Keys are issued manually by
  emailing `contact@luka.zone` with the company name, intended use case and
  expected query volume. The raw secret is shown only once at issue time and
  must be stored in the partner's secrets manager.
- All request and response bodies are `application/json; charset=utf-8`.
- All timestamps are ISO 8601 UTC.
- Names and string identifiers may be in Latin, Cyrillic, or Belarusian
  Łacinka script. The matching engine handles transliteration internally.
- Rate limit: 60 requests/minute per key (basic tier). `429 Too Many Requests`
  is returned with `Retry-After` when exceeded. Higher volumes negotiable.
- Every query is logged for abuse detection and audit.
- Input data is encrypted at rest and retained only for operational purposes
  — this is a lookup service, not a data store.

## Endpoints

- `POST /v1/match` — Submit identifiers (any combination of name, date of
  birth, personal ID, phone, email, Telegram ID, address). Returns up to 5
  scored matches with a top-level `decision` of `clear`, `review`, or
  `likely_match`. Use `decision` as a signal — do not auto-block on
  `review` or `likely_match`; route them to human review.
- `GET /v1/match/{person_id}` — Full evidence bundle for a flagged person:
  crime description, source citations, translations, profile URL, photo URL.
  Use this after a `POST /v1/match` returned a candidate the partner wants
  to inspect in depth.
- `GET /v1/health` — Liveness probe and database freshness timestamp. No
  authentication required. Safe to poll for monitoring.

## Example: POST /v1/match

Request:

```http
POST /v1/match HTTP/1.1
Host: api.luka.zone
Authorization: Api-Key <prefix>.<secret>
Content-Type: application/json

{
  "last_name": "Лукашенко",
  "first_name": "Александр",
  "date_of_birth": "1954-08-30",
  "partner_reference": "tx_abc123"
}
```

Response (`200 OK`):

```json
{
  "request_id": "a3f1c4...",
  "partner_reference": "tx_abc123",
  "decision": "review",
  "matches": [
    {
      "person_id": "550e8400-...",
      "score": 0.72,
      "matched_fields": [
        { "field": "last_name", "method": "phonetic", "similarity": 0.95 },
        { "field": "date_of_birth", "method": "exact", "similarity": 1.0 }
      ],
      "summary": {
        "full_name": "Лукашенко Александр Григорьевич",
        "category": "executive",
        "region": "MINSK_CITY",
        "sources_count": 47,
        "profile_url": "https://luka.zone/person/550e8400-..."
      }
    }
  ],
  "checked_at": "2026-04-24T10:15:00Z"
}
```

## Decision semantics

- `clear` — no candidate above the review threshold. Safe to proceed with
  onboarding. Always still subject to the partner's other KYC checks.
- `review` — at least one candidate at moderate confidence. Route to a human
  reviewer; do not auto-block.
- `likely_match` — high-confidence candidate. Route to a human reviewer with
  priority; still do not auto-block. Fetch `GET /v1/match/{person_id}` for
  full evidence before any user-facing action.

## Errors

- `400 Bad Request` — malformed JSON or unknown field.
- `401 Unauthorized` — missing or malformed `Authorization` header.
- `403 Forbidden` — valid header but the key has been revoked, or the IP is
  outside the partner's allow-list.
- `404 Not Found` — `person_id` does not exist in the database.
- `422 Unprocessable Entity` — request was syntactically valid but no usable
  identifier was provided. Submit at least one of: full name, date of birth,
  personal ID, phone, email, Telegram ID.
- `429 Too Many Requests` — rate limit exceeded. Honor `Retry-After`.
- `5xx` — transient backend error. Retry with exponential backoff.

## Reference

- Landing page: https://api.luka.zone/
- Quickstart: https://api.luka.zone/#quickstart
- Endpoint table: https://api.luka.zone/#endpoints
- Rate limits & terms: https://api.luka.zone/#terms
- Source database: https://luka.zone/ (search UI), https://para2022.org/ (mirror)
- Contact: contact@luka.zone

## Out of scope

- This API does not return raw photos or PII beyond what is published on
  https://luka.zone/ for the matched person.
- This API is not a sanctions list. It overlaps with EU/US/UK/Canada/Swiss
  sanctions on Belarusian officials but is not a substitute for screening
  against authoritative sanctions sources.
- The API does not make compliance decisions. It returns a scored signal —
  the partner remains responsible for the final onboarding outcome.
