> ## Documentation Index
> Fetch the complete documentation index at: https://docs.origoid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OFAC Sanctions List Check

> **Credits:** 1 per call.

Searches the consolidated OFAC sanctions lists for the provided name. Coverage includes:

- **SDN consolidated** — Specially Designated Nationals (general SDN, plus sub-programs `SDGT` Specially Designated Global Terrorists and `SDNTK` Specially Designated Narcotics Traffickers / Kingpin Act).
- **Non-SDN consolidated** — Foreign Sanctions Evaders (`FSE`), Sectoral Sanctions Identifications (`SSI`), Correspondent Account / Payable-Through Account restrictions (`CAPTA`), Menu-Based Sanctions (`NS-MBS`), Iran Sanctions Act non-SDN (`NS-ISA`), Palestinian Legislative Council (`NS-PLC`).
- **UN consolidated sanctions** — surfaced as `OFAC_UN` for clients who want a single endpoint covering both US and UN screening.

Each match carries the originating list (`listType`), the sanction programs that apply, entity type (individual, entity, vessel, aircraft), full aliases and any compliance remarks published with the record.

**Risk Level Matrix (`riskLevel`):**
- `NONE` (envelope `type: SUCCESS`): no matches at or above `minSimilarityScore`. Safe for automated approval from an OFAC perspective.
- `CRITICAL` (envelope `type: SUCCESS`): one or more matches found in **any** OFAC or UN sanctions list. Treat as a hard block, reject the relationship, and file the SAR (Suspicious Activity Report) required by your jurisdiction.

There are intentionally only two levels. AML best practice treats any sanctions list hit — SDN, sectoral, informational, anywhere — as a binding stop. Surfacing intermediate gradations (HIGH / MEDIUM / LOW) misleads the client into believing some hits are merely advisory and is the most common cause of regulatory findings against KYC systems. The `listType` and `complianceDetails.programs` of every match are still surfaced so your compliance team can apply finer policy on top of the binary verdict.

**Multi-match handling:** common names can produce dozens of fuzzy hits. The response returns **every record at or above `minSimilarityScore`**, sorted by `similarityScore` descending. There is no fixed truncation, so a genuine hit will never be hidden by a cap. If the volume of matches is higher than your review process can absorb, raise `minSimilarityScore` to tighten the match. `data.totalMatchesFound` mirrors `matches[].length` and is provided for convenience.

**Which variant matched:** every entry in `matches[]` carries a `matchedOn` object indicating whether the query matched the canonical `entityName` or one of the record's aliases:
- `matchedOn.type` is either `entityName` (the query matched the canonical name) or `alias` (the query matched an alias on the record).
- `matchedOn.value` is the alias text that produced the hit when `type` is `alias`, and `null` when `type` is `entityName`.

Why this matters: OFAC sometimes lists a person under a family member's record (e.g. `OSEGUERA CERVANTES, Nemesio` — better known as El Mencho — is published as an alias of the canonical `OSEGUERA CERVANTES, Ruben`). Without `matchedOn` a reviewer scanning the response would see `Ruben` with score 100 and discount the hit. With `matchedOn` the alias is surfaced explicitly so the reviewer can confirm the right person was matched.

**Multi-identifier matching:** `name` is required, but you can pass `passportNumber` and/or `nationalIdNumber` alongside it to tighten the match. Each extra identifier you provide is used to:

