{"openapi":"3.1.0","info":{"title":"SanctionListCheck API","version":"1.0.0","termsOfService":"https://sanctionlistcheck.com/terms","description":"Screen names against the sanctions lists in one merged snapshot. Every screen returns a screening record: snapshot version, per-source data-as-of, engine version and a record id you can fetch again. Results are an aid for your own review, never a clearance."},"servers":[{"url":"https://sanctionlistcheck.com"}],"security":[{"bearerAuth":[]}],"paths":{"/v1/keys":{"post":{"operationId":"createKey","summary":"Request an API key by email","description":"Sends a new API key with 100 free credits to the email address. The key is delivered only by email, never in the response. Every valid address gets the same 202, whether a key was sent or not (1 key per email address for life, no disposable domains). Limit: 3 new keys per network per 24 hours.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKeyRequest"}}}},"responses":{"202":{"description":"Accepted. If the address is eligible, the key is on its way by email.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyRequestAccepted"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"403":{"description":"turnstile_required or turnstile_failed: the browser check of the key form is missing (when required) or failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"413":{"$ref":"#/components/responses/BodyTooLarge"},"415":{"description":"unsupported_media_type: the Content-Type is not application/json.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"key_limit_per_ip: too many new keys from this network in 24 hours. key_limit_unverified: too many keys were created today (UTC) without the browser check of the key form; create the key with the form on https://sanctionlistcheck.com/developers. Once a limit is reached, every address gets this answer.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/KeyLimitPerIp"},{"$ref":"#/components/schemas/KeyLimitUnverified"}]}}}},"503":{"description":"API keys cannot be issued right now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/keys/me":{"delete":{"operationId":"deleteKey","summary":"Delete this API key and its records","description":"Revokes the key at once, removes its email address and hard-deletes all its screening records. The credit ledger is kept for accounting. Remaining credits are lost.","responses":{"204":{"description":"Deleted."},"401":{"$ref":"#/components/responses/Unauthorized"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/screen":{"post":{"operationId":"screen","summary":"Screen names and store a screening record","description":"Sanctions screening. Screens 1 to 100 names against one pinned sanctions snapshot and stores a screening record. The response carries the record id, the snapshot version, the data-as-of date of each source list and the engine version. Costs 1 credit per name, charged before screening; a screen that cannot complete gives the credits back. Hits at or above the threshold are returned for human review; no hit is not a clearance.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[\\x21-\\x7e]+$"},"description":"Optional. A retry within 24 hours with the same key and the same body returns the stored record and charges nothing; the same key with a different body is a 422. Without this header, only a retry with the same body (names and threshold) within 1 hour does the same; after 1 hour the same body is a new, charged screen against the current lists. Send a new key to force a new, charged screen."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenRequest"}}}},"responses":{"200":{"description":"Screened, the record is stored. On a replay: the stored record, credits_charged 0, header Idempotent-Replayed: true.","headers":{"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Present only on a replay."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenResponse"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Not enough credits. Nothing was charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsufficientCredits"}}}},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"description":"in_progress: a request with the same Idempotency-Key or body is still running. record_id names it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"$ref":"#/components/responses/BodyTooLarge"},"422":{"description":"idempotency_key_reused: this Idempotency-Key was already used with a different body. record_id names the first request. Nothing was charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"description":"Screening or record storage is unavailable. credits_refunded says whether the credits came back now; if not, a scheduled reconcile refunds them. Keep record_id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenFailure"}}}}}}},"/v1/records":{"get":{"operationId":"listRecords","summary":"List screening records (metadata only)","description":"Records of this key, newest first. Metadata only, no names or hits. Page with next_cursor.","parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"screened_at >= from."},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"screened_at < to."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"next_cursor from the previous page."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"One page of records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/records/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9A-HJKMNP-TV-Z]{26}$"}}],"get":{"operationId":"getRecord","summary":"Fetch a stored screening record","description":"Returns a screening record created by the same API key. The metadata is kept. The screened names and hits are kept until payload_expires_at (the key's retention_days, capped by the service); after that, results is null and payload_status is \"expired\".","responses":{"200":{"description":"The record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningRecord"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"No record with this id for this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"description":"The stored record could not be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteRecord","summary":"Delete a screening record","description":"Hard-deletes the record, its names and hits. Same key only.","responses":{"204":{"description":"Deleted."},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"No record with this id for this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record's credits are still being settled. Try again later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/me":{"get":{"operationId":"me","summary":"Credit balance and key details","responses":{"200":{"description":"The key's details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"429":{"$ref":"#/components/responses/RateLimited"}}},"patch":{"operationId":"updateMe","summary":"Set how long records keep names and hits","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMeRequest"}}}},"responses":{"200":{"description":"Updated. Applies to existing records too.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"413":{"$ref":"#/components/responses/BodyTooLarge"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/packs":{"get":{"operationId":"listPacks","summary":"Credit packs and checkout URLs","description":"Public. Without Authorization, checkout_url is null. With a valid key, each checkout_url opens a Paddle checkout bound to that key for 24 hours.","security":[{},{"bearerAuth":[]}],"responses":{"200":{"description":"The packs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Packs"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/openapi.json":{"get":{"operationId":"openapi","summary":"This OpenAPI document","security":[],"responses":{"200":{"description":"The OpenAPI 3.1 document.","content":{"application/json":{"schema":{"type":"object"}}}},"405":{"$ref":"#/components/responses/MethodNotAllowed"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An API key that starts with slc_live_."}},"responses":{"InvalidRequest":{"description":"The request is not valid (body, JSON or query).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"MethodNotAllowed":{"description":"This method is not allowed on this path. See the Allow header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"BodyTooLarge":{"description":"The request body is larger than 256 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BodyTooLarge"}}}},"RateLimited":{"description":"Too many requests for this key in the current minute. See the Retry-After header.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string"},"details":{"type":"array","items":{"type":"string"}},"record_id":{"type":"string"}}},"RateLimited":{"type":"object","required":["error","limit_per_minute","retry_after_seconds"],"properties":{"error":{"type":"string","const":"rate_limited"},"limit_per_minute":{"type":"integer"},"retry_after_seconds":{"type":"integer","minimum":1}}},"KeyLimitPerIp":{"type":"object","required":["error","limit","window_hours"],"properties":{"error":{"type":"string","const":"key_limit_per_ip"},"message":{"type":"string"},"limit":{"type":"integer"},"window_hours":{"type":"integer"}}},"KeyLimitUnverified":{"type":"object","required":["error","limit","window"],"properties":{"error":{"type":"string","const":"key_limit_unverified"},"message":{"type":"string"},"limit":{"type":"integer"},"window":{"type":"string","const":"utc_day"}}},"BodyTooLarge":{"type":"object","required":["error","max_bytes"],"properties":{"error":{"type":"string","const":"body_too_large"},"max_bytes":{"type":"integer"}}},"InsufficientCredits":{"type":"object","required":["error","balance","needed","buy_url"],"properties":{"error":{"type":"string","const":"insufficient_credits"},"balance":{"type":"integer","minimum":0},"needed":{"type":"integer","minimum":1},"buy_url":{"type":"string","format":"uri","description":"A checkout page bound to this key, valid 24 hours."}}},"ScreenFailure":{"type":"object","required":["error","message","record_id","credits_charged","credits_refunded"],"properties":{"error":{"type":"string","enum":["snapshot_unavailable","screening_unavailable","record_persist_failed"]},"message":{"type":"string"},"record_id":{"type":"string"},"credits_charged":{"type":"integer","description":"Credits still charged now. 0 when the refund succeeded."},"credits_refunded":{"type":"integer"}}},"CreateKeyRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","maxLength":254},"lang":{"type":"string","maxLength":16,"description":"Language of the key email: en, cs, de, es, fr, it, nl, pl, fi or sv. Optional; any other value means en."}}},"KeyRequestAccepted":{"type":"object","required":["status"],"properties":{"status":{"type":"string","const":"sent_if_eligible"}}},"UpdateMeRequest":{"type":"object","required":["retention_days"],"properties":{"retention_days":{"type":"integer","minimum":1,"maximum":365}}},"Me":{"type":"object","required":["key_prefix","credits_balance","retention_days","effective_retention_hours"],"properties":{"key_prefix":{"type":"string"},"email":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"credits_balance":{"type":"integer","minimum":0},"rate_limit_per_minute":{"type":"integer"},"retention_days":{"type":"integer","minimum":1,"maximum":365,"description":"Days a record keeps names and hits. Default 90."},"effective_retention_hours":{"type":"integer","description":"min(retention_days x 24, the service cap)."},"ledger":{"type":"array","maxItems":10,"description":"The 10 newest credit changes, newest first.","items":{"$ref":"#/components/schemas/LedgerEntry"}}}},"LedgerEntry":{"type":"object","required":["delta","reason","ref","created_at"],"properties":{"delta":{"type":"integer"},"reason":{"type":"string","enum":["free_grant","screen","pack","refund","pack_refund","admin"],"description":"refund: a failed screen's credits given back (positive). pack_refund: pack credits taken back after a payment refund or chargeback (negative)."},"ref":{"type":["string","null"],"description":"Record id (screen, refund), Paddle transaction id (pack) or Paddle adjustment id (pack_refund)."},"created_at":{"type":"string","format":"date-time"}}},"Packs":{"type":"object","required":["purchase","credits_expire","packs"],"properties":{"purchase":{"type":"string","const":"one_time"},"credits_expire":{"type":"string","const":"never_while_key_active"},"credit_unit":{"type":"string"},"checkout":{"type":"string","description":"Present only without Authorization."},"packs":{"type":"array","items":{"$ref":"#/components/schemas/Pack"}}}},"Pack":{"type":"object","required":["id","name","credits","price","checkout_url"],"properties":{"id":{"type":"string","enum":["starter","growth","scale"]},"name":{"type":"string"},"credits":{"type":"integer","minimum":1},"price":{"type":"object","required":["amount","amount_minor","currency"],"properties":{"amount":{"type":"string","examples":["15.00"]},"amount_minor":{"type":"integer"},"currency":{"type":"string","const":"EUR"}}},"checkout_url":{"type":["string","null"],"format":"uri"}}},"ScreenInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"country":{"type":"string","maxLength":100,"description":"Optional context. A country that agrees with the list entry raises reviewPriority to HIGH; it never hides a hit."},"dob":{"type":"string","maxLength":100,"description":"Optional date of birth, ISO 8601. Same rule as country."},"type":{"type":"string","enum":["person","entity"],"description":"Optional. Lowers the score of hits of the opposite type."}}},"ScreenRequest":{"type":"object","required":["names"],"properties":{"names":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/ScreenInput"}},"threshold":{"type":"number","minimum":0.6,"maximum":1,"description":"Optional. Return only hits with score >= threshold. Default 0.6, the engine's own floor; a lower value is rejected."}}},"MatchedTokenPair":{"type":"object","required":["inputToken","candidateToken","similarity","idfWeight"],"properties":{"inputToken":{"type":"string"},"candidateToken":{"type":"string"},"similarity":{"type":"number"},"idfWeight":{"type":"number"}}},"ListEntry":{"type":"object","description":"The matched entry's data as the list publishes it. A null field: the list publishes none for this entry, unless the field is in unavailableFields.","required":["primaryName","entityType","dob","country","listingReason","unavailableFields"],"properties":{"primaryName":{"type":"string"},"entityType":{"type":["string","null"],"description":"individual, entity, vessel, aircraft or unknown."},"dob":{"type":["string","null"]},"country":{"type":["string","null"]},"listingReason":{"type":["string","null"],"description":"The listing reason or sanctions program, as the list states it."},"unavailableFields":{"type":"array","items":{"type":"string","enum":["entityType","dob","country","listingReason"]},"description":"Fields our data of this list does not carry at all. For these, null means unknown, not that the list publishes none."},"entryId":{"type":"string","description":"Batch report export only (2026-10-06). The list's own reference for the entry: the part of entityId after the first colon, e.g. 35096, EU.7510.16, RUS0251."},"officialUrl":{"type":["string","null"],"format":"uri","description":"Batch report export only (2026-10-06). The entry's page on the list owner's site. Only for OFAC_SDN entries (https://sanctionssearch.ofac.treas.gov/Details.aspx?id=<entryId>); null for every other list."}}},"ReportSummary":{"type":"object","description":"Batch report export only: the summary block of the JSON export. reviewRows* added 2026-10-06; of the reviewCount rows: reviewRowsAgreeing have a match whose country or date of birth agrees; reviewRowsStrong have a top score in the Strong band; reviewRowsPossibleOnly have Possible matches only (reviewRowsStrong + reviewRowsPossibleOnly = reviewCount). otherTypeCount added 2026-10-08: names in a column whose header says it holds people (for example Student, Applicant, or First name + Last name) whose matches are all list entries of type entity, vessel or aircraft. They are not in reviewCount or cleanCount; their matches are in the export's otherTypeMatches array (same form as matches; not in matches), and the CSV marks their rows report_section = only_company_vessel_aircraft (the last column until 2026-10-09, when band_note and name_score_before_cap were appended after it; review rows have review).","required":["headline","rowsScreened","cleanCount","reviewCount"],"properties":{"headline":{"type":"string"},"rowsScreened":{"type":"integer","description":"Rows in the file."},"namesScreened":{"type":"integer","description":"Rows with a name (added 2026-10-07)."},"emptyNameRows":{"type":"integer","description":"Rows whose name cell is empty: not screened and not counted as no match (added 2026-10-07). With several names per row: empty name cells."},"rowsInFile":{"type":"integer","description":"Rows screened, counted as spreadsheet rows; differs from rowsScreened when a row holds several names (added 2026-10-07). For a first-rows order the uploaded file has more rows: see firstRows."},"firstRows":{"type":["object","null"],"description":"Set when only the first rows of the uploaded file were screened (a website order for a file up to 20 % over its pack); null otherwise. Every row after spreadsheet row notScreenedAfterRow was not screened (added 2026-10-19).","properties":{"rowsCovered":{"type":"integer"},"rowsInUploadedFile":{"type":"integer"},"rowsNotScreened":{"type":"integer"},"notScreenedAfterRow":{"type":"integer"}}},"parties":{"type":"array","description":"Per name group when a row holds several names (added 2026-10-07); empty otherwise.","items":{"type":"object","required":["party","names","review","empty"],"properties":{"party":{"type":"string"},"names":{"type":"integer"},"review":{"type":"integer"},"empty":{"type":"integer"},"otherType":{"type":"integer","description":"Names of this group in otherTypeCount (added 2026-10-08)."},"oneWord":{"type":"integer","description":"Names of this group in oneWordCount (added 2026-10-08)."},"mutualMismatch":{"type":"integer","description":"Names of this group in mutualMismatchCount (added 2026-10-09)."},"dobCountryDiffers":{"type":"integer","description":"Names of this group in dobCountryDiffersCount (added 2026-10-09)."}}}},"cleanCount":{"type":"integer","description":"Names screened with no match."},"reviewCount":{"type":"integer"},"otherTypeCount":{"type":"integer","description":"Added 2026-10-08; see the description of this object."},"oneWordCount":{"type":"integer","description":"Added 2026-10-08: names in a column whose header says it holds people that have one word only, and no match is the same one-word name on a list. Not in reviewCount, cleanCount or otherTypeCount; their matches are in the export's oneWordMatches array (same form as matches), and the CSV marks their rows report_section = only_one_word."},"mutualMismatchCount":{"type":"integer","description":"Added 2026-10-09 (matcher 2.8): names in any column whose matches all have different words on both sides (each match row has mutualMismatch = true: the uploaded name and the list name each keep a word that pairs with nothing), and that are not in oneWordCount or otherTypeCount. Not in reviewCount or cleanCount; their matches are in the export's mutualMismatchMatches array (same form as matches), and the CSV marks their rows report_section = different_words_both_sides."},"dobCountryDiffersCount":{"type":"integer","description":"Added 2026-10-09 (E2.4): names whose matches all have a date of birth more than 2 years off (each match row has contextCheck.dobGapOver2Years = true: the date of birth differs, every item of the uploaded date-of-birth cell is read (its year written as 4 digits on their own, and every day it can mean, a circa value with its 2-year widening, on or before the report date), the list entry's date-of-birth data is read in full, and every reading of the uploaded date of birth is more than 2 calendar years from every reading of every date of birth in our data for the list entry) and a country that differs (contextCheck.country = differs, and every item of the uploaded country cell is read), and that are in no earlier section (oneWordCount, otherTypeCount, mutualMismatchCount). Not in reviewCount or cleanCount; their matches are in the export's dobCountryDiffersMatches array (same form as matches), and the CSV marks their rows report_section = dob_and_country_differ."},"reviewRowsAgreeing":{"type":"integer","description":"Of the reviewCount names: those with a match whose country or date of birth agrees (reviewPriority HIGH, or since 2026-10-09 a contextCheck that agrees)."},"reviewRowsStrong":{"type":"integer"},"reviewRowsPossibleOnly":{"type":"integer"}}},"Hit":{"type":"object","description":"One list entry that matched. Same fields as a row of the batch report's JSON export; the export row also has rowIndex, inputName, listDataAsOf, hitGroup, review and spreadsheetRow (the uploaded row's number as a spreadsheet app shows it, added 2026-10-05), and since 2026-10-06 contextCheck (ReportContextCheck), inputContext (ReportInputContext) and nameComparison (ReportNameComparison). In the export, reviewPriority is HIGH when the uploaded country or date of birth agrees with the list entry (since 2026-10-09, E2.4: a country that agrees does not make HIGH when contextCheck.dobGapOver2Years is true and every item of the uploaded country cell gives a country code). The CSV export has the same data in the columns name_comparison, words_that_match, country_check, country_your_file, country_list, dob_check, dob_your_file and dob_list, after spreadsheet_row. entityId, matchReasons and listEntry were added on 2026-10-03; records stored before that do not have them. Since 2026-10-07 a file whose rows hold several names (for example a student, an agent and a contact) is screened per name: the export row then has party (the name group, also the CSV column party), rowIndex is the name item (row x groups + group), and spreadsheetRow is the file row. Since 2026-10-07 each export row also has whyListed (the list's listing codes as [{code, plain, source}]: plain is the official programme name, or null when no official table names the code; source is the page that defines it, or null) and lookUp ({text, url}: where to look the list entry up). The CSV export has the same data in the columns why_listed, look_up and look_up_url. listing_reason keeps the raw code. Also since 2026-10-07, each export row has matchLabel (the report's words for the band and score, for example 'Strong name match (93%)'; band and score are unchanged) and alsoListedAs (the other names that matched the same listed person or entity in this row: only on the hit group's best match, [] on its other rows). These 2 keys are export-only: /v1 hits do not have them. Since 2026-10-09 (matcher 2.8) each export row also has mutualMismatch (true when the uploaded name and the list name each keep a word that pairs with nothing; false for matches screened before 2.8); export-only too. Since 2026-10-09 (E2.4) the batch report export differs from /v1/screen for the same match: /v1/screen hits keep the engine's band, score and reviewPriority (HIGH when the country or date of birth agrees), and the batch report export applies the date-of-birth cap and the HIGH change described here. Since 2026-10-09 (E2.4, QA PR #165) an uploaded date-of-birth or country cell where some item gives no reading and another does gives contextCheck.dobPartlyRead / countryPartlyRead = true and never 'differs': the check is then 'unreadable', the CSV check word is 'partly read: ...', and the CSV *_your_file column and the PDF print the cell as written. A cell that reads in full but with a year not written as 4 digits on their own, or a day after the report date, keeps its check (agrees / differs) and only switches the E2.4 rules off. Since 2026-10-09 (E2.4) each export row also has dobCap: null, or {nameScore, reason} when the engine gave the match the Strong band and the report shows it as Possible because the date of birth is more than 2 years off (contextCheck.dobGapOver2Years); band and score are then the report's (score at most the Strong line minus 0.01) and nameScore is the engine's name score; export-only. The CSV has the same data in its columns band_note and name_score_before_cap, after report_section. Since 2026-10-10 (matcher 2.10) each export row also has capReason: null, or one of weak_alias_copy, number_missing, letters_differ, one_word_spelling (and since matcher 2.11 common_words_only) when the engine gave a name score of the Strong line or more the Possible score 0.89 for that reason (the engine's score and band are then already Possible); and capNote, its plain sentence (null when capReason is null); capNote is export-only. Since matcher 2.11, /v1 hits also have capReason (see the property), without capNote. The CSV band_note then gives 'Shown as Possible (not Strong): ' and that sentence, and name_score_before_cap stays empty (no new CSV column). The CSV's last column, words_not_compared, holds the words on one side only that the engine leaves out of the name comparison as legal forms (nameComparison.notComparedYours / notComparedList, joined by ', '). The CSV columns match_label, your_words_not_in_list_name and list_words_not_in_your_name (nameComparison.unmatchedYours / unmatchedList, joined by ', ') and also_listed_as (at most 10 names joined by ' | ', then '(+N more)'; the JSON array has every name) are the last 4.","required":["matchedList","matchedName","score","band","reviewPriority","listVersion","matchedTokenPairs","identifiers"],"properties":{"matchedList":{"type":"string","description":"Source list id, e.g. OFAC_SDN."},"matchedName":{"type":"string"},"score":{"type":"number","minimum":0,"maximum":1},"band":{"type":"string","enum":["high_confidence","possible_match"]},"reviewPriority":{"type":"string","enum":["HIGH","REVIEW"]},"listVersion":{"type":"string"},"matchedTokenPairs":{"type":"array","items":{"$ref":"#/components/schemas/MatchedTokenPair"}},"identifiers":{"type":"array","items":{"type":"object","required":["type","value"],"properties":{"type":{"type":"string"},"value":{"type":"string"}}}},"entityId":{"type":"string","description":"The matched list entry, <list>:<source entry id>."},"matchReasons":{"type":"array","items":{"type":"string","enum":["exact","accent","word_order","partial","spelling","alias"]},"description":"Derived from the two names, for the reviewer; never a scoring input. exact: same words, same order (case, spaces, punctuation ignored). accent: same once diacritics are removed. word_order: same words, other order. partial: every word of one name is in the other. spelling: spelled differently. alias: the matched name is an alias of the entry (only when listEntry is known)."},"listEntry":{"oneOf":[{"$ref":"#/components/schemas/ListEntry"},{"type":"null"}],"description":"null: the entry data could not be read for this screen."},"capReason":{"type":"string","enum":["weak_alias_copy","number_missing","letters_differ","one_word_spelling","common_words_only"],"description":"Since matcher 2.11 (optional, absent when there is none): the engine gave a name score of the Strong line or more the Possible score 0.89 for this reason; score and band are already Possible. weak_alias_copy: OFAC or the UN marks this alias as weak in a linked entry. number_missing: one name has a number that the other name does not have. letters_differ: both names have single letters, and each has one the other does not have. one_word_spelling: one word on each side (legal forms and common words left out), not spelled the same. common_words_only: each matched word pair has a common business word, and one name has a word or single letter that the other does not have."}}},"ReportContextCheck":{"type":"object","description":"Batch report export only. The uploaded row's country and date of birth against the list entry. Display and sort only: it never changes the score. agrees / differs: both sides have a value. no_input: the upload has no such column or the cell is empty. no_list: the list entry has no value. unreadable: the uploaded value could not be read, or the upload could not be read for this report.","required":["country","dob","inputCountries","listCountries","inputDob","listDobs"],"properties":{"country":{"type":"string","enum":["agrees","differs","no_input","no_list","unreadable"]},"dob":{"type":"string","enum":["agrees","differs","no_input","no_list","unreadable"]},"inputCountries":{"type":"array","items":{"type":"string"},"description":"ISO 3166-1 alpha-2 codes read from the uploaded value."},"listCountries":{"type":"array","items":{"type":"string"},"description":"ISO 3166-1 alpha-2 codes of the list entry."},"inputDob":{"type":"array","items":{"$ref":"#/components/schemas/ReportDobValue"}},"listDobs":{"type":"array","items":{"$ref":"#/components/schemas/ReportDobValue"}},"dobAgreesAt":{"type":"string","enum":["day","month","year"],"description":"Only when dob is agrees: the finest level (day, month or year) at which the dates agree."}}},"ReportDobValue":{"type":"object","description":"A date of birth as a date span (from, to), with how exact it is: day, month, year, range or circa. All three fields are always present.","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"precision":{"type":"string","enum":["day","month","year","range","circa"]}}},"ReportInputContext":{"type":"object","description":"Batch report export only. The uploaded row's raw country and date-of-birth cell text, as read for the check. null: no mapped column, an empty cell, or not known.","required":["country","dob"],"properties":{"country":{"type":["string","null"]},"dob":{"type":["string","null"]}}},"ReportNameComparison":{"type":"object","description":"Batch report export only. A word-by-word comparison of the uploaded name and the list name, for the reviewer. Display only: derived from the two names, never a scoring input. same: same words, same order. same_accents: same once accents are removed. word_order: same words, other order. contained: every word of one name is in the other. similar_spelling: none of these. other_script: a name in Arabic script against a Latin list name, compared by consonants and long vowels. Pair kinds: same, similar (similar spelling), joined (one word is two or three words of the other name written together), initial (a one-letter word and a word that starts with it), word_table (the report's word table links the two words, for example a word and its translation, its short form, or a country and its adjective; only a pair the engine used, for a list entry that is a company, vessel or aircraft). The sign '&' and the word 'and' show as a same pair. legal_form: a legal form on each side (ПАО and PJSC) for a company entry; not_compared: the same for a person or an unknown-type entry, where the words can be name words. The engine leaves both words out of the name comparison.","required":["summary","pairs","unmatchedYours","unmatchedList"],"properties":{"summary":{"type":"string","enum":["same","same_accents","word_order","contained","similar_spelling","other_script"]},"pairs":{"type":"array","items":{"type":"object","required":["yours","list","kind"],"properties":{"yours":{"type":"string"},"list":{"type":"string"},"kind":{"type":"string","enum":["same","similar","joined","initial","word_table","legal_form","not_compared"]}}}},"unmatchedYours":{"type":"array","items":{"type":"string"}},"unmatchedList":{"type":"array","items":{"type":"string"}},"notComparedYours":{"type":"array","items":{"type":"string"},"description":"Words only in the uploaded name that the engine leaves out of the name comparison as legal forms (LLC, the words of Sp. z o.o.). Never listed in unmatchedYours. Absent when empty."},"notComparedList":{"type":"array","items":{"type":"string"},"description":"The same for the list name. Absent when empty."},"notComparedAreLegalForms":{"type":"boolean","description":"true when the list entry is a company type: the words are legal forms. Absent for a person or an unknown-type entry, where they can be name words (shown as 'Not compared')."}}},"ResultItem":{"type":"object","required":["input","hits"],"properties":{"input":{"$ref":"#/components/schemas/ScreenInput"},"hits":{"type":"array","items":{"$ref":"#/components/schemas/Hit"}}}},"Source":{"type":"object","required":["id","name","data_as_of"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"data_as_of":{"type":["string","null"],"format":"date-time","description":"When the source published the data in the screened snapshot. null when unknown; a warning then says so."},"attribution":{"type":"string","description":"The licence credit of the source. Present only when the source's licence requires one (CA_SEMA, AU_DFAT)."}}},"ScreenResponse":{"type":"object","required":["record_id","record_url","screened_at","snapshot_version","engine_version","sources","warnings","credits_charged","credits_remaining","results"],"properties":{"record_id":{"type":"string","description":"ULID. Fetch the record again with GET /v1/records/{id}."},"record_url":{"type":"string","format":"uri"},"screened_at":{"type":"string","format":"date-time"},"snapshot_version":{"type":"string"},"engine_version":{"type":"string"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/Source"}},"warnings":{"type":"array","items":{"type":"string"},"description":"Provenance gaps, e.g. a source whose data-as-of is unknown."},"request_hash":{"type":"string","description":"sha256 of the canonical request (names and threshold, keys sorted)."},"threshold":{"type":"number"},"credits_charged":{"type":"integer"},"credits_remaining":{"type":"integer"},"payload_expires_at":{"type":"string","format":"date-time","description":"After this time the record keeps its metadata but no longer holds the names and hits."},"payload_status":{"type":"string","enum":["available","expired","missing"],"description":"available on a fresh screen. On a replay, the same meaning as GET /v1/records/{id}: expired or missing when results is null."},"results":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/ResultItem"}},{"type":"null"}]},"disclaimer":{"type":"string"}}},"ScreeningRecord":{"type":"object","required":["record_id","status","screened_at","snapshot_version","engine_version","sources","warnings","credits_charged","payload_status","results"],"properties":{"record_id":{"type":"string"},"record_url":{"type":"string","format":"uri"},"status":{"type":"string","enum":["pending","done","failed"],"description":"failed: the screen did not complete and the credits were (or will be) refunded."},"screened_at":{"type":"string","format":"date-time"},"snapshot_version":{"type":["string","null"]},"engine_version":{"type":["string","null"]},"sources":{"type":"array","items":{"$ref":"#/components/schemas/Source"}},"warnings":{"type":"array","items":{"type":"string"}},"request_hash":{"type":"string"},"threshold":{"type":"number"},"names_count":{"type":"integer"},"credits_charged":{"type":"integer"},"payload_expires_at":{"type":"string","format":"date-time"},"payload_status":{"type":"string","enum":["available","expired","missing","none"],"description":"available: results present. expired: past retention. missing: not expired but not found (an incident; contact support). none: the screen did not complete."},"results":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/ResultItem"}},{"type":"null"}]},"disclaimer":{"type":"string"}}},"RecordSummary":{"type":"object","required":["record_id","status","screened_at","names_count","credits_charged"],"properties":{"record_id":{"type":"string"},"record_url":{"type":"string","format":"uri"},"status":{"type":"string","enum":["pending","done","failed"]},"screened_at":{"type":"string","format":"date-time"},"snapshot_version":{"type":["string","null"]},"engine_version":{"type":["string","null"]},"names_count":{"type":"integer"},"credits_charged":{"type":"integer"},"request_hash":{"type":"string"}}},"RecordList":{"type":"object","required":["records","next_cursor"],"properties":{"records":{"type":"array","items":{"$ref":"#/components/schemas/RecordSummary"}},"next_cursor":{"type":["string","null"]}}}}}}