Verify an end-customer

After creating a customer, you upload their identity documents. For individuals, verification then runs automatically with our regulated KYC partner — there’s no separate submit step. The customer stays pending until verification completes — usually a few minutes, occasionally up to ~2 hours.

This page walks the flow end to end. For request/response schemas and code samples, see the Customers API reference.

The flow

Request an upload URL

For each file, request a pre-signed upload URL — POST /v1/customers/{id}/files. You get back a file_id and a short-lived upload_url. See Upload identity documents. Pass the file’s content_type (e.g. image/jpeg, application/pdf) — it comes back inside required_headers as the Content-Type you must send.

PUT the file bytes

Upload the file directly to the returned upload_url with the required_headers verbatim. Don’t send your Bearer token — the signed URL authorizes the upload itself. A mismatched Content-Type gets the file rejected by storage. Run this PUT from your backend — the signed URL isn’t browser-CORS-enabled, so a browser/SPA PUT fails with a CORS error. Echo required_headers verbatim (they include the Content-Type).

Attach the files

Map your uploaded file_ids to typed document slots — POST /v1/customers/{id}/files/attach. id_file is mandatory; other slots depend on the customer’s country.

Acknowledge (optional)

For individual customers, verification kicks off automatically the moment id_file is attached — there’s no separate provider submit step. POST /v1/customers/{id}/kyc is just an acknowledgement: it records kycSubmittedAt and returns 200. You can skip it, but calling it gives you a clean audit timestamp. See Submit KYC.

This is the individual flow. Business / KYB customers verify through a separate Technest-managed onboarding (beneficial owners + business documents), not this acknowledgement — see Individual vs business.

Listen for the result

Verification completes asynchronously — usually a few minutes, occasionally up to ~2 hours. Subscribe to the customer.status_changed webhook for the transition to verified or rejected. You can also poll retrieve customer — the status also refreshes from the banking partner on read, so a GET returns the latest even if the webhook is delayed.

If a customer is rejected

The upstream rail doesn’t allow re-submitting on a rejected record. To retry:

  1. Notify your end-user (e.g. “We couldn’t verify your ID — please retry with a clearer photo.”).
  2. Create a new customer with a new customer_reference (e.g. append -r2).
  3. Repeat the flow above.

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

Best practices

  • Validate file size + format client-side before requesting an upload URL — saves a round-trip on a bad file.
  • Treat a 403 on the upload PUT as “URL expired” — request a fresh one.
  • Don’t submit KYC until all required files are attached — partial submissions get rejected.
  • If a customer’s pending status persists past 24 hours, contact Technest support.
  • Map rejection reasons to friendly messages in your UI — don’t surface raw upstream codes to end-users.

Next

What’s next