Open the request
Verihop shows the requesting service and the exact details it wants.
Your Personal Identity
Verihop is a personal identity app. Verify who you are from an official identity document on your phone, then approve exactly what each service receives. No account is required to start.
Start from the link. On supported iPhones, the first verification can open without installing the full app; on Android, continue in Verihop.
Start from a Verihop link or QR code. You see who is asking and which details they need before anything is shared.
Verihop shows the requesting service and the exact details it wants.
Follow one guided check using your identity document and a live face check.
Only the details you approve are returned. Save the verification in the app to reuse it later when it is still valid and accepted.
A better handoff
Layered checks, a same-flow result, and less personal data handed over.
Privacy detail: the requesting company receives no document or selfie files. One chip portrait and one selfie are processed transiently for the holder match; the full document is not uploaded. Read the privacy notice.
Made for real life
Result: age eligibility
Confirm an age requirement without sending the shop a copy of your passport.
Result: selected identity details
Share the requested name, age, or document details without typing them again.
Result: approved onboarding fields
Complete one guided phone flow and return directly to the service you chose.
Personal Identity API
Request verified personal identity fields, send the returned launch URL, receive callback tokens, and fetch the user-approved result server-to-server. The same contract covers iOS, Android, App Clip, app links, and desktop QR flows.
FIVE-MINUTE QUICKSTART
Keep the API key on your backend, request only the fields you need, and send the user to the returned launch_url.
curl https://api.verihop.com/v1/sessions \
-H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" \
-d '{
"app": "RideNow",
"header": "Age check",
"fields": ["legalName", "over18"],
"callback": "https://ridenow.example/verified"
}'
Path: https://api.verihop.com
Authenticate partner requests from your backend only:
Authorization: Bearer <api_key>
Create a test account first to get an API key for integration. Test-account responses are redacted by design, and the same account can later be upgraded to active for production.
POST /v1/sessions with callback URL and requested fields.launch_url.session_id and result_token.GET /v1/sessions/{id} for status updates.GET /v1/sessions/{id}/result.Postman collection
Set your API key and callback URL, create a session, then paste the callback result token to fetch the verified result.
/v1/sessionsCreate a verification session and get deep link + signed session token.
Authorization: Bearer <api_key>
Content-Type: application/json
Idempotency-Key: <uuid> // recommended
{
"app": "RideNow",
"header": "Age check",
"fields": ["legalName", "over18", "documentNumber"],
"callback": "ridenow://verified"
}
app: Partner app display name shown inside Verihop (max 80 chars).header: Short verification title shown to the user (max 120 chars).fields: Requested field tokens; if omitted/empty, fallback is legalName and over18.callback: Base return URL sent in POST /v1/sessions. Verihop opens it after completion and appends session_id, result_token (success path), and optional callback_jwt; required and allowlist-validated in your production policy.Authorization: Partner API key in bearer format.Content-Type: Use application/json for request body parsing.Idempotency-Key: Retry key for create-session dedupe; send UUID v4/v7 and reuse only for same payload retries.201 response{
"session_id": "sess_123",
"expires_at": 1730000000,
"launch_url": "https://www.verihop.com/verify.html?session_id=sess_123&token=h_abc123",
"app_clip_url": "https://appclip.apple.com/id?p=KycBox.VerifyBox.Clip&session_id=sess_123&token=h_abc123",
"qr_url": "https://www.verihop.com/verify.html?session_id=sess_123&token=h_abc123",
"status_url": "https://api.verihop.com/v1/sessions/sess_123"
}
session_id: Unique session identifier for tracking and result retrieval.expires_at: Session expiry (Unix epoch seconds).launch_url: Primary URL for web, Android, QR codes, emails, SMS, and general handoff.app_clip_url: Direct native App Clip URL for iOS partner apps. Open it exactly as returned; do not reconstruct it.qr_url: QR-safe URL; currently equivalent to launch_url.status_url: Session status endpoint for server-side polling.401 missing_bearer_token, 401 invalid_api_key403 customer_inactive400 missing_callback_url, invalid_callback_url, callback_host_not_allowed400 field_not_allowed, invalid_field_token, request_too_large409 idempotency_key_conflict, idempotency_key_in_progress429 rate_limit_exceeded, daily_quota_exceeded/v1/sessions/{id}Non-PII session status endpoint for desktop orchestration and monitoring.
Authorization: Bearer <api_key>
200 response{
"session_id": "sess_123",
"status": "issued",
"issued_at": 1730000000,
"expires_at": 1730000300,
"last_status": null,
"last_status_at": null,
"result_available": false,
"result_token_expires_at": null
}
/.well-known/jwks.jsonPublic signing keyset endpoint for verifying callback_jwt on partner backends.
200 response{
"keys": [
{
"kty": "RSA",
"kid": "kid_2025_01",
"alg": "RS256",
"use": "sig",
"n": "...",
"e": "AQAB"
}
]
}
/v1/sessions/{id}/resultFetch verified result payload server-to-server using one-time result token.
Authorization: Bearer <api_key>
X-Result-Token: <result_token>
200 response{
"session_id": "sess_123",
"status": "success",
"result": {
"legalName": "Jane Doe",
"over18": "yes"
}
}
401 missing_bearer_token, invalid_api_key, missing_result_token403 customer_mismatch, invalid_result_token410 result_token_expired409 result_token_used404 result_not_available, session_not_foundfields)legalName, dateOfBirth, over18, over21, passport, idCard, documentNumber, documentExpiry, documentCountry, documentNationality
The result contains only the requested supported fields approved by the user. Document-kind requirements such as passport and idCard do not automatically include every document attribute.
Yes. Your backend creates a session using POST /v1/sessions, then renders the returned qr_url inside a QR shown on the desktop page. The user scans that QR with their phone and Verihop opens the best available experience.
Best UX is direct launch: encode the returned qr_url. It is the same universal HTTPS handoff as launch_url and supports app, lightweight, and web fallback paths.
Use launch_url on Android and for general web handoff. An iOS partner app that wants the native App Clip card should open the returned app_clip_url. Your callback shape remains the same: Verihop appends session_id, success-path result_token, and optional callback_jwt.
Create the session on your backend and send the returned app_clip_url to your iOS app. Open that URL with SwiftUI Link or UIApplication.open on iOS 17 or later. Do not parse launch_url, copy its token, or hard-code Verihop's App Clip bundle ID. If the full Verihop app is installed, iOS opens it instead while preserving the same session.
If you use a custom callback such as ridenow://verified, the Android partner app must declare an intent filter for that scheme and host. If you use an https:// callback for desktop or web-started flows, treat it as a backend endpoint unless your Android app owns that domain with verified App Links.
Use an https:// callback endpoint on your backend. After Verihop completes, your server receives session_id and result_token, then fetches GET /v1/sessions/{id}/result server-to-server.
jwt from POST /v1/sessions?No. That token is for Verihop app consumption. Partners should treat it as opaque transport data and use launch_url to launch Verihop.
Callback query parameters are transport metadata only. Verified personal data is intentionally not sent in callback URLs. Your backend must exchange the one-time result_token to fetch the result payload securely. If enabled, callback_jwt can be verified via JWKS for callback authenticity.
callback_jwt, and where?Yes, on partner backend when present. Verify signature and claims using Verihop JWKS at GET /.well-known/jwks.json. Validate issuer/audience/expiry and ensure JWT claims match callback query values.
No. Keep API keys server-side and fetch results from your backend only. The frontend/web client should only handle UI and pass state to your backend session.
Create a new session when a session expires or the user abandons the flow. result_token is short-lived and single-use; if consumed or expired, restart with a new POST /v1/sessions.
Provide a fallback page behind your QR flow that can explain how to install/open Verihop and then continue. After install, create a new session and show a fresh QR (do not reuse stale sessions).
POST /v1/sessions supports Idempotency-Key for retry-safe create-session calls: same key + same payload replays the original response, while same key + different payload returns 409 idempotency_key_conflict. Misuse is further mitigated with API-key auth, callback allowlist policy, field allowlist checks, per-customer rate limits/quota, short session TTL, and one-time result_token.
Personal Identity Verification
Your customer verifies their personal identity from an official document on their phone. Verihop returns only the approved fields to your backend—without handing you document or selfie files.
Your backend creates a session for details such as legal name, age eligibility, or document information.
The customer verifies on their phone and approves the exact details requested.
Your backend exchanges a short-lived token for the approved fields and continues the customer journey.
Clear responsibilities
Verihop handles
Your company keeps
The Sessions API does not return passport images, document portraits, selfies, or reusable biometric templates.
The commercial case
Replace upload-heavy screens with one guided mobile flow and a direct return to your product.
Use one integration instead of maintaining document parsing, chip reading, face checks, and mobile edge cases.
Receive approved verified fields instead of building archives of document scans and selfie images.
Returning users can approve a saved verification when it remains valid and your policy accepts it.
And there’s more
Start with one use case, then expand without rebuilding the handoff.