DEVELOPER DOCUMENTATION
Sanctions API reference
The MatchAudit Sanctions API attempts all supported name-searchable sanctions and restricted-party lists, including OFAC SDN and Non-SDN, EU consolidated, UK Sanctions List, UN, Swiss SECO, Canadian, Australian and national sources, plus export-control, terrorism and debarment lists. It returns potential matches per list, per-list availability, data dates and a screening receipt.
This reference covers the standalone name-screening endpoint and its separate API keys. Organization-bound screening, cases and webhooks are documented separately. Workspace API documentation
Authenticate from your server
Authentication#
Send your API key in the x-api-key header, or as Authorization: Bearer <key>. Keys start with ma_live_ followed by 64 hexadecimal characters. Use the key from your servers only; never put it in a browser or mobile app.
Use your MatchAudit login to open /sanctions/api/keys. Registration alone does not grant live API access. An administrator assigns provisioned credentials to your account; you can then generate or rotate an active assigned key and revoke a key. The full secret is shown once. Rotation preserves the key ID and quota, and cannot restore suspended or revoked access. Only the hash, prefix and last four characters are stored.
Legacy manually issued keys can also use a single-use reveal link valid for 30 minutes. Issuing a replacement link invalidates the previous key and unused links before sending the new link. Account rotation or revocation also invalidates outstanding reveal links.
Use a separately issued Sanctions API key. Organization keys used by /api/v1/screen do not grant access here. Query-string credentials are not accepted. This endpoint is intended for server-to-server calls and does not provide a browser CORS preflight handler.
Send a name or a batch
Endpoint#
POST https://matchaudit.io/api/v1/sanctions/screen with a JSON object: {"names": ["…", "…"]} or {"name": "…"}. Up to 100 names per request; each name must be a string containing 2 to 200 Unicode code points after NFC normalization and trimming. When names is an array it takes precedence over name, including when the array is empty. Results preserve input order and duplicate names each consume a check.
Only name and names select the screening inputs. Additional properties are ignored: entity types, countries, sources, thresholds and other matching options cannot be configured through this endpoint. Each live request attempts the supported catalogue. This API does not implement Idempotency-Key replay handling; repeating a successful request consumes checks again.
| Parameter | Type | Description |
|---|---|---|
name | string | A single person or company name. Ignored when names is an array. |
names | array<string> | A batch of up to 100 names. Takes precedence over name. Every name follows the normalization and length rules above. |
Read the returned fields
Response fields#
| Field | Meaning |
|---|---|
results[] | One entry per name, in the order you sent them. |
results[].input | The name as screened, NFC-normalized and trimmed. |
results[].potentialMatch | true if at least one list returned a potential match. false does not mean every source was searched; inspect each list's status. |
results[].lists[] | One entry per list: key, name, status (searched or unavailable), dataDate, version, matches[]. |
lists[].status | unavailable means the list could not be loaded for this request; treat the result for that list as missing. |
lists[].dataDate | When MatchAudit last fetched the list (ISO 8601, UTC), or null if not known. |
matches[].listedName | The name of the listed entry that is similar to your input. |
matches[].programme | Programme or regime of the entry, where the list provides it. |
matches[].reference | The source record's reference or ID, where supplied, or null. Examples: OFAC uid, EU reference number, UK unique ID, UN reference number. |
matches[].officialUrl | Link to the official source for the entry, or for the list. |
matches[].score | Similarity from 0 to 1; higher is more similar. An exact full-name match scores 1. |
matches[].aliases | Live results: array of aliases supplied by the existing engine evidence; empty when absent. Not present in synthetic sandbox results. |
matches[].entityType | Live results: engine entity type, or unknown. This is response metadata, not an input filter. |
matches[].country | Live results: source nationality/country string, or null when absent; not a jurisdiction restriction. |
matches[].details | Live results: supplied date fields and known addresses; empty object when absent. |
Inspect per-list availability
Lists screened#
Every live request attempts all supported named-party sources below. Missing or unloadable datasets are returned as unavailable, never as a no-match result. The table shows each source's current index data date; each response carries per-list dates and versions. Combined OFAC and duplicate DDTC aliases are represented by their component/canonical sources to avoid searching the same dataset twice.
| key | List | Data date (UTC) |
|---|---|---|
ofac_sdn | OFAC SDN List (US) | 2026-11-14T18:06:38.905Z |
eu | EU consolidated financial sanctions | 2026-11-14T18:02:08.208Z |
uk | UK Sanctions List | 2026-11-14T18:08:40.472Z |
un | UN Consolidated | 2026-11-14T18:08:43.351Z |
un_1988_taliban | UN 1988 Committee (Taliban) | not available |
seco | Switzerland (SECO) | 2026-11-14T18:08:04.652Z |
ofac_non_sdn | OFAC Non-SDN | 2026-11-14T18:06:41.162Z |
us_consolidated_sanctions | US Consolidated Sanctions (Treasury) | 2026-11-14T18:06:42.784Z |
csl | US Consolidated Screening List (CSL) | 2026-11-14T18:05:15.263Z |
us_csl_cmic | US CSL — CMIC | not available |
us_sam_exclusions | US SAM procurement exclusions | not available |
us_ddtc_itar | US State/DDTC — ITAR Debarred | not available |
us_state_nonprolif | US State — Nonproliferation Sanctions | not available |
us_state_fto | US State — Foreign Terrorist Organizations | 2026-11-14T18:08:55.295Z |
us_state_tel | US State — Terrorist Exclusion List |
Keep a record in your system
Screening receipt#
Every successful response contains a screening receipt that you can keep as a record of the screening in your own system:
- screeningId — a unique ID for this request (UUID).
- timestamp — when the screening ran (ISO 8601, UTC).
- lists[] — for each list its key, name, data date and version.
- engineVersion — the version of the MatchAudit screening service that answered.
MatchAudit builds the receipt from the response. The API does not write the names you send to its database or application logs, and it does not keep a copy of the receipt.
Handle allowance and request limits
Quota and headers#
One check is one name. A request with several names counts each name. Your plan's checks apply per monthly billing period, starting on the start date of your subscription period.
Successful customer-key responses and quota_exceeded responses carry X-Quota-Limit (checks in your plan per period) and X-Quota-Remaining (checks left in the current period). Other errors, sandbox calls and internal calls do not carry these headers. A request that exceeds the remaining allowance returns 429 quota_exceeded without screening any names. Checks are reserved before screening; the service attempts to refund the reservation if the engine throws an error.
Default limits: 60 requests per customer key per minute, and 600 requests per minute across public keys. Operators can configure SANCTIONS_API_KEY_RATE_PER_MIN and SANCTIONS_API_PUBLIC_CAP_PER_MIN; the API product page shows the active settings. Above them the API returns 429 with error rate_limited; wait a moment and retry. All configured tiers have a 100-name request cap and a monthly hard quota, with no automatic overages.
The shared public request cap covers customer and sandbox traffic. Unavailable lists still produce a successful response and consume the submitted name checks. Rate-limit and monthly-quota responses both use HTTP 429; inspect error to choose whether to back off or wait for the next billing period. Customer API rate-limit responses do not include Retry-After.
Configured request limits on this deployment
- 60
- requests per customer key / minute
- 600
- requests / minute shared across customer and sandbox keys
Use the error code to decide what to do next
Errors#
| Status | error | When |
|---|---|---|
400 | bad_request | Body is not valid JSON, or neither name nor names is given. |
400 | invalid_name | A name is shorter than 2 or longer than 200 characters after trimming. |
400 | too_many_names | More than 100 names in one request. |
401 | unauthorized | Missing, unknown or revoked API key. |
402 | key_suspended | The key is suspended because of a billing problem. |
429 | rate_limited | Too many requests in a short time. |
429 | quota_exceeded | The monthly check limit of your plan is reached. |
500 | engine_error | The screening engine failed; a refund of reserved customer checks is attempted. |
503 | unavailable | A dependency is temporarily unavailable; retry later. |
Error bodies are JSON: {"error": "<code>", "message": "<text>"}.
Understand what a potential match means
Matching method and limitations#
- Names are normalised before comparison: transliterated to Latin script where possible, lower-cased, accents and punctuation removed.
- The name field also accepts vessel, aircraft or wallet identifiers. The shared engine checks exact identifiers where the source records supply them; an exact identifier match scores 1.
- Candidates are found by approximate (fuzzy) search over each entry's text, which also includes fields such as addresses, dates of birth and identifiers.
- A candidate is reported as a potential match only when your input also matches the entry's name or one of its aliases: exactly, by all name words, by first and last name, by several shared words, by the exact word for a one-word input, or by close spelling.
- Approximate matching can show potential matches that are not the same person or organisation (false positives) and can miss entries spelled differently, transliterated differently, or entered with only part of the name.
- Coverage is limited to supported named-party datasets that can be loaded for the request. Country/sector policy rules, PEP data, adverse media and ongoing monitoring are not included. Sources can overlap, and a record's restrictions depend on its source; a match is not automatically an asset-freeze designation.
- A potential match is not a confirmed designation. Compare further details, such as date of birth, address or registration number, with the official source.
Supporting website and operator routes
Website and operational endpoints#
The screening endpoint above is the only screening endpoint for customer API keys. The following supporting routes are not additional customer screening capabilities. The older organization-bound /api/v1/screen API and its webhook routes are a separate product surface.
| Method / path | Authentication / input | Response |
|---|---|---|
POST /api/sanctions/check | Same-origin website request; JSON {name, website?}; website is a honeypot. One name, 2–200 characters. Maximum body 2,048 bytes. Default 5 search attempts/IP/UTC day (FREE_CHECK_PER_IP_PER_DAY) and 60/minute globally (FREE_CHECK_GLOBAL_CAP_PER_MIN). | {ok:true, lists, screenedAt, quota:{limit,remaining,resetAt}}; {ok:false,error,quota?} with 400 invalid input/honeypot, 403 origin, 413 oversized body, 429 daily limit, 502 screening dependency, 503 abuse controls/global cap; 404 when disabled. 429 carries Retry-After until next UTC midnight. No-store, noindex. |
POST /api/sanctions/contact | Same-origin contact form; required topic (feature/contact/api), email (max 254 chars), message (10–2,000 chars); optional name/company (max 100 chars), product, website honeypot. Feature requests require a product. 5 submissions/IP/hour. | {ok:true}; 400 {ok:false,errors:<field map>}; localized {ok:false,error} with 403 origin, 429 rate limit, 502 mail delivery, 503 configuration/abuse-control dependency, or 404 when disabled. This route delivers contact email, not screening. |
POST / OPTIONS /api/contact | Existing general contact form used for live-key enquiries: JSON or multipart, required name/email/message; optional company, topic, source and allowlisted attachment up to 5 MB. No customer API key. | POST {ok:true,id}; 400 validation, 502 mail provider, 503 missing provider configuration, 500 exception. OPTIONS returns 204 with CORS headers. This sends contact details to sales; it does not screen names or issue keys automatically. |
GET /sanctions-screening/key/:token | Secret link token. GET does not consume the link. | HTML key-reveal form; no-store, noindex, no-referrer. |
Test against synthetic fixtures
Sandbox#
When the sandbox is enabled and a public key is configured, it is shown below. Assign that key to MATCHAUDIT_API_KEY to run the synthetic examples. The sandbox screens only an invented test list and returns results and a receipt, with fewer match-detail fields than live results. It allows 100 requests per IP per UTC day, is also subject to the shared public rate cap, and has no monthly quota headers. Live keys attempt the supported sanctions and restricted-party catalogue shown above.
Names in the synthetic test list: Sandbox Test Person Alpha, Sandbox Example Trading Ltd, Sandbox Demo Shipping Co. Names that are not similar to these return no potential match. The sandbox uses a simplified matcher with the same fuzzy settings and without the name check, so borderline results can differ from live screening.
A public synthetic sandbox key is not enabled on this deployment. Contact us to discuss testing.