API Reference

Integrate TrueGate identity verification into your application.

Download AI Integration GuideGive this file to Claude Code, ChatGPT, or any AI assistant to integrate TrueGate in minutes.

Authentication

All API requests require a Bearer token. Get your API key from Settings in the dashboard.

curl -H "Authorization: Bearer tg_live_your_api_key" \
  https://www.truegate.io/api/v1/verification

Integration Flow

1

Create a verification

Your backend calls POST /api/v1/verification with an API key. You receive a URL to redirect your user to.

2

Redirect user

Send your user to the url returned. They complete document capture and selfie on TrueGate.

3

Receive result

TrueGate sends a POST to your callback_url with the result. The user is also redirected to your redirect_url with query params.

4

Query anytime

You can also poll GET /api/v1/verification/{token} to check the status at any time.

Create Verification

POST/api/v1/verification

Request body

ParameterTypeRequiredDescription
vendor_datastringNoYour internal reference (e.g. user ID)
callback_urlstringNoURL to receive webhook POST with result
redirect_urlstringNoURL to redirect user after verification
verification_typestringNo"basic" (default)

Example

curl -X POST https://www.truegate.io/api/v1/verification \
  -H "Authorization: Bearer tg_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "vendor_data": "user-456",
    "callback_url": "https://yourapp.com/api/truegate-webhook",
    "redirect_url": "https://yourapp.com/onboarding/complete"
  }'

Response

{
  "token": "a1b2c3d4e5f6...",
  "url": "https://www.truegate.io/verify/a1b2c3d4e5f6...",
  "result_url": "https://www.truegate.io/verify/a1b2c3d4e5f6.../result",
  "session_id": 42,
  "expires_at": "2026-03-22T17:00:00.000Z"
}

Get Verification Result

GET/api/v1/verification/{token}
curl https://www.truegate.io/api/v1/verification/a1b2c3d4e5f6 \
  -H "Authorization: Bearer tg_live_your_api_key"

Response

{
  "token": "a1b2c3d4e5f6...",
  "status": "approved",
  "final_decision": "approved",
  "verification_type": "basic",

  // Personal info
  "extracted_name": "John Doe",
  "extracted_dob": "1990-01-15",
  "extracted_nationality": "Panama",
  "gender": "M",
  "place_of_birth": "Panama City",
  "address": "Av. Balboa 45, Panama City",

  // Document
  "extracted_document_type": "Identity Card",
  "extracted_document_number": "8-123-456",
  "issuing_country": "Panama",
  "issuing_country_code": "PAN",
  "issuing_subdivision": "Panama Province",
  "document_issue_date": "2020-05-10",
  "document_expiry_date": "2030-05-10",
  "document_status": "VALID",
  "document_quality_score": 92,

  // Individual document checks — "passed" | "failed" | "not_checked"
  "document_checks": {
    "template": "passed",
    "alteration": "passed",
    "mrz": "passed",
    "age": "passed",
    "duplicate": "passed",
    "expiry": "passed",
    "data_consistency": "passed",
    "photo_manipulation": "passed"
  },

  // Signed image URLs (5 min expiry) — download and re-host if you
  // need durable copies. provider_* are Didit-hosted fallbacks.
  "images": {
    "document_front": "https://<supabase>/...?token=...",
    "document_back": "https://<supabase>/...?token=...",
    "selfie": "https://<supabase>/...?token=...",
    "provider_front": null,
    "provider_back": null,
    "provider_portrait": null,
    "provider_selfie": null
  },

  // Biometric
  "identity_verified": true,
  "face_match_score": 96.37,
  "face_match_status": "MATCH",
  "liveness_passed": true,
  "liveness_score": 0.98,

  // Compliance
  "sanctions_match": false,
  "rejection_reasons": [],

  // Device fingerprint of the client that took the photos
  "device": {
    "ip": "200.24.60.10",
    "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_6 like Mac OS X) …",
    "browser": "Safari",
    "browser_version": "17.6",
    "os": "iOS",
    "os_version": "17.6",
    "device_type": "mobile"
  },

  "result_url": "https://www.truegate.io/verify/a1b2c3d4e5f6.../result",
  "created_at": "2026-09-29T12:34:56.000Z",
  "updated_at": "2026-09-29T12:35:12.000Z"
}

