Veyns Palm API
Integrate palm authentication and enrollment with your backend. Veyns returns an
opaque palmId; your application maps it to its own user record and manages the
user session.
Operations
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v2/authenticate |
Identify an enrolled palm |
| POST | /api/tee/templates/enroll/unique |
Create a palm identity |
| POST | /api/tee/templates/enrollments/{clientEnrollmentId}/recover |
Recover the original enrollment response |
| POST | /api/tee/templates/enrollments/{clientEnrollmentId}/ack |
Confirm receipt delivery and activate the identity |
Before you integrate
You need an assigned HTTPS API origin, an API token and a provisioned Veyns capture client. The capture client produces complete JSON requests and retains enrollment recovery state. Send those requests intact. Do not construct captures from a palm ID, an image or a subset of the JSON fields.
OpenAPI describes request transport and server responses. It does not define capture production. Use the complete object supplied by the capture client, including fields not listed in this reference. Custom capture implementations require separate provisioning.
An integration uses one deployment's identity population. API scopes control operations; they do not separate customer accounts or organizations. The API does not issue signed application assertions, callbacks or request-bound authorization results. Access requires a provisioned deployment and capture client.
Access
Use the base URL assigned to your integration, represented as VEYNS_API_BASE_URL
in the examples. Send JSON over HTTPS with one authorization header:
Authorization: Bearer <api-token>
Content-Type: application/json
| Scope | Operations |
|---|---|
authenticate |
Identify an enrolled palm |
enroll |
Enroll, recover a receipt and acknowledge delivery |
Keep the token on your trusted backend or provisioned capture client. Never embed it in browser JavaScript. Provision a replacement before retiring an expiring token; rotation does not replace an enrollment's recovery key or attempt ID.
Authenticate
Send the complete JSON request from a fresh capture. The file below represents a request supplied by the provisioned capture client; it is not included with this guide. Exclude capture data and credentials from logs, tracing and source control.
curl --request POST "${VEYNS_API_BASE_URL}/api/v2/authenticate" \
--header "Authorization: Bearer ${VEYNS_API_TOKEN}" \
--header 'Content-Type: application/json' \
--data-binary @authentication-request.json
The following is an illustrative response excerpt. Additional compatibility fields are described in OpenAPI.
{
"success": true,
"palmId": "u_0123456789abcdef0123456789abcdef",
"matchedHand": "LEFT",
"dualHandRequired": true,
"dualHandComplete": true,
"confidence": null
}
| Field | Handling |
|---|---|
success |
Must be true before accepting an identity |
palmId |
Must be a non-empty string; treat it as opaque |
matchedHand |
LEFT, RIGHT or null; match information only |
dualHandRequired |
Whether the deployment requires both hands at enrollment |
dualHandComplete |
Whether the identified enrollment is complete |
confidence |
Optional; may be null. Do not invent a score |
message |
Diagnostic text. Do not parse it as an error code |
HTTP 200 also carries unsuccessful outcomes. A false success can mean no match,
an invalid capture, an incomplete enrollment or temporary unavailability. Do not
grant access from the HTTP status alone. Legacy userId and user fields are
compatibility data; use the top-level palmId for new integrations.
Consume the response on your backend over the trusted capture flow. Bind it to your own pending user action before creating a session. A palm ID supplied by a browser or a success screen on a terminal is not an authenticated backend result. This API has no signed remote handoff protocol.
Enroll
The capture client owns the enrollment attempt. In dual-hand enrollment it captures
one left hand and one right hand, creates clientEnrollmentId, and retains its
recovery key and exact pending request before submission.
- Send the complete request to
POST /api/tee/templates/enroll/unique. - Return the full successful response to the originating capture client, including
enrollmentReceiptandreceiptDigest. - Let the client durably save, decrypt and verify the receipt.
- Forward its signed acknowledgement to the acknowledgement operation.
- Mark enrollment complete only after
{ "success": true, "state": "ACKED" }.
| Response field | Meaning |
|---|---|
palmId |
Identity created by this enrollment |
clientEnrollmentId |
Original attempt ID |
replayed |
true when the stored response was returned again |
enrollmentReceipt |
Protected receipt; forward it unchanged to the originating client |
receiptDigest |
Digest used by the client when verifying and acknowledging the receipt |
enrolledHands |
Hands included in the enrollment |
HTTP 200 from enrollment is not activation. For dual-hand enrollment, authentication remains unavailable for that identity until receipt delivery is acknowledged. An identical request with the same attempt ID can replay its stored result. Reusing that ID with different request contents is a conflict.
A deployment provisioned for single-hand enrollment returns no protected receipt; the capture client follows that provisioned flow. The recovery and acknowledgement operations apply to dual-hand enrollment.
Recover an interrupted enrollment
If the enrollment response is lost, preserve the original attempt and use:
POST /api/tee/templates/enrollments/{clientEnrollmentId}/recover
{
"terminalId": "terminal-example",
"signature": "<base64 signature supplied by the originating capture client>"
}
The signature is SHA256withRSA over UTF-8 text, with LF separators and no trailing newline:
veyns.enrollment-recover.v1
<clientEnrollmentId>
<terminalId>
HTTP 200 returns the original enrollment response with replayed: true. Pass the
whole response back to the client. A 404 does not prove that creating another
identity is safe. A 409 with state: RECONCILIATION_REQUIRED needs resolution of the
original attempt. Preserve its ID, protected data and recovery key.
Acknowledge receipt delivery
After the client has verified the receipt, send its acknowledgement:
POST /api/tee/templates/enrollments/{clientEnrollmentId}/ack
{
"terminalId": "terminal-example",
"receiptDigest": "<64 lowercase hexadecimal characters>",
"signature": "<base64 signature supplied by the originating capture client>"
}
The signature is SHA256withRSA over UTF-8 text, with LF separators and no trailing newline:
veyns.enrollment-ack.v1
<clientEnrollmentId>
<terminalId>
<receiptDigest>
The response is:
{ "success": true, "state": "ACKED" }
Retrying the same acknowledgement is idempotent. If its response is lost, retain the verified receipt and retry that acknowledgement. Do not return to capture or replace the attempt. This acknowledgement confirms enrollment delivery only.
Errors and retries
| Status or outcome | Action |
|---|---|
200, success: false |
Authentication did not complete. Do not authorize the user |
400 |
Correct the malformed request or have the capture client produce a valid request |
401 |
Check whether the token is missing, invalid, expired or revoked |
403 |
The token lacks the required scope |
404 during recovery |
Preserve the original enrollment and reconcile its state |
409 during authentication |
Refresh the capture client's policy before a new capture |
409, duplicate: true during enrollment |
A palm is already enrolled. Resolve the existing identity |
409, state: RECONCILIATION_REQUIRED |
Preserve the attempt and arrange reconciliation |
500, 503 or transport timeout |
Treat an enrollment outcome as unknown until resolved |
Use status codes and structured fields. Diagnostic text can change. Enrollment
errors can use error; authentication and access failures can use message.
Do not apply an automatic retry loop to every operation. In particular, an uncertain
enrollment must retain its original ID, request, terminal binding and recovery key.
A duplicate response after an earlier timeout can be related to that original
attempt; it is not permission to start over.
Integration acceptance
Verify successful and unsuccessful authentication, missing and insufficient token scopes, duplicate enrollment, lost enrollment responses and lost acknowledgement responses using a provisioned test environment. Confirm that your backend never accepts a browser-supplied palm ID and never treats HTTP 200 alone as a match.