Skip to main content

Backend API integration (without the npm SDK)

This is the end-to-end recipe for integrating Zyphe from your backend using the HTTP SDK API (https://api.zyphe.com/sdk/...) directly—no Node, browser, or React Native package required.

You will:

  1. Create a verification request with a secret API key
  2. Compose a hosted session URL from the response
  3. Open that URL in a WebView, iframe, or browser redirect
  4. Receive results via webhook (and optionally fetch images via the Export API)

If you prefer packages, use the Node SDK for the same API. For product tradeoffs, see Hosted UI vs direct API and Choosing an integration method.

Naming

SDK API means the HTTP routes under /sdk/... on api.zyphe.com.
SDK packages means @zyphe-sdk/node, @zyphe-sdk/browser, and related npm libraries. You can use the HTTP API without installing any package.

Prerequisites

ItemWhere
Secret API key (zyphe_sk_…)API keys
Flow ID (UUID)Dashboard → flow settings
Correct hostsEnvironment setup
Sandbox flag alignedSandbox mode
Webhook URL on the flow (recommended)Webhooks

1. Create a verification request

curl -X POST "https://api.zyphe.com/sdk/flow/${ZYPHE_FLOW_ID}/vr/create?sandbox=true" \
-H "x-api-key: ${ZYPHE_SECRET_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"email": "applicant@example.com",
"customData": {
"externalUserId": "user_123",
"plan": "pro"
}
}'
PieceValue
Method / pathPOST /sdk/flow/{flow_id}/vr/create
Querysandbox=true for sandbox, sandbox=false for production (required)
Headerx-api-key: zyphe_sk_… (secret key)
BodyIdentity + optional customData (see below)

Provide at least one identity: email, and/or credentials such as external ID or wallet (see OpenAPI SdkCreateVerificationRequestPayload).

Response fields you need

A successful response includes (among other fields):

FieldUse
verificationRequest.idSession id → query param zypheVr
zypheTokenSession JWT → query param zypheToken
zypheAccessSigShort-lived access signature → query param zypheAccessSig
flowSlugHosted UI path segment
flowStepSlugFirst incomplete step (informational; URL uses flowSlug)
isSandboxMust match the sandbox query you sent
emailEcho of identity email when present → optional zypheEmail

Full schema: OpenAPI SdkCreateVerificationRequestResponse.

customData

  • Optional JSON object of arbitrary key/value metadata attached to the verification request.
  • Round-trips into webhooks as data.<type>.customData and top-level custom (see Custom fields).
  • Use opaque business identifiers (your user id, application id). Avoid putting secrets or unnecessary PII in query strings if you also pass metadata on public links.

2. Compose the session URL

https://verify.zyphe.com{/sandbox}/flow/<flowSlug>?zypheVr=<verificationRequest.id>&zypheToken=<zypheToken>&zypheAccessSig=<zypheAccessSig>&zypheEmail=<email>
ModeBase path
Sandbox (sandbox=true)https://verify.zyphe.com/sandbox/flow/<flowSlug>
Production (sandbox=false)https://verify.zyphe.com/flow/<flowSlug>

Example (sandbox):

https://verify.zyphe.com/sandbox/flow/my-kyc-flow?zypheVr=cf52e18e-28d1-4a2f-8304-c04ef5a75d0f&zypheToken=eyJ...&zypheAccessSig=...&zypheEmail=applicant%40example.com

Optional query parameters supported by the hosted UI and npm helpers:

ParamPurpose
zypheFullscreen=trueFullscreen layout (recommended in mobile WebViews)
zypheHandoffBaseUrlReturn / handoff base URL for your app
Theme paramsSee Theming

Always URL-encode query values.

warning

Do not open https://api.zyphe.com/... in a WebView. Users complete verification on verify.zyphe.com. The API host is only for your backend.

3. Present the URL to the user

PlatformPattern
WebRedirect the browser, or embed in an iframe (Browser SDK automates this)
MobileLoad the URL in a WebView with camera permissions (Mobile integration)
Email / SMSSend the composed URL (or use a public flow link when you do not need server-side session creation)

4. Receive results

  1. Configure a webhook URL on the flow.
  2. Verify X-Signature (Webhook signature).
  3. Branch on event / flowStatus (Statuses and codes).
  4. Correlate with your system via custom / customData.

Document images are not included in webhook payloads by default. Extended webhooks may include a limited selfie URL; full document media requires the Export API (must be enabled by Zyphe).

5. Optional: complete steps without the hosted UI

You can drive document selection, document upload, and liveness from your backend using the step endpoints documented in OpenAPI and the Node complete-step helpers. That path has important tradeoffs (capture quality, device signals, liveness modes). Read Hosted UI vs direct API before choosing it.

Minimal Node example (raw fetch)

const API = process.env.ZYPHE_API_BASE_URL ?? 'https://api.zyphe.com'
const VERIFY = process.env.ZYPHE_VERIFY_BASE_URL ?? 'https://verify.zyphe.com'
const apiKey = process.env.ZYPHE_SECRET_API_KEY!
const flowId = process.env.ZYPHE_FLOW_ID!
const sandbox = process.env.ZYPHE_SANDBOX !== 'false'

async function createSessionUrl(email: string, customData?: Record<string, unknown>) {
const res = await fetch(`${API}/sdk/flow/${flowId}/vr/create?sandbox=${sandbox}`, {
method: 'POST',
headers: {
'x-api-key': apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, customData }),
})

if (!res.ok) {
const err = await res.json().catch(() => ({}))
throw new Error(`Create VR failed: ${res.status} ${JSON.stringify(err)}`)
}

const data = await res.json()
const pathPrefix = data.isSandbox ? '/sandbox' : ''
const params = new URLSearchParams({
zypheVr: data.verificationRequest.id,
zypheToken: data.zypheToken,
zypheAccessSig: data.zypheAccessSig,
})
if (data.email || email) {
params.set('zypheEmail', data.email ?? email)
}
params.set('zypheFullscreen', 'true')

return `${VERIFY}${pathPrefix}/flow/${data.flowSlug}?${params.toString()}`
}

Common failures

SymptomLikely causeFix
Connection / HTML error pageAPI base URL is docs.zyphe.com or another non-API hostUse https://api.zyphe.com
401 · invalid_api_keyPublishable key, typo, or wrong environmentUse zyphe_sk_…; see API errors
Flow / VR not foundsandbox flag does not match the flowAlign flag, dashboard mode, and URL path
User stuck / blank WebViewMissing camera permissions or wrong WebView flagsMobile integration
No images in webhookExpected by designExport API