Field notes

  • address, issuing_subdivision, place_of_birth — OCR-extracted from the document. Empty when the document doesn't carry the value. For LATAM national IDs, the address usually lives on the back and only populates when the reverse side was captured.
  • document_checks — each key is one control Didit runs on the document. passed when no matching warning was raised, failed when Didit flagged that control, not_checked when Didit didn't evaluate it for that document type. In particular, mrz only resolves to passed/failed for two-sided documents where TrueGate captured the reverse; for passports (biodata page) it can be evaluated from the front alone.
  • images.document_front / document_back / selfie — signed URLs against TrueGate storage, valid 5 minutes from the API call. document_back is null when the visitor picked Passport in the capture flow (single-page document) and populated for national ID / driver's license / residence permit. Download and re-host if you need durable copies.
  • device — parsed at submit time from the phone/laptop that took the photos, not the org that owns the session. null for legacy verifications that predate the capture.

Hosted capture flow

When an end user opens the url returned by POST /api/v1/verification, the hosted flow now asks them to pick the document type before the camera opens, and captures only the photos that document actually needs:

  • National ID / Cedula — front + back. MRZ, address and anti-tampering patterns live on the back.
  • Driver's license — front + back.
  • Residence permit / Foreigner ID — front + back.
  • Passport — biodata page only. Asking for a back photo would add friction with no additional signal.

This means the OCR pass and the fraud checks that require the reverse side (MRZ validation, address extraction, signature check, front↔back data consistency) run automatically for two-sided documents. No integration change is needed on your side — the result JSON is the same shape whether or not the visitor captured a back image; the affected fields (address, images.document_back, document_checks.mrz) simply populate when the reverse side was part of the capture.

The dashboard History → Detail modal and the downloadable PDF report show both front and back thumbnails side by side when the reverse was captured.

List Verifications

GET/api/v1/verification?page=1&pageSize=20
curl "https://www.truegate.io/api/v1/verification?page=1" \
  -H "Authorization: Bearer tg_live_your_api_key"

Business Screening

Screen a company directly via the API. No verification link needed -- the result is returned immediately.

POST/api/v1/business-screening

Request body

ParameterTypeRequiredDescription
company_namestringYesName of the company to screen
countrystringNoCountry code (e.g. PA, US)
registration_numberstringNoCompany registration number
vendor_datastringNoYour internal reference
callback_urlstringNoURL to receive webhook POST with result

Example

curl -X POST https://www.truegate.io/api/v1/business-screening \
  -H "Authorization: Bearer tg_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Acme Corp",
    "country": "PA",
    "registration_number": "12345",
    "vendor_data": "company-ref-456",
    "callback_url": "https://yourapp.com/webhooks/truegate"
  }'

Response

{
  "token": "abc123...",
  "vendor_data": "company-ref-456",
  "result_url": "https://www.truegate.io/verify/abc123.../result",
  "company_name": "Acme Corp",
  "country": "PA",
  "status": "approved",
  "sanctions_match": false,
  "aml": {
    "status": "Approved",
    "total_hits": 0,
    "score": null,
    "hits": []
  },
  "news": {
    "total_articles": 5,
    "risk_articles": 0,
    "articles": [{ "title": "...", "source": "...", "url": "...", "published_at": "..." }],
    "risk": []
  },
  "registry": [],
  "created_at": "2026-07-22T..."
}

Cost: $0.50 per screening. Includes: sanctions/watchlist check (1,300+ lists), adverse media, Google News risk analysis.

Phone Validation & Antifraud

Validate a phone number with carrier lookup, identity match, SIM swap detection, reassigned number check, and SMS OTP -- all in a single API call. Results are returned directly.

POST/api/v1/phone-validation

Request body

ParameterTypeRequiredDescription
phone_numberstringYesPhone number in E.164 format (e.g. +15551234567)
full_namestringNoName to match against phone owner records
vendor_datastringNoYour internal reference
callback_urlstringNoURL to receive webhook POST with result

