Integration tutorial

Sanctions screening API with Python

Run a Python sanctions screening API example with no extra packages. Save results, handle failed requests, and retry the same check safely.

Updated

250 free live screenings. One lifetime allowance. No credit card required.
Run the example
python3 screen.py

Copy the complete code below into a new file.

Runtime
Standard library

Call the API from your Python application.

Failures
HTTPError

Inspect HTTP status, code, and requestId.

1. Prepare Python and your sandbox key

Use Python 3. This example uses only json, os, re, sys and urllib from the standard library, so there is no pip install step. Create a sandbox key with screenings:write and results:read in Dashboard → API keys. Follow the quickstart if this is your first API request.

In a trusted terminal, set your sandbox key and a unique REQUEST_KEY using the commands below. Keep the same request key and body when retrying one operation; generate a new key for a new screening. In a deployed worker, supply the API key through server-side environment configuration, never a browser or committed file.

1. Prepare Python and your sandbox key
export SANCTIONSKIT_API_KEY='YOUR_LIVE_KEY'
export REQUEST_KEY="$(python3 -c 'import uuid; print(uuid.uuid4())')"

2. Copy the complete screening example

Save this as screen.py. It submits the invented subject Alex Morgan to sandbox@1 using HTTPS, an Authorization header and a 15-second timeout. The JSON is encoded as UTF-8. No external API client or repository checkout is required.

urllib raises HTTPError for failed HTTP responses, so the example handles that separately from a completed screening. It checks the success body before printing an ID and status. Error output is limited to HTTP status, a code and a request ID. Do not replace that with logging of the submitted subject or the full response.

2. Copy the complete screening example
# Save as screen.py. Run with Python 3: python3 screen.py
import json
import os
import re
import sys
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen

api_key = os.environ.get('SANCTIONSKIT_API_KEY')
request_key = os.environ.get('REQUEST_KEY')
if not api_key or not request_key:
    raise SystemExit('Set SANCTIONSKIT_API_KEY and REQUEST_KEY first.')

def safe_field(value):
    return value if isinstance(value, str) and re.fullmatch(r'[a-zA-Z0-9_.:-]{1,128}', value) else 'unknown'

request = Request(
    'https://www.sanctionskit.com/api/v1/screenings',
    method='POST',
    headers={
        'Authorization': 'Bearer ' + api_key,
        'Content-Type': 'application/json',
        'Idempotency-Key': request_key,
    },
    data=json.dumps({
        'subject': {'name': 'Alex Morgan', 'entityType': 'person', 'birthDate': '1984'},
        'package': 'sandbox@1',
    }).encode('utf-8'),
)

try:
    with urlopen(request, timeout=15) as response:
        payload = json.load(response)
    result = payload.get('data') if isinstance(payload, dict) else None
    if (not isinstance(result, dict) or not isinstance(result.get('id'), str)
            or not isinstance(result.get('matches'), list)
            or result.get('status') not in ('potential_match', 'no_match')):
        raise ValueError('Unexpected response format.')
    # Keep the full result in your authorized workflow, not application logs.
    print(json.dumps({'id': result['id'], 'status': result['status']}))
    # potential_match: route to review. no_match: retain coverage and versions.
    # Complete any required policy checks and human business review for either outcome.
except HTTPError as error:
    try:
        body = json.load(error)
        detail = body.get('error', {}) if isinstance(body, dict) else {}
        detail = detail if isinstance(detail, dict) else {}
    except (ValueError, OSError):
        detail = {}
    print('HTTP', error.code, 'code=' + safe_field(detail.get('code')),
          'requestId=' + safe_field(detail.get('requestId')), file=sys.stderr)
    raise SystemExit(1)
except (URLError, TimeoutError, OSError, ValueError):
    print('The request did not complete. Keep the same REQUEST_KEY and body when retrying.', file=sys.stderr)
    raise SystemExit(1)

3. Run it and review the outcome

Run the command below from the folder containing screen.py. A successful run prints JSON with id and status. Inspect the full result in sandbox history. A potential_match needs investigation; a no_match applies only to the selected coverage and request. The false-positive review guide explains how to compare evidence.

An error exits with code 1. For 401 or 403, check the key and scopes. For invalid input, correct the request before making a new operation. For a timeout or recoverable server error, retain the original REQUEST_KEY and body. Implement bounded retries in your application and follow the error reference; do not turn exceptions into no_match.

3. Run it and review the outcome
python3 screen.py

4. Add coverage, batches and events

For production, use a production API key and choose sources or a versioned package from source discovery. Keep unknown subject fields absent and preserve the precision of dates you actually know. Save the returned ID, coverage and versions in your authorized workflow rather than application logs.

Use batch screening when processing a portfolio, and monitoring when a retained subject needs repeated checks. For webhook receivers, verify the documented signature over the original bytes, enforce the timestamp tolerance and deduplicate event IDs before acting. The webhook guide describes the verification contract independently of language.

Frequently asked questions

Which Python package should I install for this screening example?

None is required. The example uses Python 3 and the standard json, os, re, sys, and urllib modules. Save it as screen.py, configure your sandbox key and operation key, and run it from a trusted terminal or backend worker.

Why does the Python example catch HTTPError separately?

urllib raises HTTPError for failed HTTP responses. That failure must stay separate from a completed screening. The example also checks the success body before reading its status, so a decoded error or invalid response cannot become no_match.

What does exit code 1 mean after running screen.py?

The example did not establish a completed screening outcome. Check the key and scopes for 401 or 403, correct invalid input, or recover a timeout with the saved request key and body. Do not turn the exception into customer approval.

Can the Python sandbox example be changed to production by changing only the key?

No. Use a production key and replace sandbox@1 with available source IDs or an exact production package. Confirm the source scope and supported subject type. Save coverage and versions with the screening ID, and keep the subject’s unknown fields absent.

KEEP BUILDING

Where to go next