Track the Review and Fix Rejections

Request the KYC/KYB review of an entity, read the outcome, and correct what Localpayment asks for.

When the entity has its data and files, you request the review with Request Verification; you never approve it. Localpayment Compliance decides on each file and on the entity. You don't need to wait for the result or poll the entity. When something has to change, Compliance tells you what and why, you correct it, and you request verification again. If you want to follow the result, use Get KYC Status and Get Status History.

Prerequisites

Who does what

%%{init: {'theme': 'base', 'themeVariables': {'background': '#ffffff', 'primaryColor': '#31467c', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#0c1a29', 'secondaryColor': '#31467c', 'tertiaryColor': '#ffffff', 'lineColor': '#0c1a29', 'textColor': '#0c1a29', 'edgeLabelBackground': '#ffffff', 'fontFamily': 'Manrope'}, 'fontFamily': 'Manrope', 'htmlLabels': false, 'flowchart': {'htmlLabels': false, 'wrappingWidth': 400, 'padding': 20}}}%%
flowchart TD
    A["Your backend<br/>GET /api/entity/v1/entities/{entityId}/kyc-status"] --> B["Entities API<br/>documentationStatus COMPLETE"]:::lp
    B --> V["Your backend<br/>Requests the review<br/>POST /api/entity/v1/entities/{entityId}/verify"]
    V --> C["Entities API<br/>202 Accepted: entity IN_REVIEW"]:::lp
    C --> D["Localpayment Compliance<br/>Reviews each proof: APPROVED or REJECTED, with reason"]:::lp
    D --> E["Localpayment Compliance<br/>Resolves the entity: ACTIVE, REJECTED, or back to PENDING_KYC for a correction"]:::lp
    E --> F["Your backend, optional<br/>GET /api/entity/v1/entities/{entityId}/kyc-status<br/>to follow the result"]
    F --> G["Your backend<br/>GET /api/entity/v1/entities/{entityId}/status-history<br/>every change with who made it and why"]
    classDef default fill:#31467c,stroke:#0c1a29,stroke-width:1px,color:#ffffff,font-family:Manrope
    classDef lp fill:#0c1a29,stroke:#0c1a29,color:#ffffff
    classDef terminal fill:#0c1a29,stroke:#0c1a29,color:#ffffff
    classDef lbl fill:#0c1a29,stroke:#0c1a29,color:#ffffff,font-size:13px
ℹ️

You don't need to poll the entity. Status change webhooks are not available for Entities; if you want to follow the review, call Get KYC Status at a reasonable interval, for example every few minutes while the entity is IN_REVIEW.

Before the review

  • Every document has its files: documentationStatus is COMPLETE in Get KYC Status.
  • For a company, each owner is linked and has its own documents and files.
  • At least one file is uploaded; otherwise verify returns 422 NO_PROOFS_UPLOADED.

While the entity is IN_REVIEW it is locked: you cannot edit its data, add or edit documents, upload or delete files, or link, change, or end UBOs (409 ENTITY_IN_REVIEW).

Read the KYC status

While the entity is IN_REVIEW, after Compliance approved both files:

{
  "entityId": "5aced5da-40c1-4bec-85ff-c8cd1bcb4526",
  "status": "IN_REVIEW",
  "documentationStatus": "COMPLETE",
  "statusReason": "Review started",
  "documents": [
    {
      "documentId": "2e16d844-4fa9-4295-9a21-83ec32ef241a",
      "type": "CPF",
      "status": "VERIFIED",
      "proofs": [
        {
          "proofId": "2c4c2f74-7179-4113-83fb-f11dbce9e07d",
          "verificationStatus": "APPROVED"
        }
      ]
    },
    {
      "documentId": "e0ea9515-442e-4bc5-bc82-b8d278255c37",
      "type": "PROOF_OF_ADDRESS",
      "status": "VERIFIED",
      "proofs": [
        {
          "proofId": "acb78b3f-fe18-4094-b6a9-2107f502d709",
          "verificationStatus": "APPROVED"
        }
      ]
    }
  ]
}
FieldHow to read it
statusThe entity's lifecycle status. ACTIVE is the goal.
statusReasonReason of the last status change. When the entity is back in PENDING_KYC, it says what to correct.
documentationStatusFile coverage only. COMPLETE with proofs still PENDING is normal before the review.
documents[].statusVERIFIED when all its active proofs are APPROVED, REJECTED if any is rejected, EXPIRED if the declared expiration date passed.
documents[].proofs[].verificationStatusPENDING, then IN_REVIEW, then APPROVED or REJECTED, set by Localpayment.

If you want to follow the review, a polling loop in Python:

import os
import time
import requests

BASE_URL = "https://api.stage.localpayment.com/api/entity"
access_token = os.environ["LOCALPAYMENT_ACCESS_TOKEN"]
entity_id = "5aced5da-40c1-4bec-85ff-c8cd1bcb4526"
headers = {"Authorization": f"Bearer {access_token}"}
last_reason = None

while True:
    response = requests.get(f"{BASE_URL}/v1/entities/{entity_id}/kyc-status", headers=headers, timeout=30)
    if response.status_code != 200:
        problem = response.json()
        raise RuntimeError(f"{problem.get('code')} correlationId={problem.get('correlationId')}")

    kyc = response.json()
    if kyc["status"] in ("ACTIVE", "REJECTED"):
        break

    if kyc["status"] == "PENDING_KYC" and kyc.get("statusReason") and kyc["statusReason"] != last_reason:
        # Correction requested: read statusReason and the verificationReason of each
        # rejected proof (GET /v1/proofs/{proofId}), then correct the data or upload
        # a replacement with the same proofType, then call POST .../verify again.
        last_reason = kyc["statusReason"]

    time.sleep(300)  # every 5 minutes

Possible outcomes

%%{init: {'theme': 'base', 'themeVariables': {'background': '#ffffff', 'primaryColor': '#31467c', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#0c1a29', 'secondaryColor': '#31467c', 'tertiaryColor': '#ffffff', 'lineColor': '#0c1a29', 'textColor': '#0c1a29', 'edgeLabelBackground': '#ffffff', 'fontFamily': 'Manrope'}, 'fontFamily': 'Manrope', 'htmlLabels': false, 'flowchart': {'htmlLabels': false, 'wrappingWidth': 400, 'padding': 20}}}%%
flowchart LR
    R["IN_REVIEW"]:::lp --> A{"Compliance decision"}
    A --- L1(["all proofs approved"]):::lbl --> OK["ACTIVE"]
    A --- L2(["correction requested"]):::lbl --> P["PENDING_KYC<br/>statusReason, and verificationReason on the proof"]
    P --> U["Correct the data or<br/>upload the same proofType again,<br/>then POST .../verify again"]
    U --> R
    A --- L3(["case rejected"]):::lbl --> NO["REJECTED<br/>reason in the status history"]
    OK --> B["Compliance may later block and unblock"]
    classDef default fill:#31467c,stroke:#0c1a29,stroke-width:1px,color:#ffffff,font-family:Manrope
    classDef lp fill:#0c1a29,stroke:#0c1a29,color:#ffffff
    classDef terminal fill:#0c1a29,stroke:#0c1a29,color:#ffffff
    classDef lbl fill:#0c1a29,stroke:#0c1a29,color:#ffffff,font-size:13px
  • Approved: the entity becomes ACTIVE.
  • Correction requested: the entity returns to PENDING_KYC with the reason in statusReason, and each rejected file carries its own verificationReason. Upload a replacement with the same proofType, or correct the data, then call Request Verification again.
  • Rejected: the entity becomes REJECTED and the reason is in the status history. A REJECTED entity cannot be submitted again: register a new entity with a new externalId, or contact your account manager.

Status history after approval, with each change, who made it, and why:

[
  {
    "fromStatus": "PENDING_KYC",
    "toStatus": "IN_REVIEW",
    "reason": "Review started",
    "changedBy": "12345",
    "correlationId": "b68165b9-1d60-4f9d-9919-7fee12411714",
    "createdAt": "2024-01-15T17:03:15Z"
  },
  {
    "fromStatus": "IN_REVIEW",
    "toStatus": "ACTIVE",
    "reason": "KYC approved",
    "changedBy": "67890",
    "correlationId": "b07a3416-11fb-48d8-8671-be471694f0a2",
    "createdAt": "2024-01-15T17:03:22Z"
  }
]

Rules to remember

  • You request the review with verify; approving or rejecting it is done only by Localpayment.
  • Editing entity data after approval does not change the recorded review. Editing a document resets its approved files to PENDING, and they are reviewed again.
  • BLOCKED and the return to ACTIVE are decided by Compliance. You see them in the status history with their reason.

Next steps


Did this page help you?