← All docs

Api Reference

API Reference

Base URL: https://api.idova.id — resolves to the environment you're reading on. The production URL is issued when you go live.

All endpoints:

  • Authenticate with Authorization: Bearer idv_{test|live}_…
  • Accept both the internal ULID and the short public ID (e.g. kyc_A5X7Q2P4NJ) in path parameters
  • Return JSON
  • Support Idempotency-Key on POSTs

Applicants

Create an applicant

POST /v1/applicants

Body

{
  "firstName":   "Jane",
  "lastName":    "Smith",
  "email":       "jane@example.com",
  "phone":       "+14165551234",
  "dob":         "1990-06-15",
  "country":     "CA",
  "externalRef": "customer-1234",
  "metadata":    { "source": "mobile-signup" }
}

Response 201

{
  "id": "app_01KP47W4G6RBS3B5M8CHKE0EAM",
  "publicId": "app_B8K2R9T4NM",
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane@example.com",
  "phone": "+14165551234",
  "dob": "1990-06-15",
  "country": "CA",
  "externalRef": "customer-1234",
  "metadata": { "source": "mobile-signup" },
  "status": "active",
  "createdAt": "2026-04-15T12:00:00Z",
  "updatedAt": "2026-04-15T12:00:00Z"
}

List applicants

GET /v1/applicants?page=0&size=20&includeArchived=false

Get an applicant

GET /v1/applicants/{id}

Update an applicant

PATCH /v1/applicants/{id}

Body (all fields optional — null = no change)

{ "email": "newemail@example.com", "phone": "+14165559999" }

KYC requests

Create a KYC request

POST /v1/kyc-requests

Provide exactly one of applicantId (for an existing applicant) or applicant (inline create).

Body

{
  "applicant": {
    "firstName": "Jane",
    "lastName":  "Smith",
    "email":     "jane@example.com",
    "dob":       "1990-06-15",
    "country":   "CA"
  },
  "environment":  "sandbox",
  "workflowType": "standard",
  "callbackUrl":  "https://yourapp.example.com/kyc-callback",
  "redirectUrl":  "https://yourapp.example.com/kyc-complete",
  "externalRef":  "onboarding-1234",
  "metadata":     { "channel": "mobile" }
}

Or with an existing applicant:

{ "applicantId": "app_B8K2R9T4NM", "environment": "sandbox" }

Response 201

{
  "id":              "kyc_01KP4FAA2YZ9Q4HCWRJK2FV7HG",
  "publicId":        "kyc_A5X7Q2P4NJ",
  "applicantId":     "app_01KP47W4G6RBS3B5M8CHKE0EAM",
  "applicantPublicId": "app_B8K2R9T4NM",
  "status":          "link_generated",
  "decision":        "pending",
  "environment":     "sandbox",
  "portalUrl":       "https://idova.id/portal/abc123…",
  "portalExpiresAt": "2026-04-17T12:00:00Z",
  "createdAt":       "2026-04-15T12:00:00Z"
}

List KYC requests

GET /v1/kyc-requests?page=0&size=20&status=awaiting_review

Get a KYC request

GET /v1/kyc-requests/{id}

Returns the full request DTO including automationDecision, automationConfidence, processingResult with signal breakdown + reasons.

Get events timeline

GET /v1/kyc-requests/{id}/events

Every lifecycle transition, append-only.

Get captured documents

GET /v1/kyc-requests/{id}/documents

Each document includes a pre-signed downloadUrl valid for 10 minutes.

Get captured selfies

GET /v1/kyc-requests/{id}/selfies

Get screening results

GET /v1/kyc-requests/{id}/screenings

AML screening outcomes (sanctions, PEP, adverse media) for the request.

Download report PDF

GET /v1/kyc-requests/{id}/report.pdf

Returns a complete A4 compliance report: applicant details, captured images with thumbnails embedded, screening results, signal breakdown, events timeline, reviewer notes.

Download report JSON

GET /v1/kyc-requests/{id}/report.json

Same content as the PDF, structured for programmatic consumption.

AML screening

Screen a person against sanctions, PEP, and adverse-media lists on its own — no document or biometric verification. Use this when you need an AML check without a full identity flow. Each check can optionally be enrolled in ongoing monitoring (re-screened daily; a new hit raises an aml_check.monitoring_alert webhook).

Create an AML check

POST /v1/aml-checks

Synchronous — the response carries the verdict and the per-list results. Supports Idempotency-Key.

Body

{
  "firstName":   "Jane",
  "lastName":    "Smith",
  "dob":         "1990-06-15",
  "country":     "CA",
  "monitoring":  false,
  "environment": "sandbox"
}

Only firstName and lastName are required; dob and country sharpen matching and reduce false positives.

Response 201

{
  "id":            "aml_01KSGBGEA0YKNP8898XNDJEXMF",
  "publicId":      "aml_40AFMCDB33",
  "environment":   "sandbox",
  "firstName":     "Jane",
  "lastName":      "Smith",
  "dob":           "1990-06-15",
  "country":       "CA",
  "status":        "no_match",
  "riskLevel":     null,
  "matchCount":    0,
  "monitoringEnabled": false,
  "lastScreenedAt": "2026-05-25T12:00:00Z",
  "createdAt":      "2026-05-25T12:00:00Z",
  "results": [
    { "checkType": "sanctions",     "provider": "opensanctions", "status": "clear", "riskLevel": "low", "matchCount": 0, "matches": [] },
    { "checkType": "pep",           "provider": "opensanctions", "status": "clear", "riskLevel": "low", "matchCount": 0, "matches": [] },
    { "checkType": "adverse_media", "provider": "brave-llm",     "status": "clear", "riskLevel": "low", "matchCount": 0, "matches": [] }
  ]
}

Job status (rolled up from the three checks):

StatusMeaning
no_matchevery list came back clear
potential_matchat least one list returned a hit — review the results[].matches
faileda provider errored (fail-closed — not a clean pass); retry

Get an AML check

GET /v1/aml-checks/{id}

Returns the check including the per-list results and their matches.

List AML checks

GET /v1/aml-checks?page=0&size=10&status=potential_match

status filter is optional.

Download AML report PDF

GET /v1/aml-checks/{id}/report.pdf

A compliance PDF of the check — subject, verdict, per-list results + match records, and monitoring history. The JSON equivalent is just GET /v1/aml-checks/{id}.

Rate limits

See Authentication → Rate limits.

OpenAPI

Auto-generated OpenAPI specification:

GET /v3/api-docs

Interactive Swagger UI (dev only):

/swagger-ui/index.html