Developers
Integrate against a contract, not guesswork
Every operation is described in the OpenAPI 3.1 contract: request, response and error schemas, key scopes, idempotency and pagination. An unsupported operation returns an explicit error with a reason rather than silence.
Channels for the applicant
Verification link
A verification page on the service domain with your colour and logo. The link is created in one request and has an expiry.
Web widget
An SRI-pinned loader of about 3 KiB embeds the check in a frame on your page; third-party cookies are not needed.
iOS SDK
iOS 15 or later, NFC chip reading on iPhone 7 and newer, App Attest attestation, a key in the Secure Enclave.
Android SDK
Android 8.0 or later, CameraX camera, NFC IsoDep, Play Integrity, Russian and English interface.
A verification link in one request
Create the applicant and the case, then the link. Repeating the request with the same Idempotency-Key returns the same result.
curl https://api.verkyc.com/v1/cases/$CASE_ID/hosted-links \
-H "Authorization: Bearer $VERKYC_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"locale": "en", "return_url": "https://example.com/onboarding/done"}'How the API works
- Keys for the test and live environments with scopes; rotation without downtime.
- Idempotency-Key for every create and change operation: safe retries after a network failure.
- Cursor pagination bound to the list filter; ETag and If-Match for changing versioned objects.
- Errors in application/problem+json with a machine code, a retry flag and field pointers.
- Rate limits with a 429 response and a Retry-After header.
Signed webhooks
Events for cases, checks, reports, monitoring, deletion and exports. Every attempt is signed with HMAC-SHA256 over the timestamp, the event id and the body; retries follow a schedule of up to one day, after which the event can be replayed from the console. On key rotation the previous key stays valid for 24 hours.
import { createHmac, timingSafeEqual } from 'node:crypto';
// rawBody is the request body as received, before JSON parsing.
export function verifyWebhook(secret, headers, rawBody) {
const timestamp = headers['x-webhook-timestamp'];
const eventId = headers['x-webhook-id'];
const expected = createHmac('sha256', secret)
.update(`${timestamp}.${eventId}.`)
.update(rawBody)
.digest('hex');
const signature = Buffer.from(headers['x-webhook-signature'] ?? '', 'utf8');
const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300;
return fresh && signature.length === expected.length && timingSafeEqual(signature, Buffer.from(expected, 'utf8'));
}Report verification
The report is signed with ES256 (JWS over the canonical JSON form). Public keys are published at /.well-known/report-signing-jwks.json, and report authenticity is verified by reference without sharing personal data.
curl https://api.verkyc.com/public/reports/verify \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"verification_reference": "<reference from the report>", "report_sha256": "<SHA-256 of the report file>"}'Test environment
The test environment runs on synthetic data: engines and sources return predefined outcomes so you can exercise every branch of the integration, including refusals and manual review. No real documents or faces are needed.
Frequently asked questions
Are there rate limits?
Yes. Above the limit the API answers 429 with a Retry-After header; repeating the request with the same Idempotency-Key is safe.
How do I get a test key?
Leave a request on the contact page. After onboarding, keys are created in the developer section of the console.
Where can I see all operations?
In the API reference on this site: operations are grouped by section, each with its method, path, parameters, request body and responses.
See it on your own scenarios
Tell us who you need to verify and where. We will prepare a demo, test API access and a price estimate.