> ## 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.

# PEP (Politically Exposed Person) Check

> **Credits:** 2 per call.

Searches the consolidated PEP (Politically Exposed Persons) database for a subject — covering active PEPs, former PEPs (`EX_PEP`), and their immediate family and close associates (`PEP_AFFINITY`, `EX_PEP_AFFINITY`).

**Input flexibility — three valid invocation forms:**

The endpoint accepts a search in any of three forms — pick the one that matches the data you have on hand. You may include `nationalIdNumber` alongside any of them to tighten the match.

1. **Single name (`name`)** — pass the full name as one string. Quick and convenient when you only have the full name as a single value.
2. **Separated name (`givenNames` + `firstSurname` + optional `secondSurname`)** — Mexican-style split. **Strongly recommended for best match quality**, because the matching engine can apply per-component logic that produces fewer false positives on compound first names and compound surnames. When using this form, both `givenNames` and `firstSurname` are required.
3. **Identifier only (`nationalIdNumber`)** — pass a CURP or RFC by itself when that is all you have. The search runs against records that publish the identifier.

If more than one form is sent (for example `name` plus separated fields), the separated fields take precedence over `name`. The `nationalIdNumber` is normalised (trim, uppercase) and reported back per match in `matchedOn.identifiersMatched` and in the standalone `identifierMatch` field.

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

Each match in `matches[]` has a base severity per its `listType`:

| `listType` | base severity |
|---|---|
| `PEP_ACTIVE` | HIGH |
| `EX_PEP` | MEDIUM |
| `PEP_INACTIVE` | MEDIUM |
| `PEP_AFFINITY` | MEDIUM |
| `EX_PEP_AFFINITY` | LOW |

The endpoint `riskLevel` is the **maximum** severity across `matches[]`:

- `NONE` — no matches at or above `minSimilarityScore`. Safe for automated approval from a PEP perspective.
- `LOW` — only `EX_PEP_AFFINITY` hits found (family or close associate of a former PEP).
- `MEDIUM` — at least one `EX_PEP`, `PEP_INACTIVE`, or `PEP_AFFINITY` hit.
- `HIGH` — at least one `PEP_ACTIVE` hit. Aligned with the categories that FATF Recommendation 12 and Mexican LFPIORPI flag for Enhanced Due Diligence (EDD).

`riskLevel` is a screening signal intended to feed your compliance workflow. Combine it with `identifierMatch`, `similarityScore`, and the per-match `complianceDetails` we surface so your team can apply its own internal policy.

**Which variant matched:** every entry in `matches[]` carries a `matchedOn` object identifying the canonical record that was hit and an `identifiersMatched` array — for example `name` and `nationalIdNumber` — listing which fields agreed. The standalone `identifierMatch` field exposes the precision of the identifier comparison (`EXACT`, `PARTIAL`, `MISMATCH`, or `NOT_PROVIDED` when no identifier was sent). Use these together to audit the confidence behind a hit.

**How `similarityScore` is computed:** the score reflects **combined name + identifier confidence**, not name alone. A match's `similarityScore` is the higher of (a) the name match quality and (b) the strength of the identifier comparison — an `EXACT` `nationalIdNumber` match contributes a full-confidence score, a `PARTIAL` match contributes a strong-but-not-certain score, and `MISMATCH` / `NOT_PROVIDED` contribute nothing (the name drives the score in those cases). This means a search by `nationalIdNumber` alone still returns a high-confidence hit even though no name was supplied to compare — a CURP or RFC coincidence is a deterministic identity signal. Inspect `identifierMatch` and `matchedOn.identifiersMatched` to see *why* a given match scored the way it did.

**Multi-match handling:** the response returns every match at or above `minSimilarityScore`, sorted by `similarityScore` descending. `data.totalMatchesFound` mirrors `matches[].length` and is provided for convenience.

Use this endpoint as part of AML programs where screening counterparties against PEPs is part of your KYC workflow — common in regulated financial services, cross-border payments, and onboarding pipelines.



## OpenAPI

