Alaqan Pass API
Seamless biometric verification using palm recognition technology
Overview
Alaqan Pass provides a seamless biometric verification solution using palm recognition technology. Integrate with just two API calls and a single redirect URL to enable secure user enrollment and identification.
How It Works
- Create Session — Call our API to generate a unique verification URL
- Redirect User — Send the user to the URL in their browser
- User Completes — User follows the palm scanning flow on our hosted page
- Receive Result — Get notified via webhook when verification completes
Authentication
All API requests require authentication using an API key sent in the X-API-Key header.
curl -X POST "https://api.pass.alaqan.com/v1/enroll" \
-H "X-API-Key: xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json"
Endpoints
POSTEnroll User
Creates a verification session for enrolling a new user's palm biometrics.
POST /enroll
Headers
| Header | Required | Description |
|---|---|---|
| X-API-Key | Yes | Your API key |
| Content-Type | Yes | application/json |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| language | string | en | UI language code (en, kk, ru) |
Request Body
{
"external_id": "EMP-12345",
"username": "John Doe",
"metadata": {
"department": "Engineering",
"access_level": "standard"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| external_id | string | Yes | Your unique identifier for the user (max 100 chars) |
| username | string | No | Display name for the user (max 150 chars) |
| metadata | object | No | Custom key-value data to store with the user |
Response
{
"url": "https://pass.alaqan.com/enroll/abc123xyz..."
}
| Field | Type | Description |
|---|---|---|
| url | string | Redirect the user to this URL to complete enrollment |
Example
curl -X POST "https://api.pass.alaqan.com/v1/enroll?language=en" \
-H "X-API-Key: xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"external_id": "EMP-12345",
"username": "John Doe",
"metadata": {"department": "Engineering"}
}'
Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Bad Request | Missing or invalid external_id |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Partner account is inactive |
| 409 | Conflict | User with this external_id already enrolled |
POSTIdentify User
Creates a verification session for identifying an existing user by their palm.
POST /identify
Headers
| Header | Required | Description |
|---|---|---|
| X-API-Key | Yes | Your API key |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| language | string | en | UI language code (en, kk, ru) |
Response
{
"url": "https://pass.alaqan.com/identify/xyz789abc..."
}
| Field | Type | Description |
|---|---|---|
| url | string | Redirect the user to this URL to complete identification |
Example
curl -X POST "https://api.pass.alaqan.com/v1/identify?language=en" \
-H "X-API-Key: xxxxxxxxxxxxxxxxxxxx"
Error Responses
| Status | Error | Description |
|---|---|---|
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Partner account is inactive |
Webhooks
Receive real-time notifications when a verification session completes. Configure your webhook URL in the partner dashboard.
Webhook Payload
When a session completes, we send a POST request to your configured webhook URL.
{
"event": "completed",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"type": "enroll",
"external_id": "EMP-12345",
"username": "John Doe",
"metadata": {
"department": "Engineering"
},
"language": "en"
}
}
Event Types
| Event | Description |
|---|---|
| completed | User successfully completed verification |
| failed | Verification failed (see fail_reason) |
| expired | Session expired before completion |
Payload Fields
| Field | Type | Description |
|---|---|---|
| event | string | Event type |
| timestamp | string | ISO 8601 timestamp of the event |
| data.session_id | string | Unique session identifier (UUID) |
| data.type | string | Session type: enroll or identify |
| data.external_id | string | Your user identifier |
| data.username | string | User display name (if provided) |
| data.metadata | object | Custom metadata (if provided) |
| data.fail_reason | string | Reason for failure (if status is failed) |
| data.language | string | Language used in the session |
Webhook Security
All webhook requests include an HMAC signature in the X-Webhook-Signature header.
X-Webhook-Signature: sha256=<signature>
Verifying the Signature
JavaScript:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Python:
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
Retry Policy
If your endpoint returns a non-200 status code, we retry with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
After 5 failed attempts, the webhook is marked as failed and will be disabled in the dashboard.
Session Flow
URL Expiration
- Session URLs expire after 15 minutes by default
- Expired sessions return 400 Bad Request with message link expired
- Used sessions return 410 Gone if accessed again
Rate Limits
| Endpoint | Limit |
|---|---|
| POST /enroll | 100 requests/minute |
| POST /identify | 100 requests/minute |
Rate limit headers are included in all responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800
Error Handling
All errors follow a consistent format:
{
"message": "external_id is required"
}
HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created (session URL returned) |
| 400 | Bad Request — Invalid parameters |
| 401 | Unauthorized — Invalid API key |
| 403 | Forbidden — Partner inactive |
| 404 | Not Found — Resource doesn't exist |
| 409 | Conflict — Duplicate resource |
| 410 | Gone — Session already used |
| 429 | Too Many Requests — Rate limit exceeded |
| 500 | Internal Server Error |