Direct URL Integration

This guide covers integrating the AdvanGuard Web SDK using direct URL redirection — the simplest integration method.

Why Choose URL Integration?

✅ Simplest Implementation: redirect to a URL
✅ No Iframe Restrictions: avoids iframe-related browser limitations
✅ Works Everywhere: compatible with all browsers and webviews
✅ Mobile-Friendly: works for mobile apps and deep links
✅ Quick MVP: get started in minutes

How It Works

┌──────────────┐
│  Your App    │
└──────┬───────┘
       │
       │ 1. User clicks "Verify"
       │
       ▼
┌────────────────────────────┐
│  Your Backend              │  POST /v1/individual/applications
│                            │  (or POST /v1/client-integration/links to
│                            │   re-issue a link for an existing application)
└──────┬─────────────────────┘
       │
       │ 2. Response contains link.url
       │
       ▼
┌──────────────┐
│  Your App    │  Redirect to link.url
└──────┬───────┘
       │
       │ 3. window.location.href = link.url
       │
       ▼
┌─────────────────────┐
│  AAI Verification   │  User completes Document / Face steps
│  (new page/tab)     │
└──────┬──────────────┘
       │
       │ 4. Flow ends → redirect to submittedUrl / successUrl / rejectUrl
       │
       ▼
┌──────────────────────┐
│  Your Redirect URL   │  Handle the hand-off, then fetch the result:
│  (your app)          │  GET /v1/individual/applications/{applicationId}
└──────────────────────┘

How To Integrate

Before you start

ItemWhere to get it
accessKey / secretKeyDashboard → Developer Hub → API Credential
A Level containing a Document and/or Face stepDashboard → Configuration → Verification Levels — see Verification Level
API base URLhttps://openapi.advance.ai (Production SG)

Note: the newer and older integration models differ. The examples below use the current AdvanGuard API (Get started with API). If your account is still on the legacy Identity Verification model, refer to the corresponding legacy documentation instead.

1. Create the Application and Get the URL

Authenticate first — see Authentication — then create an Application:

curl -X POST https://openapi.advance.ai/v1/individual/applications \
  -H "Authorization: Bearer <accessToken>" \
  -H "Content-Type: application/json" \
  -d '{
    "levelId": "level-kyc-standard",
    "externalUserId": "user-001",
    "inputInfo": {
      "preferences": { "language": "en-US", "prefersColorScheme": "light" }
    },
    "link": {
      "ttlSeconds": 604800,
      "redirect": {
        "submittedUrl": "https://yourapp.com/kyc/submitted",
        "successUrl":   "https://yourapp.com/kyc/success",
        "rejectUrl":    "https://yourapp.com/kyc/failed"
      }
    }
  }'

Response (200 OK):

{
  "applicationId": "app-7392581047263518721",
  "profileId": "prof_01a0b245aa137be19e7fa44a116eedb5",
  "levelId": "level-kyc-standard",
  "levelVersion": 3,
  "created": "2026-10-08T08:00:00Z",
  "link": {
    "linkId": "AAECAwQFBgcICQoLDA0ODw",
    "url": "https://flow.advance.ai/ekyc/<flow-hash>?linkId=AAECAwQFBgcICQoLDA0ODw&language=en-US&theme=light",
    "status": "ACTIVE",
    "expiresAt": "2026-10-15T08:00:00Z"
  },
  "requestId": "req-example"
}

Open link.url exactly as returned — linkId identifies the verification session and must not be replaced or edited.

FieldTypeNotes
link.ttlSecondsinteger1 – 2592000 (30 days); default 604800 (7 days)
link.redirect.submittedUrlHTTPS URLOpened after the applicant submits (under review)
link.redirect.successUrlHTTPS URLOpened when verification succeeds
link.redirect.rejectUrlHTTPS URLOpened when verification is rejected or not completed
inputInfo.preferences.languageBCP 47 tage.g. en-US, zh — see Supported Languages
inputInfo.preferences.prefersColorSchemelight | darkDefault light
link.redirect requires at least one URL and every value must be HTTPS.

No link in the response? The Level contains no client collection step (for example an API-only or AML-only Level). This is not an error.
Re-issue a link for an existing Application — if a link expired or the applicant needs another attempt, create a new link instead of a new Application (Create a client access link):