- **Boost the score** when it agrees with the record (record's passport or national ID matches the one you sent → +5 added to `similarityScore`, capped at 100).
- **Downgrade or filter the match** when it contradicts the record (different passport or national ID → −20 points). If the final score falls below `minSimilarityScore`, the record is excluded from `matches[]` entirely.
- **Stay neutral** when the record does not publish that identifier (most OFAC records don't have a passport number, for example). Missing data never penalises a match — only contradicting data does.

A `matchedOn` entry per match always carries an `identifiersMatched` array — for example `name` and `passportNumber` — listing exactly which fields agreed, so the reviewer can audit the confidence behind a hit.

**Practical coverage of the identifier boost:** OFAC publishes passport numbers and national IDs on a minority of records — most often on non-Mexican subjects (Iranian, Russian, Venezuelan, Cuban records carry passports more frequently). For purely Mexican counterparties the boost rarely applies in practice: OFAC does not publish CURP, RFC appears only on a handful of records, and most Mexican subjects are sanctioned with name + aliases only. Use these identifiers for cross-border screening where the upside is real; for MX-only KYC the `name` field is what does the work and the optional identifiers stay neutral.



## OpenAPI

````yaml /openapi.json post /global/compliance/v1/ofac-searches
openapi: 3.0.3
info:
  title: OrigoID API
  description: >-
    Identity and Background Verification API for Mexico.


    ### Authentication

    The API Gateway supports the following methods. You must send **one** of
    them in the headers:


    1. **API Key**: `x-api-key: YOUR_KEY`

    2. **Bearer Token**: `Authorization: Bearer YOUR_TOKEN`

    3. **Basic Auth**: `Authorization: Basic BASE64`


    ### Standard Format

    All responses follow this structure (HTTP 200). Authentication errors return
    401.

    ```json

    {
      "status": "OK | ERROR",
      "type": "TYPE_CODE",
      "message": "Description",
      "data": { ... },
      "transactionId": "uuid",
      "processedAt": "2026-03-19T10:00:00-06:00",
      "billable": true
    }

    ```


    ### Rate Limiting

    The API enforces per-endpoint rate limits, calculated on a sliding 1-minute
    window. Limits are defined per user, with a global default that can be
    overridden individually or by payment plan.


    When a limit is exceeded, the API returns HTTP `429 Too Many Requests` with
    the following headers:


    - **`Retry-After`**: seconds to wait before retrying.

    - **`X-RateLimit-Limit`**: total requests allowed in the current window.

    - **`X-RateLimit-Remaining`**: requests remaining in the current window.

    - **`X-RateLimit-Reset`**: Unix timestamp (seconds) when the window resets.


    Clients should implement backoff using `Retry-After`. The response body
    follows the standard envelope with `type: RATE_LIMIT_EXCEEDED`.


    ### Language Conventions

    The API follows a strict bilingual contract:


    - **All API-facing copy is in English**: response messages, error codes,
    field names, schema descriptions, summaries, and tag descriptions.

    - **Passthrough fields preserve the original Spanish text** sourced verbatim
    from Mexican regulators (SAT, RENAPO, IMSS, INE). These include:
      - `officialMessage` — official regulator response text.
      - Fields inside `taxRegimes` and `taxObligations` arrays from CSF (`description`, `dueDate`, etc.) — preserved exactly as published by SAT.
      - Address components extracted from documents (street names, neighborhood names) — preserved as printed.
      - Compliance match fields like `position`, `institution` from PEPs — preserved as recorded by the source.

    Do not translate passthrough fields — their value lies in legal traceability
    to the original source.


    ### Image Processing Policy

    Endpoints that accept images follow a **best-effort processing** philosophy:


    - **Hard Limits** (max file size, supported formats) are strictly enforced.
    A request that exceeds them is rejected with `INVALID_REQUEST` before any
    processing occurs.

    - **Recommendations** (resolution, file size for latency, framing, lighting)
    are guidance — not enforced. Suboptimal images that meet the Hard Limits are
    still processed.

    - If extraction fails on a low-quality image, the endpoint returns the
    appropriate type code (`IMAGE_UNREADABLE`, `NO_FACE_DETECTED`,
    `DOCUMENT_NOT_IDENTIFIED`, etc.) with `billable: true` — processing did run
    and consumed resources.


    This policy exists because integrators often cannot control their capture
    SDK output (third-party SDKs, legacy systems, browser-based capture).
    Rejecting suboptimal images would block legitimate use cases. Processing
    best-effort and reporting honest results gives the integrator the
    information needed to decide whether to retry or accept the result.


    ### Date and Time Conventions

    All temporal fields across the API follow standardized formats:


    - **`processedAt`**: ISO 8601 datetime with Mexico City offset (`-06:00`).
    Example: `2026-03-19T10:00:00-06:00`.

    - **Date-only fields** (`dateOfBirth`, `dueDate`, `issueDate`,
    `publicationDate`, `publicationDateSat`, `publicationDateDof`,
    `constitutionDate`, `startDate`, `registrationDate`,
    `lastStatusChangeDate`): ISO 8601 date (`YYYY-MM-DD`). Example:
    `2024-01-10`.

    - **Year-month fields** (`reportPeriod`, `positionEndDate`): ISO 8601
    year-month (`YYYY-MM`). Example: `2026-02`. (`positionEndDate` is normalised
    from the source — the PEP provider publishes the month and year a former
    office-holder left office, e.g. `Septiembre de 2024` becomes `2024-09`.)

    - **Year-only fields** (`year`, `emissionYear`, `registrationYear`,
    `validUntilYear`): returned as 4-digit string (e.g. `"2022"`). Strings
    preserve the raw value sourced from the document; clients may safely parse
    to integer.

    - **Money fields** (`baseSalary`, `amountDue`, `taxAmount`): object `{
    amount: "<decimal-string>", currency: "<ISO 4217>" }`. Amounts are decimal
    strings (not floats) to avoid precision errors. Example: `{ "amount":
    "452.50", "currency": "MXN" }`.


    ---


    # Catalogs


    #### 1. CURP Status (`statusCurp`)


    Status code returned by RENAPO inside `personalInfo.statusCurp` and similar
    fields.


    | `statusCurp` | State | Description |

    | :--- | :--- | :--- |

    | `AN` | Active | Normal registration (Alta Normal). Valid and current. |

    | `AH` | Active | Homonymy alert (Alta con Homonimia). First 16 chars match
    another CURP. |

    | `RCC` | Active | Change affecting CURP (Registro con Cambio). Data
    correction modified the key. |

    | `RCN` | Active | Change not affecting CURP. Minor data correction. |

    | `BAP` | Inactive | Apocryphal document (Baja por documento apócrifo). |

    | `BSU` | Inactive | Unused (Baja sin uso). Requires reactivation at a
    RENAPO module. |

    | `BD` | Inactive | Deceased (Baja por defunción). |

    | `BDM` | Inactive | Administrative cancellation (Baja administrativa). |

    | `BDP` | Inactive | Adoption-related cancellation (Baja por adopción). |

    | `BJD` | Inactive | Judicial cancellation (Baja judicial). |


    #### 2. Probatory Document (`docProbatorio`)


    Code identifying which civil document supports the CURP registration.


    | `docProbatorio` | Document |

    | :--- | :--- |

    | `1` | Birth Certificate (Acta de Nacimiento) |

    | `3` | Migration Document (Documento Migratorio) |

    | `4` | Naturalization Certificate (Carta de Naturalización) |

    | `7` | Mexican Nationality Certificate (Certificado de Nacionalidad
    Mexicana) |

    | `8` | SEGOB Processing (Trámite ante SEGOB) |


    #### 3. Mexican State Codes (`entidad` / `claveEntidad`)


    Two-letter codes used in CURP, RFC composition, INE registration, and
    addresses. State names preserved in Spanish (proper nouns).


    | `entidad` | State | `entidad` | State |

    | :--- | :--- | :--- | :--- |

    | `AS` | Aguascalientes | `QR` | Quintana Roo |

    | `BC` | Baja California | `SP` | San Luis Potosí |

    | `BS` | Baja California Sur | `SL` | Sinaloa |

    | `CC` | Campeche | `SR` | Sonora |

    | `CL` | Coahuila | `TC` | Tabasco |

    | `CM` | Colima | `TS` | Tamaulipas |

    | `CS` | Chiapas | `TL` | Tlaxcala |

    | `CH` | Chihuahua | `VZ` | Veracruz |

    | `DF` | Ciudad de México | `YN` | Yucatán |

    | `DG` | Durango | `ZS` | Zacatecas |

    | `GT` | Guanajuato | `NE` | Born Abroad (Nacido en el Extranjero) |

    | `GR` | Guerrero | `MC` | Estado de México |

    | `HG` | Hidalgo | `MN` | Michoacán |

    | `JC` | Jalisco | `MS` | Morelos |

    | `NT` | Nayarit | `NL` | Nuevo León |

    | `OC` | Oaxaca | `PL` | Puebla |

    | `QT` | Querétaro | | |


    #### 4. IMSS Coverage Modalities (`modalidad`)


    IMSS modality codes describe the worker's affiliation type. Official
    descriptions preserved in Spanish for legal traceability with the institute.


    | `modalidad` | Description |

    | :--- | :--- |

    | `10` | Urban permanent and temporary workers (Trabajadores permanentes y
    eventuales de la ciudad) |

    | `13` | Rural temporary workers (Trabajadores eventuales del campo) |

    | `14` | Rural permanent workers (Trabajadores permanentes del campo) |

    | `17` | Re-entry rural temporary workers (Reingreso de trabajadores
    eventuales del campo) |

    | `18` | Re-entry rural permanent workers (Reingreso de trabajadores
    permanentes del campo) |

    | `30` | Re-entry urban permanent and temporary workers (Reingreso de
    trabajadores permanentes y eventuales de la ciudad) |

    | `31` | Voluntary continuation in the mandatory regime (Continuación
    voluntaria al régimen obligatorio) |

    | `32` | Independent workers (Trabajadores independientes) |

    | `33` | Domestic workers (Trabajadores domésticos) |

    | `34` | Federal or state government workers (Trabajadores del gobierno
    federal o estatal) |

    | `35` | IMSS-affiliated students (Estudiantes afiliados al IMSS) |

    | `36` | Scholarship holders or social programs (Becarios o programas
    sociales) |

    | `40` | Voluntary continuation in the mandatory regime (alternate) |

    | `42` | Individual employer with domestic workers (Patrón persona física
    con trabajadores domésticos) |

    | `43` | International organization workers (Trabajadores de organismos
    internacionales) |

    | `44` | Seasonal or fixed-term workers (Trabajadores por temporada o tiempo
    determinado) |

    | `45` | Re-entered retirees in mandatory regime (Pensionados reincorporados
    al régimen obligatorio) |

    | `46` | Construction temporary workers (Trabajadores eventuales de la
    construcción) |

    | `47` | Trust workers with special regime (Trabajadores de confianza con
    régimen especial) |

    | `48` | Affiliated municipal public servants (Servidores públicos
    municipales afiliados) |

    | `50` | Voluntary continuation with extended coverage (Continuación
    voluntaria con cobertura extendida) |

    | `51` | Voluntary affiliation for students or apprentices (Afiliación
    voluntaria para estudiantes o aprendices) |

    | `60` | Special social incorporation regime — RESICO (Régimen especial de
    incorporación social) |

    | `70` | IMSS-Bienestar or community programs modality |

    | `72` | Inter-agency public agreement with IMSS (Convenio entre
    dependencias públicas y el IMSS) |


    #### 5. SAT Article 69 Sub-lists (`listType`)


    | `listType` | Sub-list (SAT) | Risk Level |

    | :--- | :--- | :--- |

    | <code style="white-space:nowrap">SAT_69_FIRMES</code> | Firmes | MEDIUM |

    | <code style="white-space:nowrap">SAT_69_CANCELADOS</code> | Cancelados
    (Insolvencia, general) | MEDIUM |

    | <code style="white-space:nowrap">SAT_69_CANCELADOS_07_15</code> |
    Cancelados 2007–2015 (Art. 146-A) | MEDIUM |

    | <code style="white-space:nowrap">SAT_69_EXIGIBLES</code> | Exigibles |
    MEDIUM |

    | <code style="white-space:nowrap">SAT_69_NO_LOCALIZADOS</code> | No
    Localizados | HIGH |

    | <code style="white-space:nowrap">SAT_69_CSD_SIN_EFECTOS</code> |
    Certificados de Sello Digital (CSD) sin Efectos | HIGH |

    | <code style="white-space:nowrap">SAT_69_SENTENCIAS</code> | Sentencias |
    CRITICAL |

    | <code style="white-space:nowrap">SAT_69_REDUCCION_74_CFF</code> |
    Reducción Art. 74 CFF | LOW |

    | <code style="white-space:nowrap">SAT_69_CONDONADOS_07_15</code> |
    Condonados 2007–2015 (Decreto) | LOW |

    | <code style="white-space:nowrap">SAT_69_CONDONADOS_146B_CFF</code> |
    Condonados Art. 146-B CFF | LOW |

    | <code style="white-space:nowrap">SAT_69_CONDONADOS_DECRETO</code> |
    Condonados por Decreto | LOW |

    | <code style="white-space:nowrap">SAT_69_CONDONADOS_21_CFF</code> |
    Condonados Art. 21 CFF | LOW |

    | <code style="white-space:nowrap">SAT_69_RETORNO_INVERSIONES</code> |
    Retorno de Inversiones | LOW |

    | <code style="white-space:nowrap">SAT_69_ENTES_PUBLICOS_OMISOS</code> |
    Entes Públicos y de Gobierno Omisos | LOW |


    #### 6. SAT Article 69-B Status (`complianceDetails.status`)


    The SAT 69-B endpoint always returns `listType: SAT_69B`. The granular state
    lives in `complianceDetails.status`:


    | `status` | Description | Risk Level |

    | :--- | :--- | :--- |

    | <code style="white-space:nowrap">PRESUNTO</code> | Currently under
    investigation for simulated operations (EFOS) | HIGH |

    | <code style="white-space:nowrap">DEFINITIVO</code> | Confirmed shell
    company / EFOS | CRITICAL |

    | <code style="white-space:nowrap">DESVIRTUADO</code> | Investigated but
    successfully proved innocence | LOW |

    | <code style="white-space:nowrap">SENTENCIA_FAVORABLE</code> | Won in court
    / cleared by judicial ruling | LOW |


    #### 7. PEPs Categories (`listType`)


    These are OrigoID's stable taxonomy codes. They remain consistent over time
    so client integrations don't need to change when data sources evolve.


    | `listType` | Description | Risk Level |

    | :--- | :--- | :--- |

    | <code style="white-space:nowrap">PEP_ACTIVE</code> | Politically Exposed
    Person — currently in office | HIGH |

    | <code style="white-space:nowrap">PEP_INACTIVE</code> | Politically Exposed
    Person — record marked inactive by the source | MEDIUM |

    | <code style="white-space:nowrap">EX_PEP</code> | Former PEP — held office
    in the past | MEDIUM |

    | <code style="white-space:nowrap">PEP_AFFINITY</code> | Family member or
    close associate of an active PEP | MEDIUM |

    | <code style="white-space:nowrap">EX_PEP_AFFINITY</code> | Family member or
    close associate of a former PEP | LOW |


    #### 8. OFAC Lists (`listType`)


    We query the official OFAC sanctions lists in real time and consolidate them
    under the `listType` codes below. Each entry also exposes
    `complianceDetails.programs[]` (sanction program codes such as CUBA, IRAN,
    RUSSIA, etc. — these evolve continuously and are not statically catalogued)
    and `complianceDetails.entityType` (`INDIVIDUAL` | `ENTITY` | `VESSEL` |
    `AIRCRAFT`).


    | `listType` | Official OFAC list | Risk Level |

    | :--- | :--- | :--- |

    | <code style="white-space:nowrap">OFAC_SDN</code> | Specially Designated
    Nationals & Blocked Persons | CRITICAL |

    | <code style="white-space:nowrap">OFAC_NON_SDN</code> | Consolidated
    Non-SDN List | HIGH |

    | <code style="white-space:nowrap">OFAC_FSE</code> | Foreign Sanctions
    Evaders | CRITICAL |

    | <code style="white-space:nowrap">OFAC_NS_ISA</code> | Non-SDN Iran
    Sanctions Act List | HIGH |

    | <code style="white-space:nowrap">OFAC_SSI</code> | Sectoral Sanctions
    Identifications List | MEDIUM |

    | <code style="white-space:nowrap">OFAC_CAPTA</code> | Foreign Financial
    Institutions subject to Correspondent / Payable-Through Account Sanctions |
    HIGH |

    | <code style="white-space:nowrap">OFAC_NS_PLC</code> | Non-SDN Palestinian
    Legislative Council | LOW |


    #### 9. CFDI Effect (`effect`)


    Fiscal purpose of the invoice as classified by SAT. Each CFDI has exactly
    one effect.


    | `effect` | SAT code | Description |

    | :--- | :--- | :--- |

    | <code style="white-space:nowrap">INCOME</code> | I (Ingreso) | Sales /
    revenue invoice. Issuer received payment for goods or services. |

    | <code style="white-space:nowrap">EXPENSE</code> | E (Egreso) | Refund,
    credit note, or discount. Reverses or reduces a previous income invoice. |

    | <code style="white-space:nowrap">TRANSPORT</code> | T (Traslado) | Goods
    transport waybill (Carta Porte). Does not reflect a sale, only movement of
    goods. |

    | <code style="white-space:nowrap">PAYROLL</code> | N (Nómina) | Payroll
    receipt issued by an employer to an employee. |

    | <code style="white-space:nowrap">PAYMENT</code> | P (Pago) | Payment
    receipt complement (REP) for invoices paid in installments (PPD). |


    #### 10. CFDI Status (`status`)


    Current fiscal status of the CFDI according to SAT's verification service.


    | `status` | Description |

    | :--- | :--- |

    | <code style="white-space:nowrap">VALID</code> | Vigente. The CFDI is
    current and fiscally valid. |

    | <code style="white-space:nowrap">CANCELED</code> | Cancelada. The CFDI has
    been canceled and is no longer fiscally valid. |


    #### 11. CFDI Cancellation Status (`cancellationStatus`)


    Reflects SAT's 2022 cancellation rules ("cancelación con aceptación"), which
    require receiver consent in some scenarios. This field shows both
    pre-cancellation eligibility and post-cancellation outcome.


    | `cancellationStatus` | Description |

    | :--- | :--- |

    | <code style="white-space:nowrap">NOT_CANCELABLE</code> | Cannot be
    canceled (e.g. payment complements, payroll receipts, or invoices linked to
    other active CFDIs). |

    | <code style="white-space:nowrap">CANCELABLE_WITHOUT_ACCEPTANCE</code> |
    The issuer may cancel unilaterally (small amounts, payroll corrections,
    etc.). |

    | <code style="white-space:nowrap">CANCELABLE_WITH_ACCEPTANCE</code> | The
    issuer can request cancellation, but the receiver must accept it within 72
    hours. |

    | <code style="white-space:nowrap">CANCELED_WITHOUT_ACCEPTANCE</code> |
    Already canceled; acceptance was not required. |

    | <code style="white-space:nowrap">CANCELED_WITH_ACCEPTANCE</code> | Already
    canceled; the receiver approved the cancellation. |


    ---

    **Soporte:** contacto@origoid.com
  version: 1.0.0
  contact:
    name: Soporte OrigoId
    email: contacto@origoid.com
servers:
  - url: https://api.origoid.com
security:
  - ApiKeyAuth: []
  - BearerAuth: []
  - BasicAuth: []
tags:
  - name: Authentication
    description: Generation of temporary bearer tokens (JWT).
  - name: RENAPO
    description: Official identity and CURP validation.
  - name: INE
    description: Validation of Nominal Lists and Voter Credentials.
  - name: Social Security
    description: Employment and social security data.
  - name: Biometrics
    description: Facial biometric comparison against identity documents.
  - name: Compliance
    description: 'Sanctions and risk lists: SAT 69, SAT 69-B, OFAC, and PEPs.'
  - name: Email
    description: Email deliverability and fraud risk validation.
  - name: Proof of Address
    description: >-
      Data extraction from utility and proof-of-address documents (CFE, Telmex,
      Telcel, etc.).
  - name: Fiscal
    description: RFC validation and CSF (Constancia de Situación Fiscal) extraction.
  - name: Banking
    description: SPEI / CEP payment validation against Banco de México.
paths:
  /global/compliance/v1/ofac-searches:
    post:
      tags:
        - Compliance
      summary: OFAC Sanctions List Check
      description: >-
        **Credits:** 1 per call.


        Searches the consolidated OFAC sanctions lists for the provided name.
        Coverage includes:


        - **SDN consolidated** — Specially Designated Nationals (general SDN,
        plus sub-programs `SDGT` Specially Designated Global Terrorists and
        `SDNTK` Specially Designated Narcotics Traffickers / Kingpin Act).

        - **Non-SDN consolidated** — Foreign Sanctions Evaders (`FSE`), Sectoral
        Sanctions Identifications (`SSI`), Correspondent Account /
        Payable-Through Account restrictions (`CAPTA`), Menu-Based Sanctions
        (`NS-MBS`), Iran Sanctions Act non-SDN (`NS-ISA`), Palestinian
        Legislative Council (`NS-PLC`).

        - **UN consolidated sanctions** — surfaced as `OFAC_UN` for clients who
        want a single endpoint covering both US and UN screening.


        Each match carries the originating list (`listType`), the sanction
        programs that apply, entity type (individual, entity, vessel, aircraft),
        full aliases and any compliance remarks published with the record.


        **Risk Level Matrix (`riskLevel`):**

        - `NONE` (envelope `type: SUCCESS`): no matches at or above
        `minSimilarityScore`. Safe for automated approval from an OFAC
        perspective.

        - `CRITICAL` (envelope `type: SUCCESS`): one or more matches found in
        **any** OFAC or UN sanctions list. Treat as a hard block, reject the
        relationship, and file the SAR (Suspicious Activity Report) required by
        your jurisdiction.


        There are intentionally only two levels. AML best practice treats any
        sanctions list hit — SDN, sectoral, informational, anywhere — as a
        binding stop. Surfacing intermediate gradations (HIGH / MEDIUM / LOW)
        misleads the client into believing some hits are merely advisory and is
        the most common cause of regulatory findings against KYC systems. The
        `listType` and `complianceDetails.programs` of every match are still
        surfaced so your compliance team can apply finer policy on top of the
        binary verdict.


        **Multi-match handling:** common names can produce dozens of fuzzy hits.
        The response returns **every record at or above `minSimilarityScore`**,
        sorted by `similarityScore` descending. There is no fixed truncation, so
        a genuine hit will never be hidden by a cap. If the volume of matches is
        higher than your review process can absorb, raise `minSimilarityScore`
        to tighten the match. `data.totalMatchesFound` mirrors
        `matches[].length` and is provided for convenience.


        **Which variant matched:** every entry in `matches[]` carries a
        `matchedOn` object indicating whether the query matched the canonical
        `entityName` or one of the record's aliases:

        - `matchedOn.type` is either `entityName` (the query matched the
        canonical name) or `alias` (the query matched an alias on the record).

        - `matchedOn.value` is the alias text that produced the hit when `type`
        is `alias`, and `null` when `type` is `entityName`.


        Why this matters: OFAC sometimes lists a person under a family member's
        record (e.g. `OSEGUERA CERVANTES, Nemesio` — better known as El Mencho —
        is published as an alias of the canonical `OSEGUERA CERVANTES, Ruben`).
        Without `matchedOn` a reviewer scanning the response would see `Ruben`
        with score 100 and discount the hit. With `matchedOn` the alias is
        surfaced explicitly so the reviewer can confirm the right person was
        matched.


        **Multi-identifier matching:** `name` is required, but you can pass
        `passportNumber` and/or `nationalIdNumber` alongside it to tighten the
        match. Each extra identifier you provide is used to:


        - **Boost the score** when it agrees with the record (record's passport
        or national ID matches the one you sent → +5 added to `similarityScore`,
        capped at 100).

        - **Downgrade or filter the match** when it contradicts the record
        (different passport or national ID → −20 points). If the final score
        falls below `minSimilarityScore`, the record is excluded from
        `matches[]` entirely.

        - **Stay neutral** when the record does not publish that identifier
        (most OFAC records don't have a passport number, for example). Missing
        data never penalises a match — only contradicting data does.


        A `matchedOn` entry per match always carries an `identifiersMatched`
        array — for example `name` and `passportNumber` — listing exactly which
        fields agreed, so the reviewer can audit the confidence behind a hit.


        **Practical coverage of the identifier boost:** OFAC publishes passport
        numbers and national IDs on a minority of records — most often on
        non-Mexican subjects (Iranian, Russian, Venezuelan, Cuban records carry
        passports more frequently). For purely Mexican counterparties the boost
        rarely applies in practice: OFAC does not publish CURP, RFC appears only
        on a handful of records, and most Mexican subjects are sanctioned with
        name + aliases only. Use these identifiers for cross-border screening
        where the upside is real; for MX-only KYC the `name` field is what does
        the work and the optional identifiers stay neutral.
      operationId: searchOfac
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  description: >-
                    Full name of the individual or Legal Name of the entity.
                    Required.
                  example: JOAQUIN GUZMAN LOERA
                passportNumber:
                  type: string
                  description: >-
                    Passport number, normalised (trimmed, uppercase). Optional.
                    Exact match against a record's passport ID is a strong
                    signal — adds 5 to the score and is reported in
                    `matchedOn.identifiersMatched`. A mismatch drops the score
                    by 20.
                  example: G01234567
                nationalIdNumber:
                  type: string
                  description: >-
                    National identifier as published by OFAC — typically
                    `National ID`, `Cedula`, `RFC`, `SSN`, or `Tax ID` depending
                    on jurisdiction. Optional. Normalised (trimmed, uppercase).
                    Exact match adds 5 to the score; mismatch drops 20. OFAC
                    does not publish CURP, and RFC appears only on a handful of
                    records, so for Mexican subjects this field is usually
                    neutral. Highest practical value is for cross-border
                    screening of foreign counterparties.
                  example: BC166787
                minSimilarityScore:
                  type: integer
                  maximum: 100
                  default: 90
                  description: >-
                    Minimum similarity score required to return a fuzzy match.
                    Defaults to 90 — a conservative threshold tuned to suppress
                    common-name false positives. Lower it for broader recall
                    when manual review is in place; raise it for stricter
                    automated approval. There is no enforced floor — you can
                    request very low thresholds, but the lower you go the
                    noisier the response will be. The final score after
                    multi-identifier boosts and penalties is the value compared
                    against this threshold.
            examples:
              Name only (basic):
                summary: Name only (basic)
                value:
                  name: JOAQUIN GUZMAN LOERA
              Name + passport (cross-border KYC):
                summary: Name + passport (cross-border KYC)
                value:
                  name: Abu Sufian al-Salamabi Muhammed Ahmed Abd al-Razziq
                  passportNumber: BC166787
              Name + national ID (cross-border KYC):
                summary: Name + national ID (cross-border KYC)
                value:
                  name: JOAQUIN GUZMAN LOERA
                  nationalIdNumber: BC166787
      responses:
        '200':
          description: OFAC search results (Strict Envelope Pattern).
          content:
            application/json:
              examples:
                'Risk: NONE':
                  summary: 'Risk: NONE — no OFAC or UN sanctions match'
                  value:
                    status: OK
                    type: SUCCESS
                    message: No OFAC matches found
                    data:
                      matchFound: false
                      riskLevel: NONE
                      totalMatchesFound: 0
                      matches: []
                    transactionId: 9041aa05-782b-461e-9033-5e07b2ad55fc
                    processedAt: '2026-03-19T10:00:00-06:00'
                    billable: true
                'Risk: CRITICAL':
                  summary: >-
                    Risk: CRITICAL — alias match ("EL CHAPO") against canonical
                    SDN record
                  value:
                    status: OK
                    type: SUCCESS
                    message: OFAC match found
                    data:
                      matchFound: true
                      riskLevel: CRITICAL
                      totalMatchesFound: 1
                      matches:
                        - listType: OFAC_SDNTK
                          entityName: GUZMAN LOERA, Joaquin Archivaldo
                          recordType: INDIVIDUAL
                          similarityScore: 100
                          registeredAddress: Mexico
                          matchedOn:
                            type: alias
                            value: GUZMAN, Chapo
                            identifiersMatched:
                              - name
                          complianceDetails:
                            programs:
                              - SDNTK
                            aliases:
                              - EL CHAPO
                              - EL RAPIDO
                              - SHORTY
                            nationality: MEX
                            dateOfBirth: '1954-12-25'
                            remarks: Confirmed senior leader of the Sinaloa Cartel.
                    transactionId: 3d272616-b391-4930-9391-dc4557e77e01
                    processedAt: '2026-03-19T10:01:00-06:00'
                    billable: true
                'Risk: CRITICAL (high-confidence multi-identifier)':
                  summary: >-
                    Risk: CRITICAL — name + passportNumber both match (boost
                    applied)
                  value:
                    status: OK
                    type: SUCCESS
                    message: OFAC match found
                    data:
                      matchFound: true
                      riskLevel: CRITICAL
                      totalMatchesFound: 1
                      matches:
                        - listType: OFAC_SDGT
                          entityName: >-
                            'ABD AL-RAZZIQ, Abu Sufian al-Salamabi Muhammed
                            Ahmed
                          recordType: INDIVIDUAL
                          similarityScore: 100
                          registeredAddress: Khartoum, Sudan
                          matchedOn:
                            type: entityName
                            value: null
                            identifiersMatched:
                              - name
                              - passportNumber
                          complianceDetails:
                            programs:
                              - SDGT
                            aliases:
                              - ABU SUFIAN ABD AL-RAZZIQ
                            nationality: SDN
                            dateOfBirth: '1972-01-01'
                            remarks: Passport No. BC166787 (Sudan).
                    transactionId: 67a9fe23-1c15-4d8d-b30e-2c1aef84c031
                    processedAt: '2026-03-19T10:01:30-06:00'
                    billable: true
                'Risk: CRITICAL (multiple records)':
                  summary: >-
                    Risk: CRITICAL — common name, all 28 matches returned (no
                    cap)
                  value:
                    status: OK
                    type: SUCCESS
                    message: OFAC match found
                    data:
                      matchFound: true
                      riskLevel: CRITICAL
                      totalMatchesFound: 28
                      matches:
                        - listType: OFAC_SDN
                          entityName: MEDINA HERNANDEZ, Jose
                          recordType: INDIVIDUAL
                          similarityScore: 100
                          registeredAddress: Sinaloa, Mexico
                          matchedOn:
                            type: entityName
                            value: null
                            identifiersMatched:
                              - name
                          complianceDetails:
                            programs:
                              - SDNTK
                            aliases:
                              - EL JEFE
                            nationality: MEX
                            dateOfBirth: '1972-06-14'
                            remarks: >-
                              DOJ-indicted trafficker, multiple seizures linked
                              to Pacific corridor.
                        - listType: OFAC_SSI
                          entityName: MEDINA, Jose Manuel
                          recordType: INDIVIDUAL
                          similarityScore: 96
                          registeredAddress: Moscow, Russian Federation
                          matchedOn:
                            type: entityName
                            value: null
                            identifiersMatched:
                              - name
                          complianceDetails:
                            programs:
                              - UKRAINE-EO13662
                            aliases: []
                            nationality: RUS
                            dateOfBirth: null
                            remarks: >-
                              Listed as sectoral; restrictions on equity / new
                              debt transactions per Directive 1.
                        - listType: OFAC_UN
                          entityName: JOSE MEDINA RAMIREZ
                          recordType: INDIVIDUAL
                          similarityScore: 93
                          registeredAddress: Caracas, Venezuela
                          matchedOn:
                            type: alias
                            value: JOSE A. MEDINA
                            identifiersMatched:
                              - name
                          complianceDetails:
                            programs:
                              - UN-1267
                            aliases:
                              - JOSE A. MEDINA
                            nationality: VEN
                            dateOfBirth: '1968-03-02'
                            remarks: >-
                              UN consolidated list, ISIL/Da'esh and Al-Qaida
                              sanctions list.
                    transactionId: f9b1cad3-5a98-4d62-bef0-c9d0e5b7c1aa
                    processedAt: '2026-03-19T10:02:00-06:00'
                    billable: true
                Validation Error:
                  summary: Validation Error
                  value:
                    status: ERROR
                    type: INVALID_REQUEST
                    message: Validation failed
                    data: null
                    errors:
                      - field: name
                        code: MISSING_REQUIRED_FIELD
                        message: must have required property 'name'
                      - field: name
                        code: NAME_TOO_SHORT
                        message: name must be at least 2 characters
                      - field: name
                        code: NAME_ONLY_STOPWORDS
                        message: name cannot consist solely of stopwords
                      - field: minSimilarityScore
                        code: OUT_OF_RANGE
                        message: minSimilarityScore must be 100 or below
                      - field: body
                        code: PAYLOAD_TOO_LARGE
                        message: body exceeds the maximum allowed size
                    transactionId: fdfdaa1f-d61d-4910-b161-87c976fc85d0
                    processedAt: '2026-03-19T10:06:00-06:00'
                    billable: false
                Internal Error:
                  summary: Internal Error
                  value:
                    status: ERROR
                    type: INTERNAL_ERROR
                    message: Unexpected internal error
                    data: null
                    transactionId: b0d241cb-f224-425a-9fe3-4be793e2d541
                    processedAt: '2026-03-19T10:07:00-06:00'
                    billable: false
                Service Unavailable:
                  summary: Service Unavailable
                  value:
                    status: ERROR
                    type: SERVICE_UNAVAILABLE
                    message: >-
                      The OFAC sanctions list service is currently unavailable.
                      Please retry.
                    data: null
                    transactionId: 8718e5d5-0691-4b2a-9bab-2baa1d539c5e
                    processedAt: '2026-05-21T10:00:00-06:00'
                    billable: false
              schema:
                $ref: '#/components/schemas/Envelope'
        '401':
          description: Unauthorized
          content:
            application/json:
              examples:
                Unauthorized:
                  summary: Unauthorized
                  value:
                    status: ERROR
                    type: UNAUTHORIZED
                    message: Invalid credentials
                    data: null
                    transactionId: 71d64fd8-8a54-4792-a844-7e2466eb01f7
                    processedAt: '2026-05-21T10:00:00-06:00'
                    billable: false
              schema:
                $ref: '#/components/schemas/Envelope'
        '429':
          description: Too Many Requests — endpoint rate limit exceeded.
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: >-
                Total requests allowed in the current window (per minute, per
                endpoint, per user/plan).
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests remaining in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp (seconds) when the rate limit window resets.
          content:
            application/json:
              examples:
                Rate Limit:
                  summary: Rate Limit Exceeded
                  value:
                    status: ERROR
                    type: RATE_LIMIT_EXCEEDED
                    message: >-
                      API rate limit exceeded for this endpoint. Retry after the
                      duration specified in the Retry-After header.
                    data: null
                    transactionId: d018fa81-8e77-4e51-894b-168be3667421
                    processedAt: '2026-04-26T10:00:00-06:00'
                    billable: false
              schema:
                $ref: '#/components/schemas/Envelope'
      x-codeSamples:
        - lang: cURL
          source: >-
            curl -X POST
            https://api.origoid.com/global/compliance/v1/ofac-searches \
              -H "x-api-key: YOUR_API_KEY" \
              -H "content-type: application/json" \
              -d '{
                "name": "Abu Sufian al-Salamabi Muhammed Ahmed Abd al-Razziq",
                "passportNumber": "BC166787"
              }'
        - lang: JavaScript
          source: >-
            const response = await
            fetch("https://api.origoid.com/global/compliance/v1/ofac-searches",
            {
              method: "POST",
              headers: {
                "x-api-key": process.env.ORIGOID_API_KEY,
                "content-type": "application/json",
              },
              body: JSON.stringify({
                "name": "Abu Sufian al-Salamabi Muhammed Ahmed Abd al-Razziq",
                "passportNumber": "BC166787"
              }),
            });


            if (!response.ok) {
              throw new Error(`HTTP ${response.status}`);
            }


            const result = await response.json();

            console.log(result);
        - lang: Python
          source: |-
            import os
            import requests

            response = requests.post(
                "https://api.origoid.com/global/compliance/v1/ofac-searches",
                headers={
                    "x-api-key": os.environ["ORIGOID_API_KEY"],
                    "content-type": "application/json",
                },
                json={
                    "name": "Abu Sufian al-Salamabi Muhammed Ahmed Abd al-Razziq",
                    "passportNumber": "BC166787"
                },
                timeout=30,
            )
            response.raise_for_status()
            result = response.json()
            print(result)
        - lang: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.time.Duration;

            public class Example {
                public static void main(String[] args) throws Exception {
                    String payload = "{\"name\": \"Abu Sufian al-Salamabi Muhammed Ahmed Abd al-Razziq\", \"passportNumber\": \"BC166787\"}";

                    HttpClient client = HttpClient.newBuilder()
                        .connectTimeout(Duration.ofSeconds(10))
                        .build();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.origoid.com/global/compliance/v1/ofac-searches"))
                        .header("x-api-key", System.getenv("ORIGOID_API_KEY"))
                        .header("content-type", "application/json")
                        .timeout(Duration.ofSeconds(30))
                        .POST(HttpRequest.BodyPublishers.ofString(payload))
                        .build();

                    HttpResponse<String> response = client.send(
                        request, HttpResponse.BodyHandlers.ofString()
                    );

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: PHP
          source: >-
            <?php

            $payload = '{"name": "Abu Sufian al-Salamabi Muhammed Ahmed Abd
            al-Razziq", "passportNumber": "BC166787"}';


            $ch =
            curl_init('https://api.origoid.com/global/compliance/v1/ofac-searches');

            curl_setopt_array($ch, [
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $payload,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_HTTPHEADER => [
                    'x-api-key: ' . getenv('ORIGOID_API_KEY'),
                    'content-type: application/json',
                ],
            ]);


            $response = curl_exec($ch);

            $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

            curl_close($ch);


            if ($status >= 400) {
                throw new Exception("HTTP $status");
            }


            $result = json_decode($response, true);

            print_r($result);
        - lang: Go
          source: "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n)\n\nfunc main() {\n\tpayload := []byte(`{\"name\": \"Abu Sufian al-Salamabi Muhammed Ahmed Abd al-Razziq\", \"passportNumber\": \"BC166787\"}`)\n\treq, err := http.NewRequest(\"POST\", \"https://api.origoid.com/global/compliance/v1/ofac-searches\", bytes.NewBuffer(payload))\n\tif err != nil { log.Fatal(err) }\n\treq.Header.Set(\"x-api-key\", os.Getenv(\"ORIGOID_API_KEY\"))\n\treq.Header.Set(\"content-type\", \"application/json\")\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil { log.Fatal(err) }\n\tdefer resp.Body.Close()\n\n\tvar result map[string]any\n\tif err := json.NewDecoder(resp.Body).Decode(&result); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(result)\n}"
        - lang: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
                    client.DefaultRequestHeaders.Add("x-api-key",
                        Environment.GetEnvironmentVariable("ORIGOID_API_KEY"));

                    var payload = "{\"name\": \"Abu Sufian al-Salamabi Muhammed Ahmed Abd al-Razziq\", \"passportNumber\": \"BC166787\"}";
                    var content = new StringContent(payload, Encoding.UTF8, "application/json");

                    var response = await client.PostAsync("https://api.origoid.com/global/compliance/v1/ofac-searches", content);
                    response.EnsureSuccessStatusCode();

                    var body = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(body);
                }
            }
components:
  schemas:
    Envelope:
      type: object
      required:
        - status
        - type
        - message
        - transactionId
        - processedAt
        - billable
      properties:
        status:
          type: string
          enum:
            - OK
            - ERROR
          description: >-
            High-level outcome. `OK` means the request was successfully
            processed (regardless of business result). `ERROR` means the request
            was rejected or could not be processed.
        type:
          type: string
          description: >-
            Stable result type code. Includes generic codes (`SUCCESS`,
            `INVALID_REQUEST`, `UNAUTHORIZED`, `SERVICE_UNAVAILABLE`,
            `INTERNAL_ERROR`, `RATE_LIMIT_EXCEEDED`) plus endpoint-specific
            result codes — see this endpoint's response examples.
        message:
          type: string
          description: >-
            Human-readable summary of the result. Always in English (per
            Language Conventions in the API overview).
        data:
          type: object
          nullable: true
          description: >-
            Response payload. `null` on error responses. Shape depends on the
            endpoint — see each operation's response schema.
        errors:
          type: array
          description: >-
            Per-field error details. Present only on `INVALID_REQUEST`
            responses.
          items:
            $ref: '#/components/schemas/ErrorDetail'
        transactionId:
          type: string
          format: uuid
          description: >-
            Unique identifier of this request, generated by the API Gateway.
            Propagated end-to-end for traceability.
        processedAt:
          type: string
          format: date-time
          description: >-
            ISO 8601 datetime with Mexico City offset (`-06:00`). Always set by
            the API Gateway when the response leaves the system.
        billable:
          type: boolean
          description: >-
            Whether this request will be charged against the client's plan.
            Typically `true` for successful business results and `false` for
            validation errors or system errors that prevented processing.
    ErrorDetail:
      type: object
      required:
        - field
        - code
        - message
      properties:
        field:
          type: string
          description: >-
            JSON path or field name where the validation failed. For body-level
            errors (malformed JSON, payload exceeds size limit, oneOf with all
            alternatives present) use `body`. For field-specific errors use the
            dotted path (e.g. `rfc`, `personalInfo.curp`, `front`).
        code:
          type: string
          description: >-
            Machine-readable error code. Standard catalog (non-exhaustive):
            `MISSING_REQUIRED_FIELD`, `INVALID_TYPE`, `INVALID_FORMAT`,
            `INVALID_ENUM_VALUE`, `INVALID_LENGTH`, `OUT_OF_RANGE`,
            `INVALID_ARRAY`, `UNKNOWN_FIELD`, `SCHEMA_MISMATCH`,
            `MISSING_DEPENDENT_FIELD`, `MALFORMED_JSON`, `PAYLOAD_TOO_LARGE`,
            `INVALID_SCOPE`, `INVALID_VALUE`. Some operations also emit
            endpoint-specific codes documented in each operation's spec (e.g.
            `INVALID_RFC_FORMAT`, `NAME_TOO_SHORT`, `QR_NOT_FOUND`).
        message:
          type: string
          description: Human-readable description of the field-level error.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    BasicAuth:
      type: http
      scheme: basic

````