Click API Overview
The Click API enables you to deploy and manage click-to-accept agreements programmatically. Your backend renders an agreement, shows it to the user in your own page or app, and records the acceptance with the checksum of what it rendered; the REST APIs also manage templates, deployments, and evidence.
Click is server to server. There is no browser SDK or embeddable script, and every render and accept call needs an OAuth Bearer token, so none of them is made from a browser.
Key Features
- Template Management - Create and version rich-text consent templates with DOCX support
- Deployments - Deploy templates to sites with locale and branding configuration
- Server-side render - Fetch the exact agreement a deployment serves, with its checksum, and show it in your own UI
- Consent Acceptance - Idempotent endpoint records user consent, checked against the content that was rendered
- Identity Verification - Optional OTP-based verification before consent
- Evidence Bundles - Tamper-evident proof of consent for compliance
- Analytics - Track acceptance rates, versions, and consent metrics
Architecture
Three APIs, One Product
Click is composed of three services, each purpose-built for its role:
Management API
The internal API for managing templates, deployments, acceptances, and analytics. Used by your backend and the Propper dashboard.
| Area | Endpoints |
|---|---|
| Templates | CRUD, versioning, statistics |
| Deployments | Create, update, manage deployment targets |
| Acceptances | Retrieve and list consent acceptance records |
| Evidence | Retrieve tamper-evident evidence bundles |
| Analytics | Acceptance rates and consent metrics |
Accept API
A high-throughput endpoint for recording consent acceptance, called from your backend with an OAuth Bearer token (click:accept). Writes are idempotent, and the checksum you send is verified against what the deployment serves before anything is recorded.
| Feature | Description |
|---|---|
| Idempotent writes | Duplicate requests return the same result |
| Identity verification | Optional OTP-based verification |
| Pub/Sub integration | Triggers async evidence processing |
Render API
A read-only endpoint that returns the Experience JSON of an active deployment in your organization, including the checksum of its content, for your backend to show to the user. Requires an OAuth Bearer token (click:read). Supports ETag revalidation and locale overrides.
| Feature | Description |
|---|---|
| Deployment rendering | Render by deployment ID |
| Template rendering | Render by template and version |
| Locale override | Dynamic locale selection |
| ETag revalidation | If-None-Match answers 304 when unchanged |
Lists and retries
Paging through a list
Every Management API list returns one page at a time, under a key named for what it holds, with a pagination object beside it:
{
"deployments": [{ "id": "a6f0c5e2-7a39-4c5e-9d3e-1b2f8c4d5e6f", "domain": "www.propper.ai" }],
"pagination": { "total": 57, "page": 1, "limit": 20, "hasMore": true }
}
| List | Key |
|---|---|
GET /v1/click/templates | templates |
GET /v1/click/deployments | deployments |
GET /v1/click/acceptances | acceptances |
GET /v1/click/evidence/retention/status | acceptances, with a summary |
GET /v1/click/templates/scheduled-publishes | scheduledPublishes |
pagestarts at 1 andlimitis 1 to 100, 20 when omitted. A value outside those bounds is a 400CLICK_VALIDATION_FAILED.totalcounts every row that matches your filters, not just this page.- Keep asking for the next
pagewhilehasMoreis true. Rows keep the same order on every page.
To narrow a list to when its rows were created, send createdAfter (inclusive) and createdBefore (exclusive) as ISO 8601 date-times, for example createdAfter=2026-03-01T00:00:00Z.
For acceptances and retention status the time is when the acceptance started.
Retrying a write safely
Send an X-Idempotency-Key header on a write and a retry of the same request is applied once.
The key is optional on every Management API write and required on POST /v1/click/accept.
- Use a fresh key for each distinct request and the same key for every retry of it. A UUID works well; the key must be 8 to 128 letters, digits, dashes or underscores.
On a Management API write:
- A repeat returns the stored response of the first attempt, with its original status code, and changes nothing.
- The body is not compared. The same key with a different body returns the first response, so a changed request needs a new key.
- A retry that arrives while the first attempt is still running is refused with a 409
CLICK_CONFLICT. Wait a moment and send it again. - Responses are kept for 24 hours.
On POST /v1/click/accept:
- A retry with the same key and the same body returns the original receipt and records nothing new, with no time limit.
- The body is compared.
A key reused for a different body is refused with 422
CLICK_IDEMPOTENCY_KEY_REUSEDand nothing is recorded.
OpenAPI Specs
Click publishes one combined OpenAPI JSON file for product-level discovery and separate service specs for generated reference docs and service-specific integrations.
| Spec | Covers | Reference | JSON | YAML |
|---|---|---|---|---|
| Combined Click API | Management, Accept, and Render APIs | Click API Reference | JSON | - |
| Management API | Templates, deployments, acceptances, analytics | Management API Reference | JSON | YAML |
| Accept API | Consent acceptance and identity verification | Accept API Reference | JSON | YAML |
| Render API | Experience rendering for your backend | Render API Reference | JSON | YAML |
Core Concepts
Template
A template defines the consent language. It is one of three types: STATIC, GENERATED or CONSENT. Write its content through the API with PUT /v1/click/templates/{templateId}/draft, or in the dashboard; a template starts as a draft with no content.
Template Version
Each template can have multiple versions. Only published versions can be deployed. Version history provides an audit trail of consent language changes.
Deployment
A deployment serves a published template at a domain, path and environment. You address it by its ID alone; domain and path are recorded for allowlisting and reporting.
Acceptance
An acceptance records a single consent interaction. When a user views and accepts a consent experience, the acceptance captures the event with metadata.
Signer Status
A version's number says how much its change matters to consent: a major needs signers to accept again, a minor or patch does not.
Signer status (POST /v1/click/deployments/{id}/signer-status with { "userRef": "..." }) answers whether a signer has accepted the major a deployment serves, so you re-prompt only the signers whose consent is stale, and tells a stale signer what changed since the version they accepted.
Acceptance Links
An acceptance link sends one signer to a page Propper hosts, where they read the agreement a deployment serves.
Your backend mints it with a click:accept token (POST /v1/click/deployments/{deploymentId}/acceptance-links), sends the signer the returned url, and reads the outcome later (GET /v1/click/acceptance-links/{id}).
If a link leaks, it revokes it with POST /v1/click/acceptance-links/{id}/revoke.
The part of the URL after # is a one-time secret that is returned only when the link is minted.
Links last one hour by default and seven days at most, minting again for the same deployment and signer revokes that signer's earlier link, and only static agreements can be hosted.
Evidence Bundle
An evidence bundle is the tamper-evident proof that consent was given. It includes the template version, user metadata, timestamps, and a content hash.
Integration Flow
API Base URLs
| Service | Base URL |
|---|---|
| Management API | https://api.propper.ai/v1/click |
| Accept API | https://api.propper.ai/v1/click/accept |
| Render API | https://api.propper.ai/v1/click/render |
Authentication
All three APIs use OAuth 2.0 with Bearer tokens. An API key is not accepted:
POST https://auth.propper.ai/oauth2/token
Content-Type: application/json
{
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"scope": "click:read click:write click:accept"
}
OAuth Scopes
| Scope | Description |
|---|---|
click:accept | Record acceptances through the Accept API and mint, read and revoke hosted acceptance links, with no access to read or change other Click data |
click:read | Read templates, deployments, and acceptances |
click:write | Create and modify templates and deployments; also records acceptances |
click:admin | Full management access (create, update, delete); also records acceptances |
A backend that only records acceptances should use a client with click:accept. See Limits and retries.
Errors
All three Click APIs answer an error with the same JSON body:
{
"errorCode": "CLICK_VALIDATION_FAILED",
"message": "Request validation failed",
"requestId": "0b6f3a52-9a44-4f4b-9c1e-6a1f0e0f7c11",
"details": [{ "field": "name", "message": "name must be a string", "code": "isString" }]
}
errorCode is a stable CLICK_* code to branch on, requestId is the x-request-id response header to quote to support, and details appears only on validation failures.
Each API reference lists the full code table.
Next Steps
Quickstart
Deploy an agreement and record an acceptance from your backend.
Management API Reference
Templates, deployments, acceptances, analytics, and evidence endpoints.
Accept API Reference
Consent acceptance and identity verification endpoints.
Render API Reference
Experience JSON rendering endpoint for your backend.