REST API: data erasure
Erase session personal data
Destroy the personal data of a session on request.
Purpose
Use this call when a person asks for their data to be erased, withdraws consent, or when the purpose of processing is achieved. The call destroys the document data, contacts, images and video of the session, and the person record the session created, unless another session or a manual entry still holds that record. The session itself stays, with its verdict and without the personal data.
The caller needs the kycSessionDelete permission. When the destruction finishes, the PD_ERASURE_COMPLETE webhook reports it. See also the data protection overview and the data erasure log.
Request
POST <API_BASE_URL>/kyc/session/erase. All calls are POST under your API address. Replace <API_BASE_URL> with the API address provided with your access.
Send a permanent API token in the token field of the body, or a user token in the token header. See authentication.
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
token | string (uuid) | if no header | Your permanent API token. Required unless you send a user token in the token header. |
sessionId | string | one of two | The session whose personal data is destroyed. Send exactly one of sessionId and clientUser. |
clientUser | string | one of two | Your identifier of the user, as you set it when creating sessions. The personal data of every session of your group with this value is destroyed, whenever it was created. The length is from 1 to 36 characters once edge spaces are cut. |
reason | string | no | Why the data is destroyed, written to the destruction journal. One of subject_request, consent_withdrawn, purpose_achieved, unlawful_processing or operator_request. Without it the journal records operator_request. |
Sessions still being passed. A session the user is still passing is not refused: the call closes it and destroys its data. The widget then shows the session as finished, and further uploads to it are refused.
No personal data in identifiers. clientKey and clientUser stay on the session and in the journal after the destruction. Do not put personal data into them: send an opaque identifier of your own.
After the destruction. Creating or opening a session with the same clientKey gives back that finished session, not a new one. To verify the person again, create a session with a new clientKey.
A stage-one questionnaire record without a session is not destroyed by this call. Use delete questionnaire session.
Response
HTTP 200. The personal data is destroyed. With clientUser, the answer lists every session in sessions, newest first, each with its own result, and the overall result is erased only when every session in the list is.
| Field | Type | Description |
|---|---|---|
status | string | Always ok on this body. |
result | string | erased: the destruction is finished. Repeating the call answers the same, also after the session was deleted from the dashboard. |
sessionId | string | The session, as in the request. |
pdErasedAt | string (date-time) | When the destruction was completed, a UTC timestamp to the whole second. |
parts | object | The state of each kind of data: text, media, person and questionnaire. Each has a state of erased, kept, unconfirmed or absent. |
parts.text.state | string | Document data, contacts, browser fingerprint and check provider answers. |
parts.media.state | string | Images of the face and the documents, liveness video and frames. |
parts.person.state | string | The person record the session created: face vector, photo and name in the face list. |
parts.questionnaire.state | string | Answers of the stage-one questionnaire record the session was linked to. |
HTTP 202. Part of the destruction could not be confirmed while the call waited, for example because media storage did not answer. The system keeps trying without another call, and the PD_ERASURE_COMPLETE webhook arrives when it is done.
| Field | Type | Description |
|---|---|---|
result | string | in_progress: the destruction is started and not finished. parts shows what is confirmed so far. |
Branch on result. Do not branch on the HTTP code or on status alone: erased is the only outcome that means the destruction is finished, and status is ok while it is still going on.
Kept data. A state of kept comes with a reason: linked_session when another session of the same person still holds the record, manual_person when the record was entered by hand, or blacklist_person when the record is on a blacklist.
By clientUser. The call waits about 20 seconds in total. Sessions it has not finished by then are in_progress; the system finishes them and the PD_ERASURE_COMPLETE webhook arrives for each of them. Repeating the call returns the current state.
Errors
400: The body does not match the request schema: neither or both ofsessionIdandclientUserwere sent.401: The token is missing, expired or unknown.403: The token holder lacks thekycSessionDeletepermission.404: No session with this identifier, or with thisclientUser, belongs to your group. A session of another group is not told apart from a missing one.500: An unexpected internal failure. The answer hasstatusoferrorand the fixed textinternal error; nothing in the body helps you branch beyond the code.
A refusal can also come before the operation runs: an address outside your IP allowlist, a token bound to another address, or a body that is not valid JSON. See response format and errors.
Example
Request:
curl -X POST "<API_BASE_URL>/kyc/session/erase" \
-H "Content-Type: application/json" \
-d '{
"token": "<your permanent API token>",
"sessionId": "00000000-0000-0000-0000-000000000000",
"reason": "subject_request"
}'
Response:
{
"status": "ok",
"result": "erased",
"sessionId": "00000000-0000-0000-0000-000000000000",
"pdErasedAt": "2026-01-01T10:00:00Z",
"parts": {
"text": {
"state": "erased"
},
"media": {
"state": "erased"
},
"person": {
"state": "erased"
},
"questionnaire": {
"state": "absent"
}
}
}