Skip to content

Quick Start

Three steps. Your backend creates an application, the applicant completes it on their phone, and UpPass posts the result to you.

How an UpPass verification flows from your backend, through the applicant’s device, to your webhook

  1. In the Portal, select your workspace and open API Token in the left-hand menu. Generate one — it is shown once — and keep it server-side.

    Terminal window
    export UPPASS_API_TOKEN='...'

    Full detail: Create an application → Before you start.

  2. One call per applicant. {form_slug} is your flow’s name from Portal → Flows → your flow → Settings.

    Terminal window
    curl --request POST \
    'https://app.uppass.io/en/api/forms/{form_slug}/create/' \
    --header 'Authorization: Bearer '"$UPPASS_API_TOKEN" \
    --header 'Content-Type: application/json' \
    --data '{ "answers": {} }'
    201 Created
    {
    "detail": { "slug": "{slug}", "submitted_at": null },
    "form_url": "https://app.uppass.io/en/form/{form_slug}/{slug}/"
    }

    Store detail.slug against your own record, and send the applicant to form_url — as a link, a QR code, or inside a WebView. That is the only key that ties the result back to them.

  3. In the Portal, open Connect → Add Webhook: enter your HTTPS URL, choose Bearer authorization and a secret, and subscribe to submit_form.

    Your endpoint receives a POST with a JSON body and Authorization: Bearer {webhook_secret}. Check the secret, return 2xx within 30 seconds, and look up your record by application.slug.

    POST to your webhook — abridged
    {
    "event": { "type": "submit_form", "created_at": "2026-08-26T09:51:56.458646+00:00" },
    "application": {
    "slug": "{slug}",
    "status": "complete",
    "submitted_at": "2026-08-26T09:51:48.165780+00:00",
    "other_status": { "ekyc": "pass" }
    },
    "answers": {
    "full_name_en_first_name": { "value": "SOMCHAI" },
    "full_name_en_last_name": { "value": "JAIDEE" },
    "date_of_birth": { "value": "1990-01-15" },
    "document_number": { "value": "AB0000001" }
    },
    "extra": {
    "ekyc": {
    "face_compare": { "status": "match", "score": 85.72 },
    "liveness": { "url": "https://app.uppass.io/api/ekyc/{slug}/result/image/?q=...&exp=..." },
    "identity_document": { "url": "https://app.uppass.io/api/ekyc/{slug}/result/image/?q=...&exp=..." }
    }
    }
    }

    other_status.ekyc is the combined document-and-liveness verdict. The detail behind it is in extra.ekyc: identity_document is the scan, liveness the selfie capture, and face_compare the match between them — so if face_compare is present, both earlier steps succeeded. The image URLs expire 15 minutes after delivery, so fetch them first.