Server-side enrolment
Enrol people from your own app or kiosk when you collect the photo and consent yourself.
Use this when the person opts in inside your app (for example a native member app, a sign-in kiosk or a staffed front desk). If you can, prefer the widget: it handles consent wording, the camera and photo quality for you, and keeps photos off your servers.
The request#
POST /v1/lists/{listId}/people →
{
"personId": "ACME-000123",
"imageBase64": "<JPEG, base64>",
"consent": {
"consentVersion": "uk-v2",
"givenAt": "2026-11-01T14:03:00Z",
"explicitBiometricConsent": true,
"writtenRelease": true,
"under16": false,
"guardianConsent": false
}
}
personId is your ID for the person: a ticket number, membership number or employee ID (up to 200 characters).
FacePing checks the consent before it even decodes the photo: without explicit consent and the written release (and a guardian's consent for under-16s), it refuses with 400 and never processes the image.
Consent#
Record exactly what the person agreed to. The wording follows the list's country: use the list's consentVersion (from GET /v1/lists/{listId} or the create response), show the published wording for that version and send the same version as consent.consentVersion:
| List country | Version | Wording |
|---|---|---|
United States (US) |
us-v2 |
Written biometric release (wording) |
| EU and EEA countries | eu-v2 |
Consent wording |
| Anywhere else, the UK included | uk-v2 |
Consent wording |
A list with no country follows your account's country, then your billing currency. See Which wording people see.
Only the list's current version is accepted, so if FacePing publishes new wording, show it and send the new version. People must tick the boxes themselves: never pre-tick them, and never make face check-in a condition of buying a ticket, joining or anything else.
The photo#
- One face, looking at the camera, in good light; nothing covering it.
- JPEG, longest side up to about 1280 px. Larger photos work but upload slowly, and FacePing works at 1280 px anyway. (If you use the .NET SDK,
EnrollmentPhoto.Preparedoes this for you.) - The whole request can be up to 15 MB (about 11 MB of photo once it's base64 encoded).
| Response | Meaning |
|---|---|
201 |
Enrolled, with a Location header (/v1/lists/{listId}/people/{personId}) and personId, modelId and deleteAfter in the body. Enrolling the same personId again replaces the face, also with 201 (still one person on your bill). |
400 |
personId missing or over 200 characters, consent missing or invalid, or the image isn't valid base64, JPEG or PNG. |
402 |
Your plan doesn't allow more people (the pilot's 500, or no plan). |
404 |
No such list (or not yours). |
409 |
Enrolment is closed for this list, or the list has ended, or consent.consentVersion isn't the list's consentVersion (show people the list's wording and send that version). |
413 |
The request is over 15 MB. |
422 |
No usable face: none found, more than one, or too small. Ask for a new photo. |
The photo is used once and never stored or logged.
Close enrolment#
When a list is final (the doors have opened, say, or sign-up has closed), close enrolment. No one else can enrol, from your server, the widget or the dashboard, and no new enrolment links can be created. Check-in devices get the final list at their next sync. People already enrolled stay until their faces are deleted as usual. Enrolment can't be reopened, and the list's enrollmentClosed is then true.
curl -X POST https://api-eu.faceping.ai/v1/lists/$LIST_ID/close-enrollment -H "X-Api-Key: $FACEPING_API_KEY"