API v1 · Stable

API Reference

Screen names against the OFAC SDN list. Every response carries a confidence score, a recommended action, and an Ed25519-signed receipt you can verify offline.

Introduction

The Sigeel API is a REST API that screens individual and entity names against the US Treasury OFAC Specially Designated Nationals (SDN) list. It returns ranked matches with a 0–100 confidence score, a recommended action, and a cryptographically signed receipt — so every lookup becomes an audit artifact.

Base URL

https://api.sigeel.com

Content type

application/json

Data source

OFAC SDN · rebuilt monthly

Typical latency

~50–150 ms warm

Authentication

Authenticate every request with your API key in the X-API-Key header. Keys are prefixed sk_live_ for production and sk_test_ for sandbox.

X-API-Key: sk_live_your_api_key_here

Never expose your key in client-side code. Keys grant full access to your account's quota. If a key is compromised, rotate it immediately from your dashboard — old keys are revoked instantly.

Rate limits

Limits are applied per API key. When you exceed your limit the API returns 429 Too Many Requests with a Retry-After header (seconds).

Tier Monthly quota Rate limit Overage
Free1005 / minBlocked
Starter1,00030 / min$0.01 / call
Pro10,000100 / min$0.01 / call
Ultra50,000300 / min$0.01 / call
Enterprise250,000600 / min$0.01 / call

Quickstart

One request. One response. Signed and verifiable.

quickstart.sh
curl -X POST https://api.sigeel.com/screen \
  -H "X-API-Key: sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Victor Bout", "min_score": 70}'

POST /screen

Screen a name against the OFAC SDN list. Returns ranked matches with scores, recommended actions, and a signed receipt.

Auth: X-API-Key
Body: application/json
Avg latency: ~50–150ms

Request body

Field Type Required Description
name string required The name to screen. 2–500 chars. Any language. Diacritics, inverted order, and punctuation are normalized automatically.
min_score number optional Return only matches with score ≥ this value. Range 0–100. Default 50.
limit integer optional Max matches returned. Range 1–50. Default 10.
entity_type string optional Filter by "individual", "entity", or "vessel". Default: all.

Example request

curl -X POST https://api.sigeel.com/screen \
  -H "X-API-Key: sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Victor Bout",
    "min_score": 70,
    "limit": 5
  }'

Example response 200 OK

response.json
{
  "body": {
    "query": "Victor Bout",
    "normalized_query": "victor bout",
    "match_count": 1,
    "matches": [{
      "score": 93.1,
      "primary_name": "BOUT, Viktor Anatoljevitch",
      "matched_name": "viktor anatoljevitch bout",
      "matched_on": "primary",
      "entity_type": "individual",
      "sdn_id": "12345",
      "programs": ["SDGT", "UKRAINE-EO13662"],
      "recommended_action": "manual_review",
      "aliases": [
        "BOUT, Victor",
        "BUTT, Viktor",
        "BOUT, Viktor Anatolyevich"
      ]
    }],
    "list": {
      "source": "OFAC SDN",
      "entity_count": 19457,
      "variant_count": 44074,
      "built_at": "2026-10-01T00:00:00Z"
    },
    "usage": {
      "month_to_date": 142,
      "quota": 10000,
      "overage": 0
    }
  },
  "signature": {
    "alg": "Ed25519",
    "key_id": "pk_2026_10",
    "public_key_b64": "MCowBQYDK2VwAyEA…",
    "signature_b64": "9f2a…",
    "signed_at": "2026-10-19T14:32:01Z"
  }
}

Response fields

FieldTypeDescription
body.querystringThe original name as submitted.
body.normalized_querystringNormalized form used for matching (lowercase, diacritics stripped, punctuation removed).
body.match_countintegerNumber of matches in this response.
body.matchesarrayArray of Match objects, ranked by score descending.
body.listobjectMetadata about the SDN list build used for this screening.
body.usageobjectQuota usage: month_to_date, quota, overage.
signatureobjectEd25519 signature over canonical JSON of body. See verification.
GET /pubkey

Returns the current Ed25519 public key used to sign responses. Use this to verify any receipt offline. Public — no auth required.

{
  "alg": "Ed25519",
  "key_id": "pk_2026_10",
  "public_key_b64": "MCowBQYDK2VwAyEA3x8Z...",
  "valid_from": "2026-10-01T00:00:00Z",
  "rotates_at": "2027-01-01T00:00:00Z"
}

Key rotation happens quarterly. Old keys remain valid for verification of previously-signed receipts. Match key_id from a receipt to select the right key.

