AgentMessage
Legal Acceptances

Record a clickwrap acceptance event

POST
/v1/legal-acceptances

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
AuthorizationBearer <token>

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"
  }
}