Example

curl -X POST https://www.truegate.io/api/v1/phone-validation \
  -H "Authorization: Bearer tg_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+15551234567",
    "full_name": "John Doe",
    "vendor_data": "user-456"
  }'

Response

{
  "token": "ph_abc123...",
  "status": "approved",
  "phone_number": "+15551234567",
  "carrier": {
    "name": "T-Mobile",
    "type": "mobile",
    "country": "US"
  },
  "identity_match": {
    "match": true,
    "score": 0.95,
    "registered_name": "John A Doe"
  },
  "sim_swap": {
    "detected": false,
    "last_swap_date": null,
    "risk": "low"
  },
  "reassigned": {
    "detected": false,
    "last_assignment_date": "2019-03-15"
  },
  "sms_verified": true,
  "risk_level": "low",
  "created_at": "2026-07-24T..."
}

Cost: $0.35 per validation. Includes: carrier lookup, identity match, SIM swap detection, reassigned number check, and SMS OTP.

Compliance Check

Run a standalone sanctions/AML check by name without requiring identity verification.

POST/api/compliance/check

Request body

ParameterTypeRequiredDescription
full_namestringYesFull name to screen (min 2 characters)
date_of_birthstringNoDate of birth (YYYY-MM-DD)
nationalitystringNoCountry code (e.g. PA, US)
check_typestringYes"registration", "withdrawal", or "batch"

Example

curl -X POST https://www.truegate.io/api/compliance/check \
  -H "Authorization: Bearer tg_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "full_name": "John Doe",
    "date_of_birth": "1990-01-15",
    "nationality": "PA",
    "check_type": "registration"
  }'

Response

{
  "check_id": 99,
  "match_found": false,
  "highest_match_score": 0.0,
  "risk_level": "low",
  "matches": [],
  "processing_time_ms": 245
}

Webhooks

Webhook callback

When a verification completes, TrueGate sends a POST to your callback_url:

{
  "event": "verification.completed",
  "token": "a1b2c3d4e5f6...",
  "vendor_data": "user-456",
  "status": "approved",
  "final_decision": "approved",

  // Personal info
  "extracted_name": "John Doe",
  "extracted_dob": "1990-01-15",
  "extracted_nationality": "Panama",
  "gender": "M",
  "place_of_birth": "Panama City",
  "address": "Av. Balboa 45, Panama City",

  // Document
  "extracted_document_type": "Identity Card",
  "extracted_document_number": "8-123-456",
  "issuing_country": "Panama",
  "issuing_country_code": "PAN",
  "issuing_subdivision": "Panama Province",
  "document_issue_date": "2020-05-10",
  "document_expiry_date": "2030-05-10",
  "document_quality_score": 92,
  "document_checks": {
    "template": "passed", "alteration": "passed", "mrz": "passed",
    "age": "passed", "duplicate": "passed", "expiry": "passed",
    "data_consistency": "passed", "photo_manipulation": "passed"
  },

  // Images — signed URLs, 5 min expiry
  "images": {
    "document_front": "https://<supabase>/...?token=...",
    "document_back": "https://<supabase>/...?token=...",
    "selfie": "https://<supabase>/...?token=..."
  },

  // Biometric
  "identity_verified": true,
  "face_match_score": 96.37,
  "face_match_status": "MATCH",
  "liveness_passed": true,
  "liveness_score": 0.98,

  // Compliance
  "sanctions_match": false,
  "rejection_reasons": [],

  // Only populated when the session ran a civil-registry check
  "database_validation": null,

  // Device fingerprint of the client that took the photos
  "device": {
    "ip": "200.24.60.10",
    "user_agent": "Mozilla/5.0 ...",
    "browser": "Safari",
    "browser_version": "17.6",
    "os": "iOS",
    "os_version": "17.6",
    "device_type": "mobile"
  },

  "timestamp": "2026-03-21T18:30:00.000Z"
}

User redirect

After verification, the user is automatically redirected to your redirect_url with query parameters:

https://yourapp.com/onboarding/complete?token=a1b2c3d4e5f6&status=approved&decision=approved