````yaml /openapi.json post /mex/compliance/v1/peps-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:
  /mex/compliance/v1/peps-searches:
    post:
      tags:
        - Compliance
      summary: PEP (Politically Exposed Person) Check
      description: >-
        **Credits:** 2 per call.


        Searches the consolidated PEP (Politically Exposed Persons) database for
        a subject — covering active PEPs, former PEPs (`EX_PEP`), and their
        immediate family and close associates (`PEP_AFFINITY`,
        `EX_PEP_AFFINITY`).


        **Input flexibility — three valid invocation forms:**


        The endpoint accepts a search in any of three forms — pick the one that
        matches the data you have on hand. You may include `nationalIdNumber`
        alongside any of them to tighten the match.


        1. **Single name (`name`)** — pass the full name as one string. Quick
        and convenient when you only have the full name as a single value.

        2. **Separated name (`givenNames` + `firstSurname` + optional
        `secondSurname`)** — Mexican-style split. **Strongly recommended for
        best match quality**, because the matching engine can apply
        per-component logic that produces fewer false positives on compound
        first names and compound surnames. When using this form, both
        `givenNames` and `firstSurname` are required.

        3. **Identifier only (`nationalIdNumber`)** — pass a CURP or RFC by
        itself when that is all you have. The search runs against records that
        publish the identifier.


        If more than one form is sent (for example `name` plus separated
        fields), the separated fields take precedence over `name`. The
        `nationalIdNumber` is normalised (trim, uppercase) and reported back per
        match in `matchedOn.identifiersMatched` and in the standalone
        `identifierMatch` field.


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


        Each match in `matches[]` has a base severity per its `listType`:


        | `listType` | base severity |

        |---|---|

        | `PEP_ACTIVE` | HIGH |

        | `EX_PEP` | MEDIUM |

        | `PEP_INACTIVE` | MEDIUM |

        | `PEP_AFFINITY` | MEDIUM |

        | `EX_PEP_AFFINITY` | LOW |


        The endpoint `riskLevel` is the **maximum** severity across `matches[]`:


        - `NONE` — no matches at or above `minSimilarityScore`. Safe for
        automated approval from a PEP perspective.

        - `LOW` — only `EX_PEP_AFFINITY` hits found (family or close associate
        of a former PEP).

        - `MEDIUM` — at least one `EX_PEP`, `PEP_INACTIVE`, or `PEP_AFFINITY`
        hit.

        - `HIGH` — at least one `PEP_ACTIVE` hit. Aligned with the categories
        that FATF Recommendation 12 and Mexican LFPIORPI flag for Enhanced Due
        Diligence (EDD).


        `riskLevel` is a screening signal intended to feed your compliance
        workflow. Combine it with `identifierMatch`, `similarityScore`, and the
        per-match `complianceDetails` we surface so your team can apply its own
        internal policy.


        **Which variant matched:** every entry in `matches[]` carries a
        `matchedOn` object identifying the canonical record that was hit and an
        `identifiersMatched` array — for example `name` and `nationalIdNumber` —
        listing which fields agreed. The standalone `identifierMatch` field
        exposes the precision of the identifier comparison (`EXACT`, `PARTIAL`,
        `MISMATCH`, or `NOT_PROVIDED` when no identifier was sent). Use these
        together to audit the confidence behind a hit.


        **How `similarityScore` is computed:** the score reflects **combined
        name + identifier confidence**, not name alone. A match's
        `similarityScore` is the higher of (a) the name match quality and (b)
        the strength of the identifier comparison — an `EXACT`
        `nationalIdNumber` match contributes a full-confidence score, a
        `PARTIAL` match contributes a strong-but-not-certain score, and
        `MISMATCH` / `NOT_PROVIDED` contribute nothing (the name drives the
        score in those cases). This means a search by `nationalIdNumber` alone
        still returns a high-confidence hit even though no name was supplied to
        compare — a CURP or RFC coincidence is a deterministic identity signal.
        Inspect `identifierMatch` and `matchedOn.identifiersMatched` to see
        *why* a given match scored the way it did.


        **Multi-match handling:** the response returns every match at or above
        `minSimilarityScore`, sorted by `similarityScore` descending.
        `data.totalMatchesFound` mirrors `matches[].length` and is provided for
        convenience.


        Use this endpoint as part of AML programs where screening counterparties
        against PEPs is part of your KYC workflow — common in regulated
        financial services, cross-border payments, and onboarding pipelines.
      operationId: searchPeps
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: >-
                    Full name of the subject (single string). Optional
                    alternative to the split `givenNames` / `firstSurname`
                    format. Use this when you only have the full name as one
                    value (form input, OCR extraction). For best match quality,
                    prefer the separated fields below.
                  example: ANDRES MANUEL LOPEZ OBRADOR
                givenNames:
                  type: string
                  description: >-
                    Subject's given name(s). Use together with `firstSurname`
                    for the most precise matching. Recommended over the single
                    `name` field whenever the components are available.
                  example: ANDRES MANUEL
                firstSurname:
                  type: string
                  description: >-
                    Subject's first (paternal) surname. Use with `givenNames`
                    for best match quality.
                  example: LOPEZ
                secondSurname:
                  type: string
                  description: Subject's second (maternal) surname. Optional.
                  example: OBRADOR
                nationalIdNumber:
                  type: string
                  description: >-
                    National identifier — CURP (18 chars) or RFC (12-13 chars).
                    Optional. Normalised (trimmed, uppercase). When provided, it
                    is reported back per match in `matchedOn.identifiersMatched`
                    and in the standalone `identifierMatch` field so the
                    reviewer can audit the precision of the hit. Examples:
                    `LOOA531113HTCPBN07` (CURP), `LOOA531113FI5` (RFC).
                  example: LOOA531113HTCPBN07
                minSimilarityScore:
                  type: integer
                  maximum: 100
                  default: 70
                  description: >-
                    Minimum similarity score required to return a match.
                    Defaults to 70 — a balanced threshold for PEP screening.
                    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
                    threshold is compared against the combined name + identifier
                    `similarityScore` (see the description), so a search by
                    `nationalIdNumber` alone with an exact match is not filtered
                    out even though no name was provided to compare.
              anyOf:
                - required:
                    - name
                - required:
                    - givenNames
                    - firstSurname
                - required:
                    - nationalIdNumber
            examples:
              By single name (basic):
                summary: By single name (basic)
                value:
                  name: ANDRES MANUEL LOPEZ OBRADOR
              By separated name (recommended):
                summary: By separated name (recommended for best match)
                value:
                  givenNames: ANDRES MANUEL
                  firstSurname: LOPEZ
                  secondSurname: OBRADOR
              By separated name + CURP:
                summary: By separated name + CURP (highest confidence)
                value:
                  givenNames: ANDRES MANUEL
                  firstSurname: LOPEZ
                  secondSurname: OBRADOR
                  nationalIdNumber: LOOA531113HTCPBN07
              By single name + RFC:
                summary: By single name + RFC
                value:
                  name: ANDRES MANUEL LOPEZ OBRADOR
                  nationalIdNumber: LOOA531113FI5
              By identifier only (CURP):
                summary: By identifier only (CURP)
                value:
                  nationalIdNumber: LOOA531113HTCPBN07
      responses:
        '200':
          description: PEP search results (Strict Envelope Pattern).
          content:
            application/json:
              examples:
                'Risk: NONE':
                  summary: 'Risk: NONE — no PEP match'
                  value:
                    status: OK
                    type: SUCCESS
                    message: No PEPs matches found
                    data:
                      matchFound: false
                      riskLevel: NONE
                      totalMatchesFound: 0
                      matches: []
                    transactionId: d2b0b572-0be8-4744-bf0d-72f21135125b
                    processedAt: '2026-03-19T10:05:00-06:00'
                    billable: true
                'Risk: LOW':
                  summary: 'Risk: LOW — only EX_PEP_AFFINITY hit'
                  value:
                    status: OK
                    type: SUCCESS
                    message: PEPs match found
                    data:
                      matchFound: true
                      riskLevel: LOW
                      totalMatchesFound: 1
                      matches:
                        - listType: EX_PEP_AFFINITY
                          entityName: ROSA MARIA HERNANDEZ MARTINEZ
                          recordType: INDIVIDUAL
                          similarityScore: 78
                          identifierMatch: NOT_PROVIDED
                          matchedOn:
                            type: entityName
                            value: null
                            identifiersMatched:
                              - name
                          complianceDetails:
                            position: null
                            institution: null
                            status: UNKNOWN
                            positionEndDate: null
                            dateOfBirth: null
                            curp: null
                            rfc: null
                            registeredAddress: MEXICO
                    transactionId: e9af2c47-1b94-4a23-a0a6-5fa6d3eed101
                    processedAt: '2026-03-19T10:00:00-06:00'
                    billable: true
                'Risk: MEDIUM':
                  summary: 'Risk: MEDIUM — EX_PEP hit (former office-holder)'
                  value:
                    status: OK
                    type: SUCCESS
                    message: PEPs match found
                    data:
                      matchFound: true
                      riskLevel: MEDIUM
                      totalMatchesFound: 2
                      matches:
                        - listType: EX_PEP
                          entityName: LOPEZ OBRADOR ANDRES MANUEL
                          recordType: INDIVIDUAL
                          similarityScore: 100
                          identifierMatch: EXACT
                          matchedOn:
                            type: entityName
                            value: null
                            identifiersMatched:
                              - name
                              - nationalIdNumber
                          complianceDetails:
                            position: PRESIDENTE DE LOS ESTADOS UNIDOS MEXICANOS
                            institution: Gobierno de los Estados Unidos Mexicanos
                            status: INACTIVE
                            positionEndDate: 2024-09
                            dateOfBirth: '1953-11-13'
                            curp: LOOA531113HTCPBN07
                            rfc: LOOA531113FI5
                            registeredAddress: >-
                              C ODONTOLOGIA 57 EDIF B, DEPT 301, COYOACAN,
                              MEXICO
                        - listType: PEP_AFFINITY
                          entityName: PIO LORENZO LOPEZ OBRADOR
                          recordType: INDIVIDUAL
                          similarityScore: 80
                          identifierMatch: NOT_PROVIDED
                          matchedOn:
                            type: entityName
                            value: null
                            identifiersMatched:
                              - name
                          complianceDetails:
                            position: null
                            institution: null
                            status: UNKNOWN
                            positionEndDate: null
                            dateOfBirth: null
                            curp: null
                            rfc: null
                            registeredAddress: MEXICO
                    transactionId: b1c2d3e4-f5a6-7b8c-9d0e-123456789001
                    processedAt: '2026-03-19T10:01:00-06:00'
                    billable: true
                'Risk: HIGH':
                  summary: 'Risk: HIGH — sitting PEP, EDD required'
                  value:
                    status: OK
                    type: SUCCESS
                    message: PEPs match found
                    data:
                      matchFound: true
                      riskLevel: HIGH
                      totalMatchesFound: 1
                      matches:
                        - listType: PEP_ACTIVE
                          entityName: SHEINBAUM PARDO CLAUDIA
                          recordType: INDIVIDUAL
                          similarityScore: 100
                          identifierMatch: EXACT
                          matchedOn:
                            type: entityName
                            value: null
                            identifiersMatched:
                              - name
                              - nationalIdNumber
                          complianceDetails:
                            position: PRESIDENTA DE LOS ESTADOS UNIDOS MEXICANOS
                            institution: Gobierno de los Estados Unidos Mexicanos
                            status: ACTIVE
                            positionEndDate: null
                            dateOfBirth: '1962-06-24'
                            curp: SEPC620624MDFHRL05
                            rfc: SEPC620624C57
                            registeredAddress: CIUDAD DE MEXICO, MEXICO
                    transactionId: c2d3e4f5-a6b7-8c9d-0e12-3456789ab012
                    processedAt: '2026-03-19T10:02:00-06:00'
                    billable: true
                'Risk: MEDIUM (identifier-only search)':
                  summary: >-
                    Risk: MEDIUM — searched by CURP alone, exact identifier
                    match
                  value:
                    status: OK
                    type: SUCCESS
                    message: PEPs match found
                    data:
                      matchFound: true
                      riskLevel: MEDIUM
                      totalMatchesFound: 1
                      matches:
                        - listType: EX_PEP
                          entityName: LOPEZ OBRADOR ANDRES MANUEL
                          recordType: INDIVIDUAL
                          similarityScore: 100
                          identifierMatch: EXACT
                          matchedOn:
                            type: entityName
                            value: null
                            identifiersMatched:
                              - nationalIdNumber
                          complianceDetails:
                            position: PRESIDENTE DE LOS ESTADOS UNIDOS MEXICANOS
                            institution: Gobierno de los Estados Unidos Mexicanos
                            status: INACTIVE
                            positionEndDate: 2024-09
                            dateOfBirth: '1953-11-13'
                            curp: LOOA531113HTCPBN07
                            rfc: LOOA531113FI5
                            registeredAddress: >-
                              C ODONTOLOGIA 57 EDIF B, DEPT 301, COYOACAN,
                              MEXICO
                    transactionId: f3e4d5c6-b7a8-9c0d-1e23-456789abc123
                    processedAt: '2026-03-19T10:03:00-06:00'
                    billable: true
                Validation Error:
                  summary: Validation Error
                  value:
                    status: ERROR
                    type: INVALID_REQUEST
                    message: Validation failed
                    data: null
                    errors:
                      - field: body
                        code: MISSING_REQUIRED_FIELD
                        message: >-
                          Provide one of: `name` (single string), or both
                          `givenNames` and `firstSurname` (separated form), or
                          `nationalIdNumber` (CURP/RFC).
                      - field: nationalIdNumber
                        code: INVALID_FORMAT
                        message: >-
                          nationalIdNumber must match CURP (18 characters) or
                          RFC (12-13 characters) format
                      - field: firstSurname
                        code: NAME_TOO_SHORT
                        message: firstSurname 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: 22cbcaa5-ba6c-45cc-a1b0-f9c048e4f481
                    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: 716080c8-5ec0-48a7-892d-fb88f1ad55a0
                    processedAt: '2026-03-19T10:07:00-06:00'
                    billable: false
                Service Unavailable:
                  summary: Service Unavailable
                  value:
                    status: ERROR
                    type: SERVICE_UNAVAILABLE
                    message: The PEP database service is currently unavailable
                    data: null
                    transactionId: 878bb9a5-16ee-405e-88ed-8de43ba99401
                    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: fb9c33a5-ee2f-42b2-8467-ff6807e14beb
                    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/mex/compliance/v1/peps-searches
            \
              -H "x-api-key: YOUR_API_KEY" \
              -H "content-type: application/json" \
              -d '{"givenNames": "ANDRES MANUEL", "firstSurname": "LOPEZ", "secondSurname": "OBRADOR", "nationalIdNumber": "LOOA531113HTCPBN07"}'
        - lang: JavaScript
          source: >-
            const response = await
            fetch("https://api.origoid.com/mex/compliance/v1/peps-searches", {
              method: "POST",
              headers: {
                "x-api-key": process.env.ORIGOID_API_KEY,
                "content-type": "application/json",
              },
              body: JSON.stringify({
                "givenNames": "ANDRES MANUEL",
                "firstSurname": "LOPEZ",
                "secondSurname": "OBRADOR",
                "nationalIdNumber": "LOOA531113HTCPBN07"
              }),
            });


            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/mex/compliance/v1/peps-searches",
                headers={
                    "x-api-key": os.environ["ORIGOID_API_KEY"],
                    "content-type": "application/json",
                },
                json={
                    "givenNames": "ANDRES MANUEL",
                    "firstSurname": "LOPEZ",
                    "secondSurname": "OBRADOR",
                    "nationalIdNumber": "LOOA531113HTCPBN07"
                },
                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 = "{\"givenNames\": \"ANDRES MANUEL\", \"firstSurname\": \"LOPEZ\", \"secondSurname\": \"OBRADOR\", \"nationalIdNumber\": \"LOOA531113HTCPBN07\"}";

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

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.origoid.com/mex/compliance/v1/peps-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 = '{"givenNames": "ANDRES MANUEL", "firstSurname": "LOPEZ",
            "secondSurname": "OBRADOR", "nationalIdNumber":
            "LOOA531113HTCPBN07"}';


            $ch =
            curl_init('https://api.origoid.com/mex/compliance/v1/peps-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(`{\"givenNames\": \"ANDRES MANUEL\", \"firstSurname\": \"LOPEZ\", \"secondSurname\": \"OBRADOR\", \"nationalIdNumber\": \"LOOA531113HTCPBN07\"}`)\n\treq, err := http.NewRequest(\"POST\", \"https://api.origoid.com/mex/compliance/v1/peps-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 = "{\"givenNames\": \"ANDRES MANUEL\", \"firstSurname\": \"LOPEZ\", \"secondSurname\": \"OBRADOR\", \"nationalIdNumber\": \"LOOA531113HTCPBN07\"}";
                    var content = new StringContent(payload, Encoding.UTF8, "application/json");

                    var response = await client.PostAsync("https://api.origoid.com/mex/compliance/v1/peps-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

````