Record a clickwrap acceptance event
Records one clickwrap-acceptance event. Every affirmative checkbox click during onboarding (and any future plan-change checkout) writes one row. The row is the durable record the Terms of Service §23 evidentiary clause requires.
The handler captures the request IP and user agent
server-side from the connecting socket and request headers;
clients do not (and cannot) pass them. Org and user identity
are derived from the Clerk session. beta_terms_version is
optional so older clients that have not yet adopted the
beta-terms revision continue to record valid acceptances;
post-bump clients send it.
Append-only. There is no read surface on this route, a
future staff / DPO audit-enumeration handler will land
separately under a platform:* scope.
Requires a user session. API-key principals receive
403 USER_REQUIRED because API keys are not user-scoped and
cannot affirmatively accept terms on any user's behalf.
Authorization
clerkJWT First-party clients (the dashboard) authenticate with the session token issued at sign-in. Requests are scoped to the active organization and the signed-in user's role.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/legal-acceptances" \ -H "Content-Type: application/json" \ -d '{ "terms_version": "v1.1", "privacy_version": "v1.0", "messaging_policy_version": "v1.1", "carrier_compliance_version": "v1.0", "dpa_version": "v1.0", "subprocessors_version": "v1.0", "beta_terms_version": "v1.0", "checkout_page_url": "https://agentmessage.io/onboarding" }'{
"success": true,
"error": {
"code": "string",
"message": "string",
"request_id": "string",
"details": {
"property1": "string",
"property2": "string"
}
},
"meta": {
"total": 0,
"limit": 0,
"offset": 0,
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wNC0yNlQxMjowMDowMFoiLCJpZCI6IjAxOTAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMSJ9",
"last_event_at": "2019-08-24T14:15:22Z"
},
"data": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",
"user_id": "user_2abcDEF1234",
"ip_address": "203.0.113.7",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
"terms_version": "string",
"privacy_version": "string",
"messaging_policy_version": "string",
"carrier_compliance_version": "string",
"dpa_version": "string",
"subprocessors_version": "string",
"beta_terms_version": "string",
"checkout_page_url": "string",
"stripe_customer_id": "string",
"created_at": "2019-08-24T14:15:22Z"
}
}{
"success": true,
"data": null,
"error": {
"code": "string",
"message": "string",
"request_id": "string",
"details": {
"property1": "string",
"property2": "string"
}
},
"meta": {
"total": 0,
"limit": 0,
"offset": 0,
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wNC0yNlQxMjowMDowMFoiLCJpZCI6IjAxOTAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMSJ9",
"last_event_at": "2019-08-24T14:15:22Z"
}
}{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "authentication failed",
"request_id": "01JTBQH2FZ8K1RXC0WJ4Z9P3VM"
}
}{
"success": false,
"error": {
"code": "USER_REQUIRED",
"message": "endpoint requires a user session",
"request_id": "01JTBQH2FZ8K1RXC0WJ4Z9P3VM"
}
}