You can read the decision query param to immediately show the appropriate screen, then verify the result server-side via the API.

Result Page

Every verification returns a result_url. It's a merchant-facing page — visiting it as the merchant that owns the verification (signed in to the TrueGate dashboard) or as a TrueGate super admin renders the full report with every extracted field, the captured images, the government DB comparison and a download button for the PDF. Any other viewer, including the person who was verified, gets a plain "verification complete" acknowledgement with no PII.

Example URL

https://www.truegate.io/verify/{token}/result

Use result_urlas the merchant's own review link — share it with your compliance team or embed it in your internal dashboard. For a downloadable PDF of the same report, call GET /api/v1/verification/{token}/pdf with your API key.

Verification Types

TrueGate supports multiple verification types. Specify the type when creating a verification session via the verification_type field.

TypeDescriptionPrice
basicID + liveness + face match + sanctions$0.75
advancedBasic + 1000+ AML lists + PEP + adverse media + IP$1.25
business_amlCompany sanctions + adverse media + news$0.50
email_verificationEmail OTP$0.25
phone_verificationPhone OTP (WhatsApp)$0.25
phone_antifraudCarrier lookup + identity match + SIM swap + reassigned number + SMS OTP$0.35
database_validationGov database, 18 LATAM countries$1.50
customMix & match stepsper step

Statuses & Errors

Verification statuses

StatusDescription
pendingSession created, waiting for user
processingUser submitted, verification in progress
approvedAll checks passed
rejectedOne or more checks failed
expiredSession expired (24 hours)

Error codes

HTTPCodeDescription
401UNAUTHORIZEDMissing or invalid API key
402INSUFFICIENT_BALANCENot enough balance. Top up in dashboard
403FORBIDDENVerification belongs to another organization
404NOT_FOUNDVerification not found
422VALIDATION_ERRORInvalid request parameters

Pricing

TrueGate charges per verification based on the type selected.

Verification TypePriceIncludes
basic$0.75ID verification, passive liveness, face match, sanctions screening (OFAC, UN, EU)
advanced$1.25Everything in basic + 1000+ AML lists, PEP screening, adverse media, IP analysis
business_aml$0.50Company sanctions, adverse media, Google News risk analysis (1,300+ lists)
email_verification$0.25Email OTP verification
phone_verification$0.25Phone OTP via WhatsApp
phone_antifraud$0.35Carrier lookup + identity match + SIM swap + reassigned number + SMS OTP
database_validation$1.50Government database validation, 18 LATAM countries
customper stepMix & match individual verification steps

No minimums. Top up anytime in Settings. Compliance checks via POST /api/compliance/check are included at no extra cost.

SDKs & Mobile Integration

TrueGate provides native SDKs for mobile apps. Each SDK opens the verification flow in a branded WebView with native callbacks.

React Native

@truegate/react-native-sdk
npm install @truegate/react-native-sdk react-native-webview

import { TrueGateVerify } from '@truegate/react-native-sdk';

<TrueGateVerify
  url={verificationUrl}
  visible={showVerify}
  onComplete={(result) => {
    if (result.status === 'approved') { /* verified */ }
  }}
  onCancel={() => setShowVerify(false)}
/>
View on GitHub →

iOS (Swift)

TrueGateSDK
// Swift Package Manager
.package(url: "https://github.com/eflorezlabequis/truegate", from: "1.0.0")

import TrueGateSDK

let truegate = TrueGate(apiKey: "tg_live_...")
truegate.presentVerification(from: self, url: verificationUrl) { result in
    switch result {
    case .success(let r): print(r.isApproved)
    case .failure(let e): print(e)
    }
}
View on GitHub →

Android (Kotlin)

io.truegate.sdk
// build.gradle
implementation("io.truegate:sdk:1.0.0")

val truegate = TrueGate("tg_live_...")
truegate.presentVerification(this, verificationUrl, object : TrueGateCallback {
    override fun onComplete(result: TrueGateResult) {
        if (result.isApproved) { /* verified */ }
    }
    override fun onCancelled() { }
    override fun onError(error: Exception) { }
})
View on GitHub →

TrueGate API v1 — www.truegate.io