Record a consent
POST /v1/users/{user_id}/consent-records · permission consent-records:write
Records an acceptance you obtained in your own channel (method = management_api). The subject is a legal document (subject_type = document; consent purposes are not available yet) and state is presented, accepted or declined. The version, content hash and locale are taken from the document; you cannot supply them. occurred_at defaults to now and cannot be in the future or more than 5 minutes old. Records are append-only: they are never updated or deleted.
Request
Path parameters:
| Field | Type | Required | Description |
|---|---|---|---|
user_id |
string | yes | User ID (usr_…). |
JSON body (unknown fields are rejected with 400 unknown_field):
| Field | Type | Required | Description |
|---|---|---|---|
Idempotency-Key |
header | no | Optional key (16-64 characters) that makes a retried request safe. |
subject_type |
string | yes | Only document. |
subject_id |
string | yes | Legal document ID (ldoc_…) the user saw. |
state |
string | yes | presented, accepted or declined. |
application_id |
string | null | no | Application (app_…); when omitted and the document is application-specific, the document's application is recorded. |
occurred_at |
string (date-time) | no | When it happened; defaults to now, not in the future, at most 5 minutes old. |
Response
201 Created with the consent record.
{
"id": "crec_01j9xk3m7q8r2s4t6v8w0y2z4b",
"user_id": "usr_01j9xk3m7q8r2s4t6v8w0y2z4c",
"subject_type": "document",
"subject_id": "ldoc_01j9xk3m7q8r2s4t6v8w0y2z4a",
"subject_version": "2026-10",
"content_sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"locale": "en",
"state": "accepted",
"method": "management_api",
"application_id": null,
"occurred_at": "2026-10-05T09:31:12.004211Z"
}
Errors
| HTTP | code | When |
|---|---|---|
| 400 | unknown_field |
The body contains an unknown field. |
| 404 | not_found |
The user or application_id does not exist in this environment. The resource extension says which one is missing: user or application. |
| 415 | unsupported_media_type |
The content type is not application/json. |
| 422 | validation_failed |
A field is invalid: unknown document (/subject_id, unknown_subject), subject_type: purpose (not_supported), a state not allowed for documents, or occurred_at out of range. |
| 401 | unauthenticated |
The credential is missing, invalid or revoked. |
| 403 | insufficient_permissions |
The credential lacks the required permission. |
| 429 | rate_limited |
The rate limit was exceeded; retry after the Retry-After period. |
| 503 | service_unavailable |
A dependency is temporarily unavailable; retry after the Retry-After period. |
Example
curl -X POST https://api.eu.keenauth.com/v1/users/usr_01j9xk3m7q8r2s4t6v8w0y2z4c/consent-records \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"subject_type":"document","subject_id":"ldoc_01j9xk3m7q8r2s4t6v8w0y2z4a","state":"accepted"}'
Personal data
This endpoint carries personal data: consent records. Personal data in the KeenAuth APIs describes what is stored, how long it is kept and how it is deleted. Do not send special categories of personal data (health, biometric data, religion, political opinions, sexual orientation) in any field.