curl -X POST https://openapi.advance.ai/v1/client-integration/links \
  -H "Authorization: Bearer <accessToken>" -H "Content-Type: application/json" \
  -d '{"target": {"targetType": "APPLICATION", "targetId": "app-7392581047263518721"},
       "ttlSeconds": 1800, "language": "en-US", "prefersColorScheme": "light"}'

Existing links can be reviewed with List client access links and Retrieve a client access link.

2. Open the URL in a WebView

link.url is a standard web URL, so your app opens it directly (window.location.href = link.url). No special handling is required.
The redirect targets you configured in step 1 are HTTPS only at API level. If your app must land on a custom scheme (myapp://…), let the flow finish on an HTTPS URL you control and forward to your app scheme from there.

3. Give Camera Permission

Refer to Camera Permission for Android WebView (onPermissionRequest) and iOS WebView (NSCameraUsageDescription + WKWebViewConfiguration + a pre-flight AVCaptureDevice.authorizationStatus check).
Fallback behaviour when the camera is unavailable is controlled by frontend feature flags (enableFallback, enableNoPermissionDirectReturn) — see Frontend Configuration.

4. Handle the Redirect URL

The flow ends on one of the three URLs configured in step 1.

CaseURL usedWhen it happensParameters appended
Under reviewsubmittedUrlApplicant submitted all required materials and is under reviewnone
SuccesssuccessUrlVerification passednone
Failure / not completedrejectUrlApplicant did not complete the flow, or verification failederrorCode, message
Example:
https://yourapp.com/kyc/failed?errorCode=CAMERA_ISSUE

Parameters are appended to your URL as configured (query string, or the fragment if your URL contains one); your existing parameters are preserved.

The redirect is a signal, not a result. These parameters are not trustworthy on their own — confirm the outcome with the API (step 5) before changing any user status.

Failure errorCode values

errorCodeDescriptionNode
ERRORSystem error, backend processing exception or network issueCOMMON
BROWSER_ISSUENot supported due to browser compatibility issuesCOMMON
NOT_SUPPORTNot supported due to compatibility issuesCOMMON
CAMERA_ISSUECamera unavailable or the camera stream failedCOMMON
NO_PERMISSIONCamera permission denied (returned when the flow is configured to return directly instead of showing the permission page)COMMON
DOCUMENT_AUTO_SCAN_TRY_COUNT_EXCEEDDocument auto-scan try count exceeded the limitDOCUMENT
DOCUMENT_MANUAL_TRY_COUNT_EXCEEDDocument manual photo try count exceeded the limitDOCUMENT
DOCUMENT_GALLERY_TRY_COUNT_EXCEEDGallery upload retry count exceededDOCUMENT
RESELECT_DOC_TYPEUser clicked to reselect document typeDOCUMENT
RESELECT_REGIONUser clicked to reselect regionDOCUMENT
A message parameter accompanies errorCode for troubleshooting only — do not show it to end users.

5. Get the Result

  1. Query the Application: GET /v1/individual/applications/{applicationId} — returns status (init / pending / onHold / completed / terminated) and, once completed, review.reviewAnswer (GREEN / RED) with per-step results under stepResults.
  2. Or subscribe to webhooks: APPLICATION_PENDING, APPLICATION_ON_HOLD, APPLICATION_COMPLETED, APPLICATION_TERMINATED — see Webhooks. Webhook delivery is not guaranteed; keep a polling fallback (10 minutes or greater).
  3. Identity data lives on the Profile, not on the Application response: GET /v1/individual/profiles/{profileId}.

Troubleshooting

IssueSolution
No link in the create responseThe Level has no client collection step — not an error.
Redirect never reachedConfirm the redirect URLs are HTTPS and publicly reachable from the applicant's browser. An invalid link.redirect is rejected at creation time with 400 invalid_request_error.
Link expiredexpiresAt has passed. Re-issue with POST /v1/client-integration/links for the same Application, or create a new Application.
409 active_application_existsAn active Application already exists for this externalUserId and is not resumed automatically. Re-issue its link, or terminate the old Application in the Dashboard.
409 application_create_in_progressAnother creation is running for the same user — retry with backoff.
Camera permission denied in an in-app browserComplete step 3, and keep the flow out of iframes.
Redirect received but the outcome is unclearExpected — resolve it with the API or the webhook event, not the redirect parameters.