Skip to main content

Compliance Workflows

Celar compliance has two operational parts:

  • Customer verification (KYC/KYB) during onboarding and customer updates
  • Transaction monitoring (KYT) during pay-ins and post-transaction review

Use this page as the main operational reference for both.

1. Customer Verification (KYC/KYB)

Verification Lifecycle

  1. Create the customer record via API. kyc_status starts as pending.
  2. Send the Terms of Service consent link (POST /customers/{customer_id}/celar-consent) and wait for acceptance.
  3. Upload the required documents (PATCH /customers/uploads).
    • Individuals upload proof_of_residential_address only.
    • Businesses upload proof_of_residential_address, incorporation_certificate, and proof_of_business_address.
    • This also triggers a background OpenSanctions screen against global sanctions, PEP, and watchlists.
  4. Trigger Didit verification via the customer compliance endpoint (POST /customers/compliance).
    • For individuals, Didit handles the identity-document and face/liveness step.
    • For businesses, Didit verifies the primary contact while the business documents are reviewed from the uploads step.
  5. Customer completes the Didit verification flow via the link sent by email.
  6. Once the sanctions screen, required uploads, and Didit verification pass, kyc_status moves to approved and the customer is cleared for transactions.
  7. Add payment details (PATCH /customers/payment-details) - this can be done any time after customer creation, but it is required before the customer can transact.
  8. If the customer's phone number or wallet address changes later, kyc_status moves to pending_update and Celar automatically re-runs compliance checks.

Required Documents

Customer typeRequired uploads
Individualproof_of_residential_address
Businessproof_of_residential_address, incorporation_certificate, proof_of_business_address

For individual customers, do not upload passport, driver_license, or id_card through PATCH /customers/uploads. Identity-document capture happens inside the Didit verification flow.

For business customers, the uploaded company documents stay the same: proof_of_residential_address, incorporation_certificate, and proof_of_business_address. The primary contact still completes the Didit verification step.

Upload Customer Documents

Attach the required address and business verification documents to an existing customer. Documents are sent as multipart/form-data, not JSON.

All files must be PDF format, max 5 MB each.

FieldRequiredDescription
customer_idYesID of the customer to attach documents to
proof_of_residential_addressYesUtility bill, bank statement, or similar (required for all customer types)
incorporation_certificateBusiness onlyRequired for business customers
proof_of_business_addressBusiness onlyRequired for business customers

Individual customer example:

curl --request PATCH \
--url https://api.sandbox.celar.io/api/v1/customers/uploads \
--header 'Authorization: Bearer <token>' \
--form 'customer_id=cr_53c79dae85d2cee2' \
--form 'proof_of_residential_address=@/path/to/proof_address.pdf'

Business customer example:

curl --request PATCH \
--url https://api.sandbox.celar.io/api/v1/customers/uploads \
--header 'Authorization: Bearer <token>' \
--form 'customer_id=cr_53c79dae85d2cee2' \
--form 'proof_of_residential_address=@/path/to/proof_address.pdf' \
--form 'incorporation_certificate=@/path/to/cert.pdf' \
--form 'proof_of_business_address=@/path/to/business_address.pdf'

Example Response

{
"message": "Documents uploaded successfully."
}

Complete Didit Verification (POST /customers/compliance)

After Terms of Service acceptance and the required uploads are in place, call Celar's Didit initiation endpoint under Customers: POST /customers/compliance. This sends a verification link to the customer's email address.

  • For individuals, Didit handles identity-document capture and face/liveness verification.
  • For businesses, Didit verifies the primary contact while Celar reviews the uploaded business documents.

Once the customer completes the verification, kyc_status updates to approved when all required checks have passed.

curl --request POST \
--url https://api.sandbox.celar.io/api/v1/customers/compliance \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"customer_id": "cr_c32e9ac9d9a0d6ac",
"email": "john.doe@example.com"
}'

Example Response

{
"message": "Identity verification link sent successfully",
"data": {
"email": "john.doe@example.com"
}
}
note

The email field in the request body is the address where the verification link will be sent. It does not need to match the email on the customer record.

Business Workflow Summary

For business customers, the KYB flow is:

  1. Create the business customer record
  2. Send the Terms of Service consent link
  3. Upload proof_of_residential_address, incorporation_certificate, and proof_of_business_address
  4. Trigger Didit verification for the primary contact
  5. Wait for kyc_status to move to approved
  6. Add payment details before transacting

Verification Status Expectations

  • pending - Customer record created; compliance flow not yet completed
  • id_verification_pending - Verification link sent; waiting for the customer to complete the Didit flow
  • approved - All checks passed. The customer is cleared for transactions.
  • manual_review - A potential sanctions match was found; Celar is reviewing manually.
  • pending_update - Customer details or wallet address changed; Celar is re-running compliance checks.

For broader compliance verdicts, responsibilities, and policy context, see Compliance Details.

2. Transaction Monitoring (KYT)

Celar's compliance engine runs KYT (Know Your Transaction) checks automatically on all pay-ins. Use these endpoints to fetch individual results or review summaries.

Get Risk for a Pay-in

Retrieve the KYT verdict for a specific payin_id.

curl --request GET \
--url https://api.sandbox.celar.io/api/v1/risk/payments/<payin_id> \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <your_api_key>'

Example Response

{
"payment_id": "payin_47cb728afdb91063",
"kytVerdict": "low",
"totalScore": 0,
"flags": [],
"checked_at": "2025-09-26T12:08:08.840Z"
}

List Historical KYT Checks

Retrieve historical KYT risk evaluations for all pay-ins under your PSP.

Optional Query Parameters

  • level -> filter by risk level (low, medium, high)
  • limit -> number of results to return
  • offset -> pagination offset
curl --request GET \
--url "https://api.sandbox.celar.io/api/v1/risk/checks?level=high&limit=10&offset=0" \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <your_api_key>'

Get Customer Risk Summary

Retrieve compliance summary for a specific customer.

curl --request GET \
--url https://api.sandbox.celar.io/api/v1/risk/summary/customers/<customer_id> \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <your_api_key>'

Example Response

{
"customer_id": "cr_ef211d4ba9c0",
"risk_level": "medium",
"last_check": "2025-09-26T11:55:04.522Z"
}

Get PSP Risk Summary

Retrieve an aggregate compliance summary for your entire PSP account.

curl --request GET \
--url https://api.sandbox.celar.io/api/v1/risk/summary/total \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <your_api_key>'

Example Response

{
"psp_id": "psp_3563fdacebcb",
"total_checks": 245,
"risk_levels": {
"low": 220,
"medium": 20,
"high": 5
},
"last_check": "2025-09-26T12:12:47.733Z"
}

Notes

  • KYT runs only on pay-ins.
  • Payouts and withdrawals do not trigger KYT checks directly.
  • Customer- and PSP-level summaries help you monitor compliance health across your organization.