GET /health

Liveness and readiness check. Public — no auth required.

{
  "status": "ok",
  "list_loaded": true,
  "entity_count": 19457,
  "list_built_at": "2026-10-01T00:00:00Z",
  "uptime_s": 1843221
}

Match object

Each item in body.matches is a Match object.

FieldTypeDescription
scorenumber0–100 confidence. See interpretation.
primary_namestringThe primary name on the SDN record, in OFAC's official format.
matched_namestringThe exact alias or primary name that produced this match (normalized).
matched_onstring"primary" or "alias".
entity_typestring"individual", "entity", or "vessel".
sdn_idstringOFAC SDN number. Use to cross-reference with Treasury's own records.
programsstring[]Sanctions programs (e.g. "SDGT", "UKRAINE-EO13662").
recommended_actionstring"escalate", "manual_review", or "clear".
aliasesstring[]All known aliases for this SDN record.

Score interpretation

Scores are calibrated so you can act on them consistently. The recommended_action field encodes the same thresholds so you don't have to hard-code them.

ScoreRecommended actionMeaning
95 – 100 escalate Strong match. Treat as potential SDN hit — halt and escalate through your compliance process.
70 – 94 manual_review Possible match. Route to a human reviewer with the full SDN record.
< 70 clear Below threshold. Only returned if min_score is set lower than 70.

A "clear" result does not confirm someone is unsanctioned — it means no candidate exceeded the score threshold against the current list.

Receipt verification

Every response is signed with Ed25519 over a canonical JSON representation of the body. This means you can prove months later that a specific screening happened, with exactly these results, against a specific SDN build — without trusting our servers.

Canonical form

  • JSON keys sorted lexicographically (byte order).
  • No whitespace between tokens: {"a":1,"b":2}.
  • UTF-8 encoded, no BOM.
  • Numbers serialized per ECMAScript Number.prototype.toString (no trailing zeros, no + sign).

Verify in code

import json, base64
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

def verify_receipt(receipt, public_key_b64):
    body = receipt["body"]
    sig  = base64.b64decode(receipt["signature"]["signature_b64"])
    pub  = base64.b64decode(public_key_b64)

    canonical = json.dumps(
        body, sort_keys=True, separators=(",", ":"),
    ).encode("utf-8")

    Ed25519PublicKey.from_public_bytes(pub).verify(sig, canonical)
    return True

Error codes

All errors return JSON: { "error": { "code": "...", "message": "..." } }

{
  "error": {
    "code": "invalid_api_key",
    "message": "API key is missing or invalid."
  }
}
HTTPCodeDescription
400invalid_requestMalformed JSON or missing required field.
401invalid_api_keyMissing or invalid X-API-Key.
403key_suspendedKey exists but has been suspended (e.g. payment issue).
422validation_failedField is present but invalid (name too short, min_score out of range, etc.).
429rate_limit_exceededToo many requests. Check Retry-After header.
429quota_exhaustedFree tier quota used up. Upgrade to continue.
500internal_errorUnexpected server error. Retry with exponential backoff.
503list_unavailableSDN list is being rebuilt. Typically resolves within 60 seconds.

Best practices

  • →
    Set min_score to 70 or higher in production. Lower thresholds surface weak matches that waste reviewer time.
  • →
    Screen on the exact name given to you, unmodified. Sigeel does all normalization. Pre-normalizing loses signal.
  • →
    Store the full receipt envelope, not just the matches. The signature + list.built_at is your audit artifact.
  • →
    Verify signatures on ingest if you're building an audit pipeline. It costs microseconds and closes the loop.
  • →
    Retry 5xx with exponential backoff. Do not retry 4xx. Do respect Retry-After on 429.
  • →
    Cache the pubkey for 24 hours. It rotates quarterly. Match key_id on receipts to select the right one.
  • →
    Treat results as input to a human decision, not a final determination. See the compliance disclaimer on the home page.

Changelog

v1.3 2026-10-01
  • Added entity_type filter to POST /screen.
  • body.usage now includes overage.
v1.2 2026-07-15
  • Added matched_on field to Match objects.
  • Improved alias normalization for Cyrillic transliterations.
v1.1 2026-04-01
  • Ed25519 signing on every response. Backwards-compatible: signature is an additive field.
  • Added GET /pubkey endpoint.
v1.0 2026-01-15
  • Initial public release. POST /screen and GET /health.

Ready to ship?

Grab a key and make your first screening in under a minute.

Get your API key