KYC submission

After creating a customer, you need to upload KYC documents + submit them for review with our regulated KYC partner. The flow:

  1. Request a pre-signed upload URL for each file you need to attach (POST /v1/customers/{id}/files).
  2. PUT the file bytes directly to the returned URL.
  3. Attach the uploaded files to the customer with named slots (POST /v1/customers/{id}/files/attach).
  4. Submit KYC (POST /v1/customers/{id}/kyc) — triggers verification review.
  5. Wait for the customer_verified webhook OR poll GET /v1/customers/{id} until status flips.

Step 1 — Request upload URL

POST /v1/customers/{id}/files

Request

{
  "file_category": "id_document",
  "filename": "passport.jpg",
  "content_type": "image/jpeg"
}
FieldNotes
file_categoryOne of: id_document, id_document_back, proof_of_address, liveness_check
filenameOriginal filename (preserved upstream)
content_typeMIME — image/jpeg, image/png, application/pdf

Response

{
  "object": "file_upload_intent",
  "file_id": "file_xxx",
  "upload_url": "https://upload-storage.example.com/...",
  "expires_at": "2026-05-05T12:39:56Z",
  "required_headers": {
    "Content-Type": "image/jpeg"
  }
}

The upload_url is a pre-signed PUT URL valid for ~5 minutes. PUT the file bytes directly with the indicated Content-Type header.


Step 2 — Upload the file

curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: image/jpeg" \
  --data-binary @passport.jpg

The endpoint returns 200 on success. On expiry / wrong content-type, it returns 4xx — request a fresh URL.


Step 3 — Attach files to customer

POST /v1/customers/{id}/files/attach

After ALL files are uploaded, attach them to the customer in named slots:

{
  "id_file": "file_xxx",
  "id_file_back": "file_yyy",
  "proof_of_address_file": "file_zzz"
}

id_file is mandatory — without it the verification flow won’t trigger. Other slots are optional depending on the customer’s country.

Response

200 OK with a confirmation envelope.


Step 4 — Submit KYC

POST /v1/customers/{id}/kyc

Submits the full KYC package to our regulated KYC partner for review. After this, the customer is locked into the verification pipeline; you can’t re-upload documents until they’re either verified or rejected.

{}

(Empty body — all data was captured at customer-create + file-attach.)

Response

{
  "object": "customer",
  "id": "ckcust_xxx",
  "status": "pending",
  "kyc_submitted_at": "2026-05-05T12:34:56Z",
  ...
}

The customer’s status stays pending until verification completes. Typical review window: a few hours to 1 business day.


Step 5 — Listen for verification webhook

Subscribe your webhook endpoint to customer_verified and customer_rejected events:

{
  "event": "customer_verified",
  "data": {
    "object": "customer",
    "id": "ckcust_xxx",
    "customer_reference": "pouch-user-12345",
    "status": "verified",
    "verified_at": "2026-05-05T18:23:11Z"
  }
}
{
  "event": "customer_rejected",
  "data": {
    "object": "customer",
    "id": "ckcust_xxx",
    "customer_reference": "pouch-user-12345",
    "status": "rejected",
    "rejected_at": "2026-05-05T18:23:11Z",
    "rejection_reason": "ID document unreadable"
  }
}

On rejection, you’ll need to create a fresh customer with a NEW customer_reference + re-upload corrected documents. The upstream rail doesn’t allow re-submitting on a rejected customer record.


Recovery: customer rejected

If a customer is rejected:

  1. Notify your end-user (e.g. “Your verification couldn’t be completed — please retry with a clearer photo of your ID.”)
  2. On retry, generate a NEW customer_reference (e.g. append -r2 to the original) — the upstream rail won’t accept a re-submission on the original ref.
  3. Repeat steps 1-5 with the new customer record.

The old (rejected) customer record stays in our DB for audit but is excluded from active operations.


Best practices

  1. Validate file size + format client-side before requesting an upload URL — saves a round-trip if the file is bad.
  2. Capture user-facing errors on the upload PUT — a 403 there typically means the URL expired; request a fresh one.
  3. Don’t submit KYC until ALL required files are uploaded — partial submissions get rejected.
  4. Monitor verification time — if a customer’s pending status persists > 24 hours, contact Technest support to investigate at the upstream rail.
  5. Capture rejection reasons in your UI — don’t surface raw upstream codes to your end-users; map them to friendly messages.