Record consent
POST
/api/v1/external/consents/recordUse this endpoint to record a user’s consent decision at a specific collection point. Each call appends an immutable entry to the consent log — existing records are never modified or deleted.
Authentication
Both headers are required.
| Header | Type | Required | Description |
|---|---|---|---|
X-Org-Id | string | Yes | Your organization slug |
X-API-Key | string | Yes | Your tenant API key |
Body
| Field | Type | Required | Description |
|---|---|---|---|
collectionPointId | string | Yes | UUID or display_id of the collection point |
userId | string | Yes | The ID of the user giving consent. Stored as data_principal_id on the consent log entry. |
action | string | Yes | Top-level consent decision: approved, declined, partial_consent, revoked, no_action |
purposes | array | No | Per-purpose consent decisions. Omit if the collection point has no granular purposes. |
requestId | string | No | External request identifier for idempotency. If omitted, the API generates a UUID. |
metadata | object | No | Arbitrary key-value pairs stored alongside the consent log entry. |
purposes[] fields:
| Field | Type | Description |
|---|---|---|
id | string | UUID of the purpose |
name | string | Display name of the purpose |
consented | string | Per-purpose decision: approved or declined |
is_mandatory | boolean | Whether this purpose is mandatory. Informational only. |
purpose_type | string | Optional purpose classification. May be null. |
Response
201 Created
| Field | Type | Description |
|---|---|---|
id | string | UUID of the consent log entry |
action | string | The recorded consent action |
collection_point_id | string | UUID of the collection point |
purpose_consents | array | Per-purpose consent breakdown as stored |
timestamp | string | ISO 8601 timestamp of when the consent was recorded |
status | string | Processing status. Always pending on creation. |
request_id | string | The request identifier — the value you provided or a server-generated UUID |
Errors
| Status | Description |
|---|---|
400 | userId or collectionPointId is missing, or X-Org-Id could not be resolved |
401 | X-API-Key is invalid or missing |
403 | API key lacks the admin scope |
404 | No collection point found matching collectionPointId |
422 | action is not one of the allowed values, or the request body fails validation |
500 | Internal server error |
Example
curl --request POST \ --url 'https://truapi-dev.truconsent.io/api/v1/external/consents/record' \ --header 'X-Org-Id: acme' \ --header 'X-API-Key: tck_live_xxxxxxxxxxxx' \ --header 'Content-Type: application/json' \ --data '{ "collectionPointId": "cp_signup_form", "userId": "usr_7f3a9b21", "action": "partial_consent", "purposes": [ { "id": "3d6e2f1a-bc74-4e9a-a801-123456789abc", "name": "Marketing emails", "consented": "approved", "is_mandatory": false, "purpose_type": "marketing" }, { "id": "9a1b4c2d-ef56-7890-b234-abcdef012345", "name": "Analytics", "consented": "declined", "is_mandatory": false, "purpose_type": "analytics" } ], "requestId": "req_external_8821", "metadata": { "ip_address": "203.0.113.42", "user_agent": "Mozilla/5.0" } }'{ "id": "c1d2e3f4-aaaa-bbbb-cccc-ddddeeeeeeee", "action": "partial_consent", "collection_point_id": "a0b1c2d3-1111-2222-3333-444455556666", "purpose_consents": [ { "purpose_id": "3d6e2f1a-bc74-4e9a-a801-123456789abc", "purpose_name": "Marketing emails", "status": "approved", "is_mandatory": false, "purpose_type": "marketing", "purpose_version": 1 }, { "purpose_id": "9a1b4c2d-ef56-7890-b234-abcdef012345", "purpose_name": "Analytics", "status": "declined", "is_mandatory": false, "purpose_type": "analytics", "purpose_version": 1 } ], "timestamp": "2026-04-21T10:34:52.123456", "status": "pending", "request_id": "req_external_8821"}