{
  "openapi": "3.0.0",
  "info": {
    "title": "Propper Click API",
    "description": "Complete Click API covering template management, consent acceptance, rendering, and identity verification.",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "https://api.propper.ai",
      "description": "Production server"
    }
  ],
  "tags": [
    {
      "name": "Templates",
      "description": "Create and manage consent/clickwrap templates"
    },
    {
      "name": "Template versions",
      "description": "Immutable versions of a template, numbered by consent impact: write and publish the draft, read, compare and restore"
    },
    {
      "name": "Deployments",
      "description": "Deploy templates to domains and manage activation"
    },
    {
      "name": "Acceptances",
      "description": "View acceptance records and evidence bundles"
    },
    {
      "name": "Acceptance links",
      "description": "Per-signer links to a Propper-hosted acceptance page: mint them, read their status and revoke them"
    },
    {
      "name": "Evidence Verification",
      "description": "Check the integrity and signature of recorded acceptance evidence"
    },
    {
      "name": "Analytics",
      "description": "Dashboard metrics"
    },
    {
      "name": "Organization",
      "description": "Organization settings management"
    },
    {
      "name": "Verification",
      "description": "Not available yet: email and SMS verification is being rebuilt"
    },
    {
      "name": "Acceptance",
      "description": "Record and query consent acceptances"
    },
    {
      "name": "Render",
      "description": "Fetch rendered consent experiences by deployment key"
    },
    {
      "name": "Variant",
      "description": "Assign an A/B test variant to a user"
    }
  ],
  "security": [
    {
      "bearer": []
    }
  ],
  "paths": {
    "/v1/click/templates": {
      "get": {
        "operationId": "findAllTemplates",
        "summary": "List all templates",
        "description": "Returns the templates of your organization, newest first, one page at a time. Narrow the list to a creation window with `createdAfter` and `createdBefore`. `pagination.total` counts every matching template, not just this page.",
        "parameters": [
          {
            "name": "includeVersions",
            "required": false,
            "in": "query",
            "description": "Accepted for compatibility. It does not change the response.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "description": "Only templates created at or after this time, inclusive. ISO 8601 date-time, such as `2026-03-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "required": false,
            "description": "Only templates created before this time, exclusive. ISO 8601 date-time, such as `2026-04-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of templates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      },
      "post": {
        "operationId": "createTemplate",
        "summary": "Create a new template",
        "description": "Creates a template in your organization. The slug must be unique within your organization. A template starts as a draft.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTemplateDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "409": {
            "description": "Template slug already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{id}": {
      "get": {
        "operationId": "findOneTemplate",
        "summary": "Get a specific template",
        "description": "Returns one template by ID.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "includeVersions",
            "in": "query",
            "required": false,
            "description": "Accepted for compatibility. It does not change the response.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      },
      "patch": {
        "operationId": "updateTemplate",
        "summary": "Update a template",
        "description": "Updates the fields you send and leaves the others unchanged. Changing the slug fails when another template already uses it.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTemplateDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Template slug already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      },
      "delete": {
        "operationId": "removeTemplate",
        "summary": "Delete a template",
        "description": "Permanently deletes a template. A template with active deployments cannot be deleted: deactivate or delete the deployments first. Requires the `click:admin` scope.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Template deleted successfully",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "description": "Cannot delete template with active deployments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:admin"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{id}/stats": {
      "get": {
        "operationId": "getTemplateStats",
        "summary": "Get template statistics",
        "description": "Returns deployment and version counts for one template.",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template statistics retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateStatsDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{templateId}/draft": {
      "get": {
        "operationId": "getTemplateDraft",
        "summary": "Get the draft content of a template",
        "description": "The title, body, texts and acknowledgments of each locale, as the next publish will read them.",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The draft content",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateDraftDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Template versions"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      },
      "put": {
        "operationId": "writeTemplateDraft",
        "summary": "Write the draft content of a template",
        "description": "Replaces the title, body, texts and acknowledgments of each locale named, so a template created through the API can be published without the dashboard. Locales not named, and everything else about the draft, are left as they are. Nothing published changes: deployments serve version records. A body is saved in its normalized form (`<br>` becomes `<br />`, `&` becomes `&amp;`); one that carries markup that would have to be removed, such as a script or an event handler, is refused with 422 `CLICK_CONTENT_UNSAFE` naming it, and nothing is written. Publishing applies the same rule.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WriteDraftDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The draft after the write",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateDraftDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "`CLICK_TEMPLATE_ARCHIVED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "422": {
            "description": "`CLICK_CONTENT_UNSAFE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Drafts are temporarily unavailable; nothing was written",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Template versions"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{templateId}/versions": {
      "get": {
        "operationId": "listTemplateVersions",
        "summary": "List the published versions of a template, newest first",
        "description": "Every published version of the template, one page at a time. Filter by the time a version was published with `createdAfter` and `createdBefore`. `pagination.total` counts every matching version.",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "description": "Only versions published at or after this time, inclusive. ISO 8601 date-time, such as `2026-03-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "required": false,
            "description": "Only versions published before this time, exclusive. ISO 8601 date-time, such as `2026-04-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of versions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Template versions"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      },
      "post": {
        "operationId": "publishTemplateVersion",
        "summary": "Publish the draft as the next version",
        "description": "Creates the next immutable version from the template draft. You decide the level (`MAJOR`, `MINOR` or `PATCH`) and give a reason; both are recorded next to the level the server suggested (see the preview). The first publish is 1.0.0 and must be a `MAJOR`. A `MAJOR` that follows an earlier version needs a re-acceptance `gate`. Answers `409 CLICK_NOTHING_CHANGED` when the draft equals the latest version. Deployments serving the same major follow a published `MINOR` or `PATCH` automatically; a new major is adopted by moving a deployment.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublishVersionDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The published version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "`CLICK_NOTHING_CHANGED`, `CLICK_VERSION_CONFLICT` or `CLICK_TEMPLATE_ARCHIVED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "422": {
            "description": "`CLICK_FIRST_PUBLISH_MUST_BE_MAJOR`, `CLICK_CONSPICUOUSNESS_ACK_REQUIRED`, `CLICK_REACCEPT_GATE_REQUIRED`, `CLICK_GATE_NOT_APPLICABLE`, `CLICK_LINKED_DOCUMENT_UNREACHABLE`, `CLICK_CONTENT_UNSAFE` or `CLICK_TEMPLATE_NOT_PUBLISHABLE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Versions are temporarily unavailable; nothing was published",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Template versions"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{templateId}/versions/preview": {
      "post": {
        "operationId": "previewTemplateVersion",
        "summary": "Preview publishing the draft",
        "description": "What publishing the draft now would record: the number each level would take, the suggested level with its reasons, any presentation changes that need an acknowledgment to publish as a `PATCH`, and the diff against the latest version. Writes nothing.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewVersionDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The preview",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionPreviewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "description": "The draft cannot be published",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Versions are temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Template versions"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{templateId}/versions/{versionId}": {
      "get": {
        "operationId": "getTemplateVersion",
        "summary": "Get a published version",
        "description": "The whole version: its content per locale, consent mechanics, linked documents and the change record behind its number.",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "versionId",
            "required": true,
            "in": "path",
            "description": "Version ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Template versions"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{templateId}/versions/{fromVersionId}/diff/{toVersionId}": {
      "get": {
        "operationId": "compareTemplateVersions",
        "summary": "Compare two published versions",
        "description": "What changed between two versions of the same template.",
        "parameters": [
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "fromVersionId",
            "required": true,
            "in": "path",
            "description": "The “before” version ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "toVersionId",
            "required": true,
            "in": "path",
            "description": "The “after” version ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The comparison",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionComparisonDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Template versions"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{templateId}/versions/{versionId}/restore": {
      "post": {
        "operationId": "restoreTemplateVersion",
        "summary": "Restore a published version into the draft",
        "description": "Writes the version’s content, appearance, settings and consent mechanics back into the template’s draft, replacing what the draft held. Nothing published changes. Publish the draft afterwards, naming this version in `restoredFromId`, to make it the next version.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "templateId",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "versionId",
            "required": true,
            "in": "path",
            "description": "Version ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The draft now matches the version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionRestoreDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "`CLICK_TEMPLATE_ARCHIVED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Versions are temporarily unavailable; the draft was not changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Template versions"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/types": {
      "get": {
        "operationId": "getTemplateTypes",
        "summary": "Get available template types",
        "description": "Returns all available template types with their configurations",
        "parameters": [],
        "responses": {
          "200": {
            "description": "List of template types with configurations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TemplateTypeEntryDto"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{id}/configuration": {
      "get": {
        "operationId": "getTemplateConfiguration",
        "summary": "Get template configuration",
        "description": "Returns template configuration including type config and policy flags",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template configuration details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateConfigurationDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{id}/policy-flags": {
      "post": {
        "operationId": "applyPolicyFlags",
        "summary": "Apply policy flags to template",
        "description": "Merges the flags you send into the template policy flags. Flags a template type requires are always applied, and the result is validated against the type rules. Send only the flags you want to set.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplatePolicyFlagsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Policy flags applied successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "description": "The flags break a rule of the template type, or the ID is not a UUID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/{id}/verification-requirements": {
      "get": {
        "operationId": "getVerificationRequirements",
        "summary": "Get template verification requirements",
        "description": "Returns what verification methods are required for this template",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verification requirements",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerificationRequirementsDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/verification-requirements": {
      "get": {
        "operationId": "getVerificationRequirementsCatalogue",
        "summary": "Get the catalogue of verification requirements",
        "description": "Returns the list of verification requirement keys that can be applied to a template, with the value each has by default. Use `/v1/click/templates/{id}/verification-requirements` to read the requirements configured on a specific template.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Verification requirement catalogue",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerificationRequirementsCatalogueDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/scheduled-publishes": {
      "get": {
        "operationId": "listScheduledPublishes",
        "summary": "List scheduled publish jobs",
        "description": "Returns the scheduled publish jobs of your organization, latest scheduled time first, one page at a time. Filter by status or template, or by the time the job was created with `createdAfter` and `createdBefore`. `pagination.total` counts every matching job.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only jobs in this state",
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "IN_FLIGHT",
                "SUCCEEDED",
                "FAILED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "templateId",
            "in": "query",
            "required": false,
            "description": "Only jobs for this template",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "description": "Only jobs created at or after this time, inclusive. ISO 8601 date-time, such as `2026-03-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "required": false,
            "description": "Only jobs created before this time, exclusive. ISO 8601 date-time, such as `2026-04-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of scheduled publish jobs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledPublishListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/scheduled-publishes/{id}/cancel": {
      "post": {
        "operationId": "cancelScheduledPublish",
        "summary": "Cancel a pending scheduled publish",
        "description": "Cancels a scheduled publish that has not run yet. The call succeeds even when the job already ran or was cancelled, and the response says whether anything was cancelled.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Scheduled publish ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Cancellation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelScheduledPublishResultDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/validate-content": {
      "post": {
        "operationId": "validateContent",
        "summary": "Validate template content",
        "description": "Validates template content against type-specific rules. `type` is REQUIRED and identifies which validation ruleset to apply.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "content"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "STATIC",
                      "GENERATED",
                      "CONSENT"
                    ],
                    "description": "Template type to validate against"
                  },
                  "content": {
                    "type": "string",
                    "description": "The template content to validate"
                  },
                  "format": {
                    "type": "string",
                    "description": "Content format (defaults to `html`)",
                    "default": "html"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentValidationResultDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/bulk/archive": {
      "post": {
        "operationId": "bulkArchiveTemplates",
        "summary": "Bulk archive templates",
        "description": "Marks every listed template as `ARCHIVED`. Partial-success: foreign-org IDs and templates with active deployments are returned in `skipped[]` rather than failing the whole batch. Foreign-org IDs are reported as `not_found`: the response never confirms cross-tenant existence. Requires the `click:admin` scope.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "templateIds"
                ],
                "properties": {
                  "templateIds": {
                    "type": "array",
                    "description": "Template UUIDs to archive (1–100).",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Archive summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "archived",
                    "skipped"
                  ],
                  "properties": {
                    "archived": {
                      "type": "integer",
                      "description": "Number of templates whose status flipped to ARCHIVED."
                    },
                    "skipped": {
                      "type": "array",
                      "description": "Templates that were not archived, with reason per entry.",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "reason"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reason": {
                            "type": "string",
                            "enum": [
                              "not_found",
                              "has_active_deployments"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Authenticated principal does not satisfy the `click:admin` scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:admin"
            ]
          }
        ]
      }
    },
    "/v1/click/templates/bulk/duplicate": {
      "post": {
        "operationId": "bulkDuplicateTemplates",
        "summary": "Bulk duplicate templates",
        "description": "Shallow-clones each listed template as a new `DRAFT`. Optional `namePattern` uses the `{name}` placeholder: defaults to `\"{name} (copy)\"`. Each duplicate starts a fresh version chain and inherits no audit identity from the source. Foreign-org IDs are reported as `not_found`. Requires the `click:admin` scope.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "templateIds"
                ],
                "properties": {
                  "templateIds": {
                    "type": "array",
                    "description": "Source template UUIDs to duplicate (1–50).",
                    "minItems": 1,
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  },
                  "namePattern": {
                    "type": "string",
                    "description": "Optional naming template. Use `{name}` as the placeholder for the source template name (e.g. `\"EU - {name}\"`). Defaults to `\"{name} (copy)\"`.",
                    "maxLength": 255
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Duplicate summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "duplicates",
                    "skipped"
                  ],
                  "properties": {
                    "duplicates": {
                      "type": "array",
                      "description": "Successfully created duplicates.",
                      "items": {
                        "type": "object",
                        "required": [
                          "sourceId",
                          "newId",
                          "name"
                        ],
                        "properties": {
                          "sourceId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "newId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "skipped": {
                      "type": "array",
                      "description": "Source IDs that were not duplicated.",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "reason"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reason": {
                            "type": "string",
                            "enum": [
                              "not_found",
                              "slug_conflict"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Authenticated principal does not satisfy the `click:admin` scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "bearer": [
              "click:admin"
            ]
          }
        ]
      }
    },
    "/v1/click/deployments": {
      "get": {
        "operationId": "findAllDeployments",
        "summary": "List all deployments",
        "description": "Returns the deployments of your organization, highest priority first, one page at a time. Filter by environment or active state, or by the time the deployment was created with `createdAfter` and `createdBefore`. `pagination.total` counts every matching deployment, not just this page.",
        "parameters": [
          {
            "name": "siteId",
            "required": false,
            "in": "query",
            "description": "Accepted for compatibility. It does not filter the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environment",
            "required": false,
            "in": "query",
            "description": "Filter by environment",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "active",
            "required": false,
            "in": "query",
            "description": "Filter by active status",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "includeSite",
            "required": false,
            "in": "query",
            "description": "Accepted for compatibility. It does not change the response.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "includeTemplateVersion",
            "required": false,
            "in": "query",
            "description": "Accepted for compatibility. It does not change the response.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "description": "Only deployments created at or after this time, inclusive. ISO 8601 date-time, such as `2026-03-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "required": false,
            "description": "Only deployments created before this time, exclusive. ISO 8601 date-time, such as `2026-04-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of deployments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      },
      "post": {
        "operationId": "createDeployment",
        "summary": "Create a new deployment",
        "description": "Deploys a published version of a template to a domain, path and environment. Send the version’s ID in `versionId`; the deployment serves it, as revision 1, until it is moved, rolled back, or follows a newer minor or patch of the same major. The combination of domain, environment, path and variant must be unique in your organization (`409 CLICK_DEPLOYMENT_SLOT_TAKEN`).",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDeploymentDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Deployment created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Deployment already exists for this combination (`CLICK_DEPLOYMENT_SLOT_TAKEN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Deployments are temporarily unavailable; nothing was created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/deployments/{id}": {
      "get": {
        "operationId": "findOneDeployment",
        "summary": "Get a specific deployment",
        "description": "Returns one deployment by ID.",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeSite",
            "required": false,
            "in": "query",
            "description": "Accepted for compatibility. It does not change the response.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "includeTemplateVersion",
            "required": false,
            "in": "query",
            "description": "Accepted for compatibility. It does not change the response.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deployment retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      },
      "patch": {
        "operationId": "updateDeployment",
        "summary": "Update a deployment",
        "description": "Updates the fields you send and leaves the others unchanged. What the deployment serves does not change here: move it to another version, or roll it back, through the revision operations. The environment cannot change once the deployment has recorded acceptances: create a new deployment instead.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDeploymentDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deployment updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Deployment already exists for this combination, or `CLICK_DEPLOYMENT_ENVIRONMENT_LOCKED`: the deployment has acceptances, so its environment cannot change (create a new deployment instead)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      },
      "delete": {
        "operationId": "removeDeployment",
        "summary": "Delete a deployment",
        "description": "Permanently deletes a deployment that has no revision history. A deployment created through this API always has one, so it answers `409 CLICK_DEPLOYMENT_HAS_REVISIONS`: deactivate it instead. Requires the `click:admin` scope.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deployment deleted successfully",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "`CLICK_DEPLOYMENT_HAS_REVISIONS`: the deployment has a revision history",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:admin"
            ]
          }
        ]
      }
    },
    "/v1/click/deployments/{id}/revisions": {
      "get": {
        "operationId": "listDeploymentRevisions",
        "summary": "List the revisions of a deployment, newest first",
        "description": "Every change to what a deployment serves is an appended revision: it is created, follows a newer minor or patch of its major, is moved, has its settings changed or is rolled back. The history is never edited.",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "description": "Only revisions made at or after this time, inclusive. ISO 8601 date-time, such as `2026-03-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "required": false,
            "description": "Only revisions made before this time, exclusive. ISO 8601 date-time, such as `2026-04-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of revisions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentRevisionListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/deployments/{id}/revisions/{number}": {
      "get": {
        "operationId": "getDeploymentRevision",
        "summary": "Get one revision of a deployment",
        "description": "One entry of the deployment’s history: the version it served, its settings, why it was appended and who made the change.",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "number",
            "required": true,
            "in": "path",
            "description": "Revision number",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The revision",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentRevisionDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/deployments/{id}/signer-status": {
      "post": {
        "operationId": "getSignerStatus",
        "summary": "Has a signer accepted the major this deployment serves?",
        "description": "Answers `current` when the signer has ever accepted the major this deployment serves, and `stale` otherwise, so you re-prompt only the signers whose consent no longer covers what they are shown. It is a read sent as a POST: the signer reference travels in the body, so it never appears in a URL or a request log.\n\n- **Which acceptances count.** Acceptances recorded through any deployment of the same template in the same environment. An acceptance in another environment never counts, and neither does a decline.\n- **Currency.** A minor or patch never makes a signer stale, and neither does a later acceptance of another major: a signer who accepted 3.x and later 2.x is current while 3.x is served. A signer who never accepted the served major is stale, including after a rollback to a major they never accepted.\n- **Grace window.** A version this deployment served until less than 15 minutes ago still counts for a signer who accepted it at most 15 minutes before it stopped being served, or after: an acceptance that raced the change, in the same window in which an acceptance of it is still recorded. `graceEndsAt` says when that ends. A signer who accepted it earlier is stale as soon as it stops being served, whatever the re-acceptance gate.\n- **A signer who never accepted** the template in this environment is `stale` with `reason: never_accepted` and `accepted: null`: prompt them to accept.\n- **When stale**, `change` carries the reason, the summary and the re-acceptance gate and deadline of the change that opened the served major, and `change.sinceAccepted` says what changed between the version the signer accepted and the served one, for the screen that asks them to accept again.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignerStatusRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The signer’s status against what the deployment serves",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerStatusDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "description": "`CLICK_NOT_FOUND`: the deployment does not exist in your organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "409": {
            "description": "`CLICK_CONFLICT`: the deployment serves no version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/deployments/{deploymentId}/acceptance-links": {
      "post": {
        "operationId": "mintAcceptanceLink",
        "summary": "Mint a hosted acceptance link for a signer",
        "description": "Creates a per-signer link to a page Propper hosts, where the signer reads the agreement this deployment serves. Send the signer to `url`.\n\n- **The secret is in `url` only.** The part after `#` is a one-time secret: it is returned in this response only, never stored (Propper keeps its hash) and never logged. Treat the URL like a password until the signer opens it. This operation does not honour `X-Idempotency-Key`, so the secret is never kept for a replay: a retry mints a new link.\n- **One live link per signer.** Minting for the same deployment and `signerRef` revokes that signer’s earlier links that are still live.\n- **Lifetime.** One hour by default (`expiresInSeconds`), seven days at most.\n- **Static agreements only.** A deployment whose template is of another type answers 422 `CLICK_HOSTED_TYPE_UNSUPPORTED`.\n- **Return URL.** Checked when minting and stored with the link: `https` only, no credentials, at most 2048 bytes, on the deployment’s domain. The redirect back is not proof of an outcome: read the link’s status to confirm it.\n- **`signerRef`** is your own opaque identifier for the signer, such as your user id. Do not put an email address or a name in it.",
        "parameters": [
          {
            "name": "deploymentId",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MintAcceptanceLinkDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The link, with the signer’s URL. Sent with `Cache-Control: no-store`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MintedAcceptanceLinkDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "description": "`CLICK_VALIDATION_FAILED` for an invalid field, or `CLICK_RETURN_URL_INVALID` for a return URL that is not allowed; `details` names the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "description": "`CLICK_DEPLOYMENT_NOT_FOUND`: no deployment with this ID exists in your organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "409": {
            "description": "`CLICK_ACCEPTANCE_LINK_MINT_CONFLICT`: another mint for this signer is in progress; retry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "422": {
            "description": "`CLICK_HOSTED_TYPE_UNSUPPORTED` for a template that is not static, `CLICK_CONTENT_UNSAFE` for content the hosted page would not show, or a deployment that serves nothing now",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Acceptance links are temporarily unavailable; nothing was minted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Acceptance links"
        ],
        "security": [
          {
            "bearer": [
              "click:accept"
            ]
          }
        ]
      }
    },
    "/v1/click/acceptance-links/{id}": {
      "get": {
        "operationId": "getAcceptanceLink",
        "summary": "Read the status of a hosted acceptance link",
        "description": "The link’s fields and status: `ACTIVE` until the signer opens it, `OPENED` once they have, then `ACCEPTED`, `DECLINED` or `REVOKED`. `expired` is true when the link passed `expiresAt` without an outcome. The URL and its secret are never returned again.",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Acceptance link ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The link",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptanceLinkDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "description": "`CLICK_ACCEPTANCE_LINK_NOT_FOUND`: no acceptance link with this ID exists in your organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Acceptance links are temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Acceptance links"
        ],
        "security": [
          {
            "bearer": [
              "click:accept"
            ]
          }
        ]
      }
    },
    "/v1/click/acceptance-links/{id}/revoke": {
      "post": {
        "operationId": "revokeAcceptanceLink",
        "summary": "Revoke a hosted acceptance link",
        "description": "Ends a link that is still live, now: the signer who opens it afterwards is told it is not usable. Use it when a link leaks, such as a forwarded email or a screenshot of its QR code. Answers the link, with `status` `REVOKED` and `revokedAt`.\n\n- **Idempotent.** Revoking a link that is already revoked answers it again, unchanged, and `X-Idempotency-Key` is honoured.\n- **Once answered, it stays answered.** A link whose signer already accepted or declined answers 409 `CLICK_ACCEPTANCE_LINK_COMPLETED` and keeps its outcome.\n- **Your organization only.** A link of another organization answers 404, the same as an ID that does not exist.",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Acceptance link ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The revoked link",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptanceLinkDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "description": "`CLICK_ACCEPTANCE_LINK_NOT_FOUND`: no acceptance link with this ID exists in your organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "409": {
            "description": "`CLICK_ACCEPTANCE_LINK_COMPLETED`: the signer already accepted or declined, so the link cannot be revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Acceptance links are temporarily unavailable; nothing was revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Acceptance links"
        ],
        "security": [
          {
            "bearer": [
              "click:accept"
            ]
          }
        ]
      }
    },
    "/v1/click/deployments/{id}/move": {
      "post": {
        "operationId": "moveDeployment",
        "summary": "Serve another published version",
        "description": "Appends a `MOVED` revision and takes effect immediately. A new major is never followed automatically: moving is how a deployment adopts one. The version must belong to the deployment’s template.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MoveDeploymentDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The appended revision",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentRevisionDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "`CLICK_NOTHING_TO_CHANGE`, `CLICK_VERSION_TEMPLATE_MISMATCH`, `CLICK_TEMPLATE_ARCHIVED` or `CLICK_REVISION_CONFLICT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Revisions are temporarily unavailable; nothing changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/deployments/{id}/rollback": {
      "post": {
        "operationId": "rollbackDeployment",
        "summary": "Roll a deployment back to an earlier revision",
        "description": "Appends a `ROLLBACK` revision that serves again the version and settings of the revision you name. Earlier revisions are never changed.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollbackDeploymentDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The appended revision",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentRevisionDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "`CLICK_NOTHING_TO_CHANGE` or `CLICK_REVISION_CONFLICT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Revisions are temporarily unavailable; nothing changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Deployments"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/analytics/dashboard": {
      "get": {
        "operationId": "getDashboardMetrics",
        "summary": "Get dashboard analytics and metrics",
        "description": "Returns the same dashboard numbers as the Propper web app, for your organization over a time range (7 days by default). Every figure is counted from recorded sessions, never estimated: the outcome of each session, views and the conversion rate, the daily trend, the templates with the most acceptances, the device mix and the regions.",
        "parameters": [
          {
            "name": "timeRange",
            "required": false,
            "in": "query",
            "description": "Range to report on, ending now. Defaults to `7d`.",
            "schema": {
              "type": "string",
              "enum": [
                "24h",
                "7d",
                "30d",
                "90d"
              ],
              "default": "7d"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dashboard metrics retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DashboardMetricsDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "description": "`timeRange` is not one of `24h`, `7d`, `30d` or `90d`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "The dashboard is temporarily unavailable (`CLICK_DASHBOARD_UPSTREAM_UNAVAILABLE`). Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Analytics"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/acceptances": {
      "get": {
        "operationId": "getAcceptances",
        "summary": "List acceptances",
        "description": "Returns the acceptances recorded for your organization, newest first, one page at a time. Filter by template or deployment, or by the time the acceptance started with `createdAfter` and `createdBefore`. `pagination.total` counts every matching acceptance, not just this page.",
        "parameters": [
          {
            "name": "templateId",
            "in": "query",
            "required": false,
            "description": "Only acceptances of this template",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "deploymentId",
            "in": "query",
            "required": false,
            "description": "Only acceptances recorded through this deployment",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "description": "Only acceptances that started at or after this time, inclusive. ISO 8601 date-time, such as `2026-03-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "required": false,
            "description": "Only acceptances that started before this time, exclusive. ISO 8601 date-time, such as `2026-04-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "includeEvidence",
            "in": "query",
            "required": false,
            "description": "Include an evidence summary on each acceptance",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "includeReceipt",
            "in": "query",
            "required": false,
            "description": "Include a receipt summary on each acceptance",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of acceptances",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptanceListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ],
        "tags": [
          "Acceptances"
        ]
      }
    },
    "/v1/click/acceptances/{id}": {
      "get": {
        "operationId": "getAcceptance",
        "summary": "Get an acceptance",
        "description": "Returns one acceptance by ID.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Acceptance ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeEvidence",
            "in": "query",
            "required": false,
            "description": "Include an evidence summary",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "includeReceipt",
            "in": "query",
            "required": false,
            "description": "Include a receipt summary",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Acceptance retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AcceptanceResponseDto"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ],
        "tags": [
          "Acceptances"
        ]
      }
    },
    "/v1/click/acceptances/{id}/evidence": {
      "get": {
        "operationId": "getEvidenceBundle",
        "summary": "Get acceptance evidence bundle",
        "description": "Returns where the stored evidence of an acceptance can be fetched: the HTML snapshot, its style metadata, the screenshot, the bundle archive and the receipt.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Acceptance ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Evidence bundle retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/EvidenceBundleDto"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ],
        "tags": [
          "Acceptances"
        ]
      }
    },
    "/v1/click/receipts/{receiptId}": {
      "get": {
        "operationId": "getReceipt",
        "summary": "Get acceptance receipt",
        "description": "Returns the receipt of an acceptance, with the state of its evidence. The receipt ID is the acceptance ID.",
        "parameters": [
          {
            "name": "receiptId",
            "in": "path",
            "required": true,
            "description": "Receipt ID, which is the acceptance ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The acceptance receipt and the state of its evidence.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ReceiptResponseDto"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ],
        "tags": [
          "Acceptances"
        ]
      }
    },
    "/v1/click/evidence/verify/receipt/{receiptId}": {
      "get": {
        "operationId": "verifyByReceipt",
        "summary": "Verify evidence by receipt ID",
        "description": "Re-checks the evidence behind a receipt: the content hash, the signature, the chain link, the stored screenshot and captured HTML, retention and the signing key. The receipt ID is an acceptance ID or an evidence ID, optionally prefixed with `receipt_`. An ID that does not exist in your organization, including one that belongs to another organization, is a 404, never a verification result: `valid: false` means only that the evidence failed verification.",
        "parameters": [
          {
            "name": "receiptId",
            "in": "path",
            "required": true,
            "description": "Receipt ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verification result. `valid: false` means only that the evidence failed verification: read `errors` and `checks`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvidenceVerificationResultDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Evidence Verification"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/evidence/verify/json": {
      "post": {
        "operationId": "verifyJson",
        "summary": "Verify uploaded JSON evidence payload",
        "description": "Checks the signature of a receipt you hold, without looking anything up: send the receipt JSON as the body. It needs `signature` and `signatureKeyId`. The content hash, chain, screenshot, captured HTML and retention checks are not run for an uploaded receipt. Nothing is looked up, so there is no 404: `valid: false` means the signature or the signing key did not check out, or the body is not a JSON object.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The receipt JSON, including `signature` and `signatureKeyId`",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "The signed receipt",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verification result. `valid: false` means only that the evidence failed verification: read `errors` and `checks`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvidenceVerificationResultDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Evidence Verification"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/evidence/verify/{evidenceId}": {
      "get": {
        "operationId": "verifyById",
        "summary": "Verify evidence by ID",
        "description": "Re-checks the evidence of an acceptance: the content hash, the signature, the chain link, the stored screenshot and captured HTML, retention and the signing key. The ID is an evidence ID or an acceptance ID, optionally prefixed with `evidence_` as printed on the certificate. An ID that does not exist in your organization, including one that belongs to another organization, is a 404, never a verification result: `valid: false` means only that the evidence failed verification.",
        "parameters": [
          {
            "name": "evidenceId",
            "in": "path",
            "required": true,
            "description": "Evidence ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verification result. `valid: false` means only that the evidence failed verification: read `errors` and `checks`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvidenceVerificationResultDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Evidence Verification"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    },
    "/v1/click/evidence/retention/status": {
      "get": {
        "operationId": "getRetentionStatus",
        "summary": "Get evidence retention status",
        "description": "Returns, for each acceptance on the requested page, when its retention period ends and whether it is active, close to expiry (30 days or fewer) or expired. Acceptances are listed oldest first, one page at a time. Narrow them to a window on the time the acceptance started with `createdAfter` and `createdBefore`. `pagination.total` counts every matching acceptance, not just this page.",
        "parameters": [
          {
            "name": "orgId",
            "in": "query",
            "required": false,
            "description": "Your organization ID. Must match the organization you are authenticated as.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "daysUntilExpiry",
            "in": "query",
            "required": false,
            "description": "Accepted for compatibility. The warning window is fixed at 30 days.",
            "schema": {
              "type": "integer",
              "default": 30
            }
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "description": "Only acceptances that started at or after this time, inclusive. ISO 8601 date-time, such as `2026-03-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "required": false,
            "description": "Only acceptances that started before this time, exclusive. ISO 8601 date-time, such as `2026-04-01T00:00:00Z`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of retention records with a summary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RetentionStatusResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "description": "The `orgId` does not match the organization you are authenticated as",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ],
        "tags": [
          "Acceptances"
        ]
      }
    },
    "/v1/click/acceptances/{id}/screenshot": {
      "get": {
        "operationId": "getScreenshot",
        "summary": "Get acceptance screenshot",
        "description": "Returns the screenshot captured with an acceptance, as a PNG image.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Acceptance ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The screenshot",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "description": "No screenshot for this acceptance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "500": {
            "description": "The screenshot could not be retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ],
        "tags": [
          "Acceptances"
        ]
      }
    },
    "/v1/click/organization/settings": {
      "get": {
        "operationId": "getSettings",
        "summary": "Get organization settings",
        "description": "Retrieve organization settings including retention policies, PII mode, and default template settings",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Organization settings retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationSettingsDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Organization"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      },
      "patch": {
        "operationId": "updateSettings",
        "summary": "Update organization settings",
        "description": "Update organization settings such as retention policies, PII mode, and default template settings",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOrganizationSettingsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Organization settings updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationSettingsDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Organization"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/verification/email/send": {
      "post": {
        "operationId": "sendEmailVerification",
        "summary": "Send email verification code (not available yet)",
        "description": "Not available yet. Verification is being rebuilt so that it is scoped to your organization and works across servers. Until then every request to this endpoint is refused with `404 CLICK_NOT_FOUND`: no code is sent, stored or checked. Do not integrate against it.",
        "parameters": [],
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Verification"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/verification/email/verify": {
      "post": {
        "operationId": "verifyEmailCode",
        "summary": "Verify email code (not available yet)",
        "description": "Not available yet. Verification is being rebuilt so that it is scoped to your organization and works across servers. Until then every request to this endpoint is refused with `404 CLICK_NOT_FOUND`: no code is sent, stored or checked. Do not integrate against it.",
        "parameters": [],
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Verification"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/verification/sms/send": {
      "post": {
        "operationId": "sendSMSVerification",
        "summary": "Send SMS verification code (not available yet)",
        "description": "Not available yet. Verification is being rebuilt so that it is scoped to your organization and works across servers. Until then every request to this endpoint is refused with `404 CLICK_NOT_FOUND`: no code is sent, stored or checked. Do not integrate against it.",
        "parameters": [],
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Verification"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/verification/sms/verify": {
      "post": {
        "operationId": "verifySMSCode",
        "summary": "Verify SMS code (not available yet)",
        "description": "Not available yet. Verification is being rebuilt so that it is scoped to your organization and works across servers. Until then every request to this endpoint is refused with `404 CLICK_NOT_FOUND`: no code is sent, stored or checked. Do not integrate against it.",
        "parameters": [],
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "tags": [
          "Verification"
        ],
        "security": [
          {
            "bearer": [
              "click:write"
            ]
          }
        ]
      }
    },
    "/v1/click/accept": {
      "post": {
        "operationId": "acceptConsent",
        "summary": "Accept consent",
        "description": "Record consent acceptance with idempotent writes and Pub/Sub integration",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKeyRequired"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptConsentDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Consent acceptance recorded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptConsentResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "description": "Invalid request data, including a body with no `checksum` field (an empty or wrong checksum is a 422 instead), a missing or malformed `X-Idempotency-Key`, or an identity method the template does not allow (`CLICK_BAD_REQUEST`, `CLICK_VALIDATION_FAILED`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "401": {
            "description": "Missing or invalid authentication credentials. An acceptance needs an OAuth Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "No deployment with this ID in your organization (`CLICK_DEPLOYMENT_NOT_FOUND`), or it is not active (`CLICK_DEPLOYMENT_INACTIVE`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "422": {
            "description": "The checksum is empty or is not the SHA-256 of the content the deployment serves, code `CLICK_CHECKSUM_MISMATCH`: the details name the version served, never the expected checksum. Or the X-Idempotency-Key was already used for a different request body, code `CLICK_IDEMPOTENCY_KEY_REUSED`. Nothing is recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "429": {
            "description": "The OAuth client exceeded its request rate. Nothing is recorded. Retry after the number of seconds in the Retry-After header.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the rate-limit window resets"
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests allowed in the current window"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests left in the current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix time, in seconds, at which the window resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "The deployment has no content to serve (`CLICK_CONTENT_MISSING`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Content storage (`CLICK_CONTENT_UNAVAILABLE`) or the acceptance backend (`CLICK_ACCEPT_UPSTREAM_UNAVAILABLE`) is temporarily unavailable. The request never reached the recorder, so nothing is recorded; retry with the same `X-Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "504": {
            "description": "The call to the acceptance backend timed out or dropped after the request may have reached it (`CLICK_ACCEPT_OUTCOME_UNKNOWN`). The acceptance may or may not be recorded. Retry with the same `X-Idempotency-Key`: the answer is the receipt if it was recorded, or a fresh attempt if not. Do not tell your user the acceptance failed until the retry answers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Acceptance"
        ],
        "security": [
          {
            "bearer": [
              "click:accept"
            ]
          }
        ]
      }
    },
    "/v1/click/render/deployment/{id}": {
      "get": {
        "operationId": "renderByDeploymentId",
        "summary": "Render Experience JSON by Deployment ID",
        "description": "Returns the agreement an active deployment in your organization serves, with the SHA-256 checksum of its content. Each successful render, including a 304, is counted as a view.",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Deployment ID",
            "schema": {
              "example": "c54f4b8c-d36d-4670-855d-f454c8d3b7a8",
              "type": "string"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "description": "Locale to serve. Falls back to en-US, then en, then the first locale the deployment has.",
            "schema": {
              "example": "fr-FR",
              "type": "string"
            }
          },
          {
            "name": "if-none-match",
            "required": false,
            "in": "header",
            "description": "ETag of a previous render; answers 304 when the content is unchanged",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Experience JSON successfully rendered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExperienceDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "304": {
            "description": "The content matches the `If-None-Match` ETag",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "description": "No deployment with this ID in your organization (`CLICK_DEPLOYMENT_NOT_FOUND`), or it is not active (`CLICK_DEPLOYMENT_INACTIVE`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "500": {
            "description": "The deployment has no content to serve (`CLICK_CONTENT_MISSING`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "503": {
            "description": "Content storage (`CLICK_CONTENT_UNAVAILABLE`) or the render backend (`CLICK_RENDER_UPSTREAM_UNAVAILABLE`) is temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Render"
        ]
      }
    },
    "/v1/click/render/variant/{deploymentId}": {
      "get": {
        "operationId": "assignVariant",
        "summary": "Assign A/B variant for a user",
        "description": "Splits users evenly across the sibling deployments of a route: deployments in your organization that share a domain, environment and path and differ only in variant. The same user and deployment always land on the same variant. When the deployment has no siblings it is returned unchanged.",
        "parameters": [
          {
            "name": "deploymentId",
            "required": true,
            "in": "path",
            "description": "Requested deployment ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "userRef",
            "required": true,
            "in": "query",
            "description": "Stable opaque user identifier, such as a user ID or session ID. The same value always gets the same variant.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The deployment to show this user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VariantAssignmentDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "description": "No deployment with this ID in your organization, or `userRef` was not supplied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "traceparent": {
                "$ref": "#/components/headers/traceparent"
              }
            }
          }
        },
        "tags": [
          "Variant"
        ],
        "security": [
          {
            "bearer": [
              "click:read"
            ]
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http",
        "description": "OAuth 2.0 Bearer token"
      }
    },
    "headers": {
      "X-Request-Id": {
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Correlation id for this request, returned on every response (success and error). Quote it when contacting support to pinpoint the exact request, and use it to correlate your own logs. It is the same 128-bit id as the trace-id segment of the `traceparent` header."
      },
      "traceparent": {
        "schema": {
          "type": "string"
        },
        "description": "W3C Trace Context identifier for this request, returned on every response. Send your own `traceparent` on a request to have it adopted, so a multi-call workflow shares one trace. Format: `00-<32-hex trace-id>-<16-hex span-id>-<2-hex flags>`."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "X-Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Makes a retry safe. Send the same key on every attempt of one request and the request is applied once: a repeat returns the stored response of the first attempt, with its status code, and changes nothing. Use 8 to 128 letters, digits, dashes or underscores; a UUID is a good choice. Stored responses are kept for 24 hours. The request body is not compared: the same key with a different body returns the first response, so use a new key for every distinct request. A second request with a key whose first attempt is still running is refused with a 409 `CLICK_CONFLICT`.",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 128,
          "pattern": "^[a-zA-Z0-9_-]{8,128}$"
        }
      },
      "Page": {
        "name": "page",
        "in": "query",
        "required": false,
        "description": "Page number, starting at 1. A page past the last one is empty.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Rows per page, from 1 to 100.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      },
      "IdempotencyKeyRequired": {
        "name": "X-Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Required. Makes a retry safe. Send the same key on every attempt of one acceptance and it is recorded once: a retry with the same key and the same body returns the original receipt, with no time limit, and records nothing new. Use 8 to 128 letters, digits, dashes or underscores; a UUID is a good choice. The body is compared: a key reused for a different body is refused with 422 `CLICK_IDEMPOTENCY_KEY_REUSED` and nothing is recorded, so use a new key for every distinct acceptance.",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 128,
          "pattern": "^[a-zA-Z0-9_-]{8,128}$"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request is malformed or a field is invalid (`CLICK_BAD_REQUEST`, or `CLICK_VALIDATION_FAILED` with `details`).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "traceparent": {
            "$ref": "#/components/headers/traceparent"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "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"
                }
              ]
            }
          }
        }
      },
      "Unauthorized": {
        "description": "The credentials are missing, invalid or expired (`CLICK_UNAUTHORIZED`).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "traceparent": {
            "$ref": "#/components/headers/traceparent"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "errorCode": "CLICK_UNAUTHORIZED",
              "message": "Invalid or expired token"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The token lacks the scope this operation needs, or the resource belongs to another organization (`CLICK_FORBIDDEN`), or your account does not include Click (`ENTITLEMENT_REQUIRED`, with `requiredEntitlement`).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "traceparent": {
            "$ref": "#/components/headers/traceparent"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "errorCode": "CLICK_FORBIDDEN",
              "message": "Insufficient scope"
            }
          }
        }
      },
      "NotFound": {
        "description": "The resource does not exist in your organization (`CLICK_NOT_FOUND`, or a more specific code).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "traceparent": {
            "$ref": "#/components/headers/traceparent"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "errorCode": "CLICK_NOT_FOUND",
              "message": "Resource not found"
            }
          }
        }
      },
      "Conflict": {
        "description": "The request conflicts with the current state of a resource (`CLICK_CONFLICT`, or a more specific code).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "traceparent": {
            "$ref": "#/components/headers/traceparent"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "errorCode": "CLICK_CONFLICT",
              "message": "A resource with these values already exists"
            }
          }
        }
      },
      "UnprocessableEntity": {
        "description": "The request is well formed but cannot be applied (`CLICK_UNPROCESSABLE`, or a more specific code).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "traceparent": {
            "$ref": "#/components/headers/traceparent"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "errorCode": "CLICK_UNPROCESSABLE",
              "message": "The request cannot be applied"
            }
          }
        }
      },
      "InternalError": {
        "description": "An unexpected error on our side (`CLICK_INTERNAL_ERROR`). The body is generic; quote the `requestId` when contacting support.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "traceparent": {
            "$ref": "#/components/headers/traceparent"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "errorCode": "CLICK_INTERNAL_ERROR",
              "message": "Internal server error"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "A dependency is temporarily unavailable (`CLICK_SERVICE_UNAVAILABLE`, or a more specific code). Retry with backoff.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "traceparent": {
            "$ref": "#/components/headers/traceparent"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "errorCode": "CLICK_SERVICE_UNAVAILABLE",
              "message": "The service is temporarily unavailable"
            }
          }
        }
      }
    },
    "schemas": {
      "ErrorFieldDetail": {
        "type": "object",
        "description": "One field-level cause of a rejected request.",
        "properties": {
          "field": {
            "type": "string",
            "description": "Path of the request property, such as `name` or `items.0.name`.",
            "example": "name"
          },
          "message": {
            "type": "string",
            "description": "What is wrong with that property.",
            "example": "name must be a string"
          },
          "code": {
            "type": "string",
            "description": "The validation rule that failed.",
            "example": "isString"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "description": "The body of every error response.",
        "properties": {
          "errorCode": {
            "type": "string",
            "description": "Stable, machine-readable error code. One of: `CLICK_BAD_REQUEST`, `CLICK_VALIDATION_FAILED`, `CLICK_UNAUTHORIZED`, `CLICK_FORBIDDEN`, `CLICK_NOT_FOUND`, `CLICK_CONFLICT`, `CLICK_UNPROCESSABLE`, `CLICK_RATE_LIMITED`, `CLICK_INTERNAL_ERROR`, `CLICK_SERVICE_UNAVAILABLE`, `CLICK_DEPLOYMENT_NOT_FOUND`, `CLICK_DEPLOYMENT_INACTIVE`, `CLICK_CONTENT_MISSING`, `CLICK_CONTENT_UNAVAILABLE`, `CLICK_RENDER_UPSTREAM_UNAVAILABLE`, `CLICK_ACCEPT_UPSTREAM_UNAVAILABLE`, `CLICK_ACCEPT_OUTCOME_UNKNOWN`, `CLICK_DASHBOARD_UPSTREAM_UNAVAILABLE`, `CLICK_CHECKSUM_MISMATCH`, `CLICK_VERSION_NOT_SERVED`, `CLICK_DEPLOYMENT_HAS_REVISIONS`, `CLICK_NOTHING_CHANGED`, `CLICK_VERSION_CONFLICT`, `CLICK_TEMPLATE_ARCHIVED`, `CLICK_FIRST_PUBLISH_MUST_BE_MAJOR`, `CLICK_CONSPICUOUSNESS_ACK_REQUIRED`, `CLICK_REACCEPT_GATE_REQUIRED`, `CLICK_GATE_NOT_APPLICABLE`, `CLICK_LINKED_DOCUMENT_UNREACHABLE`, `CLICK_TEMPLATE_NOT_PUBLISHABLE`, `CLICK_CONTENT_UNSAFE`, `CLICK_DEPLOYMENT_SLOT_TAKEN`, `CLICK_REVISION_CONFLICT`, `CLICK_NOTHING_TO_CHANGE`, `CLICK_VERSION_TEMPLATE_MISMATCH`, `CLICK_IDEMPOTENCY_KEY_REUSED`, `CLICK_DEPLOYMENT_ENVIRONMENT_LOCKED`, `CLICK_RETURN_URL_INVALID`, `CLICK_HOSTED_TYPE_UNSUPPORTED`, `CLICK_ACCEPTANCE_LINK_NOT_FOUND`, `CLICK_ACCEPTANCE_LINK_COMPLETED`, `CLICK_ACCEPTANCE_LINK_MINT_CONFLICT`, `ENTITLEMENT_REQUIRED`. New codes may be added.",
            "example": "CLICK_VALIDATION_FAILED"
          },
          "message": {
            "type": "string",
            "description": "Short explanation for a person. Do not parse it.",
            "example": "Request validation failed"
          },
          "requestId": {
            "type": "string",
            "description": "Correlation id of the request, the same value as the `x-request-id` response header. Quote it when contacting support.",
            "example": "0b6f3a52-9a44-4f4b-9c1e-6a1f0e0f7c11"
          },
          "details": {
            "type": "array",
            "description": "Field-level causes. Present on validation failures only, never on a server error.",
            "items": {
              "$ref": "#/components/schemas/ErrorFieldDetail"
            }
          },
          "requiredEntitlement": {
            "type": "string",
            "description": "The entitlement your account needs. Present with 403 `ENTITLEMENT_REQUIRED` only.",
            "example": "click.access"
          }
        },
        "required": [
          "errorCode",
          "message"
        ]
      },
      "CreateTemplateDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Template name",
            "example": "Terms of Service",
            "minLength": 1,
            "maxLength": 255
          },
          "slug": {
            "type": "string",
            "description": "Template slug (URL-friendly identifier)",
            "example": "terms-of-service",
            "pattern": "^[a-z0-9-]+$"
          },
          "type": {
            "type": "string",
            "description": "Template type",
            "enum": [
              "STATIC",
              "GENERATED",
              "CONSENT"
            ],
            "default": "STATIC"
          },
          "retentionDays": {
            "type": "number",
            "description": "Data retention period in days",
            "minimum": 30,
            "maximum": 3650,
            "default": 2555
          },
          "consentVersion": {
            "type": "string",
            "description": "Consent version",
            "default": "1.0"
          },
          "contentVersion": {
            "type": "string",
            "description": "Semantic content version override. If omitted, the patch component auto-bumps on every content change.",
            "pattern": "^\\d+\\.\\d+\\.\\d+$",
            "example": "2.0.0"
          },
          "description": {
            "type": "string",
            "description": "Template description"
          },
          "content": {
            "type": "object",
            "description": "Initial content for the template"
          },
          "metadata": {
            "type": "object",
            "description": "Template metadata"
          },
          "settings": {
            "type": "object",
            "description": "Additional template settings"
          }
        },
        "required": [
          "name",
          "slug"
        ]
      },
      "TemplateResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Template ID",
            "format": "uuid"
          },
          "orgId": {
            "type": "string",
            "description": "Organization ID",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Template name"
          },
          "slug": {
            "type": "string",
            "description": "Template slug"
          },
          "type": {
            "type": "string",
            "description": "Template type. Same value as `clickType`. Not present on the response of the policy-flags route.",
            "enum": [
              "STATIC",
              "GENERATED",
              "CONSENT"
            ]
          },
          "clickType": {
            "type": "string",
            "description": "Template type",
            "enum": [
              "STATIC",
              "GENERATED",
              "CONSENT"
            ]
          },
          "status": {
            "type": "string",
            "description": "Template status",
            "enum": [
              "DRAFT",
              "PUBLISHED",
              "ARCHIVED"
            ]
          },
          "description": {
            "type": "string",
            "description": "Template description",
            "nullable": true
          },
          "contentVersion": {
            "type": "string",
            "description": "Semantic content version"
          },
          "policyVersion": {
            "type": "string",
            "description": "Semantic policy version"
          },
          "retentionDays": {
            "type": "integer",
            "description": "Data retention period in days"
          },
          "settings": {
            "type": "object",
            "description": "Template settings",
            "additionalProperties": true
          },
          "tags": {
            "type": "array",
            "description": "Template tags",
            "items": {
              "type": "string"
            }
          },
          "metadata": {
            "type": "object",
            "description": "Template metadata",
            "additionalProperties": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          },
          "createdBy": {
            "type": "string",
            "description": "ID of the user who created the template",
            "nullable": true
          },
          "updatedBy": {
            "type": "string",
            "description": "ID of the user who last updated the template",
            "nullable": true
          }
        },
        "required": [
          "id",
          "orgId",
          "name",
          "slug",
          "clickType",
          "status",
          "contentVersion",
          "policyVersion",
          "retentionDays",
          "settings",
          "tags",
          "metadata",
          "createdAt",
          "updatedAt"
        ]
      },
      "UpdateTemplateDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Template name",
            "example": "Terms of Service",
            "minLength": 1,
            "maxLength": 255
          },
          "slug": {
            "type": "string",
            "description": "Template slug (URL-friendly identifier)",
            "example": "terms-of-service",
            "pattern": "^[a-z0-9-]+$"
          },
          "type": {
            "type": "string",
            "description": "Template type",
            "enum": [
              "STATIC",
              "GENERATED",
              "CONSENT"
            ],
            "default": "STATIC"
          },
          "retentionDays": {
            "type": "number",
            "description": "Data retention period in days",
            "minimum": 30,
            "maximum": 3650,
            "default": 2555
          },
          "consentVersion": {
            "type": "string",
            "description": "Consent version",
            "default": "1.0"
          },
          "contentVersion": {
            "type": "string",
            "description": "Semantic content version override. If omitted, the patch component auto-bumps on every content change.",
            "pattern": "^\\d+\\.\\d+\\.\\d+$",
            "example": "2.0.0"
          },
          "description": {
            "type": "string",
            "description": "Template description"
          },
          "content": {
            "type": "object",
            "description": "Initial content for the template"
          },
          "metadata": {
            "type": "object",
            "description": "Template metadata"
          },
          "settings": {
            "type": "object",
            "description": "Additional template settings"
          }
        }
      },
      "PublishVersionDto": {
        "type": "object",
        "properties": {
          "level": {
            "type": "string",
            "description": "The consent impact of the change, which numbers the version. The first publish of a template must be `MAJOR`. The preview suggests a level; the level you send is the one recorded.",
            "enum": [
              "MAJOR",
              "MINOR",
              "PATCH"
            ]
          },
          "reason": {
            "type": "string",
            "description": "Why this level, recorded with the version.",
            "minLength": 3,
            "maxLength": 2000
          },
          "label": {
            "type": "string",
            "description": "Replaces the generated label.",
            "maxLength": 280
          },
          "summary": {
            "type": "string",
            "description": "Your summary of the change. When you send none, one is generated: written by AI when `aiSummary` is `ENABLED` for your organization, otherwise built from the changes.",
            "minLength": 1,
            "maxLength": 1000
          },
          "summaryModel": {
            "type": "string",
            "description": "The model that wrote `summary`, when it was generated.",
            "maxLength": 100
          },
          "effectiveAt": {
            "type": "string",
            "description": "When the version takes effect, ISO 8601. Defaults to the latest version’s date.",
            "format": "date-time",
            "example": "2026-12-01T00:00:00.000Z"
          },
          "gate": {
            "type": "string",
            "description": "When signers must accept again. Required for a `MAJOR` that follows an earlier version; not allowed otherwise.",
            "enum": [
              "IMMEDIATE",
              "BY_DEADLINE",
              "NEXT_VISIT"
            ]
          },
          "gateDeadline": {
            "type": "string",
            "description": "The deadline of a `BY_DEADLINE` gate, ISO 8601, in the future.",
            "format": "date-time"
          },
          "affectedSet": {
            "type": "string",
            "description": "Who must accept again.",
            "enum": [
              "EVERYONE",
              "LOCALE",
              "NEWLY_COVERED",
              "DOCUMENT"
            ]
          },
          "affectedDetail": {
            "type": "object",
            "description": "Detail of the affected set, such as the locale.",
            "additionalProperties": true
          },
          "notify": {
            "type": "boolean",
            "description": "Whether signers are to be notified of the change."
          },
          "conspicuousnessAck": {
            "type": "string",
            "description": "Your reason for publishing flagged presentation changes as a `PATCH`. Required when the preview lists findings and the level is `PATCH`.",
            "minLength": 3,
            "maxLength": 2000
          },
          "restoredFromId": {
            "type": "string",
            "description": "The version this draft was restored from, recorded as the lineage of the new version.",
            "format": "uuid"
          }
        },
        "required": [
          "level",
          "reason"
        ]
      },
      "PreviewVersionDto": {
        "type": "object",
        "properties": {
          "effectiveAt": {
            "type": "string",
            "description": "When the version would take effect, ISO 8601.",
            "format": "date-time"
          },
          "includeSummary": {
            "type": "boolean",
            "description": "Also have AI write the change summary and suggest a level. Applies only while `aiSummary` is `ENABLED`.",
            "default": false
          }
        }
      },
      "VersionSummaryDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "templateId": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "string",
            "description": "`MAJOR.MINOR.PATCH`",
            "example": "1.1.0"
          },
          "major": {
            "type": "integer"
          },
          "minor": {
            "type": "integer"
          },
          "patch": {
            "type": "integer"
          },
          "level": {
            "type": "string",
            "enum": [
              "MAJOR",
              "MINOR",
              "PATCH",
              null
            ],
            "description": "The level the publisher decided.",
            "nullable": true
          },
          "label": {
            "type": "string",
            "description": "A short label, generated from the change or set by the publisher."
          },
          "clickType": {
            "type": "string",
            "description": "The template type at publish."
          },
          "effectiveAt": {
            "type": "string",
            "format": "date-time"
          },
          "contentHash": {
            "type": "string",
            "description": "SHA-256 of the version’s canonical content."
          },
          "publishedBy": {
            "type": "string",
            "description": "The user or client that published it."
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "restoredFromId": {
            "type": "string",
            "format": "uuid",
            "description": "The version it was restored from.",
            "nullable": true
          },
          "locales": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The locales the version carries."
          }
        },
        "required": [
          "id",
          "templateId",
          "version",
          "major",
          "minor",
          "patch",
          "label",
          "clickType",
          "effectiveAt",
          "contentHash",
          "publishedBy",
          "publishedAt",
          "locales"
        ]
      },
      "VersionDetailDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "templateId": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "string",
            "description": "`MAJOR.MINOR.PATCH`",
            "example": "1.1.0"
          },
          "major": {
            "type": "integer"
          },
          "minor": {
            "type": "integer"
          },
          "patch": {
            "type": "integer"
          },
          "level": {
            "type": "string",
            "enum": [
              "MAJOR",
              "MINOR",
              "PATCH",
              null
            ],
            "description": "The level the publisher decided.",
            "nullable": true
          },
          "label": {
            "type": "string",
            "description": "A short label, generated from the change or set by the publisher."
          },
          "clickType": {
            "type": "string",
            "description": "The template type at publish."
          },
          "effectiveAt": {
            "type": "string",
            "format": "date-time"
          },
          "contentHash": {
            "type": "string",
            "description": "SHA-256 of the version’s canonical content."
          },
          "publishedBy": {
            "type": "string",
            "description": "The user or client that published it."
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "restoredFromId": {
            "type": "string",
            "format": "uuid",
            "description": "The version it was restored from.",
            "nullable": true
          },
          "consentMechanics": {
            "type": "object",
            "additionalProperties": true
          },
          "appearance": {
            "type": "object",
            "additionalProperties": true
          },
          "settings": {
            "type": "object",
            "additionalProperties": true
          },
          "scope": {
            "type": "object",
            "additionalProperties": true
          },
          "locales": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "The content per locale: title, body source and format, the served body and its checksum, and the text strings."
          },
          "documents": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Linked documents with the SHA-256 recorded at publish."
          },
          "change": {
            "type": "object",
            "additionalProperties": true,
            "description": "The change record: the diff, the suggested and decided level, the reason, the re-acceptance gate, the summary and the findings.",
            "nullable": true
          }
        },
        "required": [
          "id",
          "templateId",
          "version",
          "major",
          "minor",
          "patch",
          "label",
          "clickType",
          "effectiveAt",
          "contentHash",
          "publishedBy",
          "publishedAt",
          "locales",
          "consentMechanics",
          "appearance",
          "settings",
          "scope",
          "documents"
        ]
      },
      "VersionListResponseDto": {
        "type": "object",
        "properties": {
          "versions": {
            "type": "array",
            "description": "The versions on this page, newest first",
            "items": {
              "$ref": "#/components/schemas/VersionSummaryDto"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "versions",
          "pagination"
        ]
      },
      "VersionPreviewDto": {
        "type": "object",
        "properties": {
          "firstPublish": {
            "type": "boolean"
          },
          "latestVersion": {
            "type": "string",
            "nullable": true
          },
          "nothingChanged": {
            "type": "boolean",
            "description": "True when the draft equals the latest version."
          },
          "nextVersions": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "The number each level would take."
          },
          "suggestedLevel": {
            "type": "string",
            "enum": [
              "MAJOR",
              "MINOR",
              "PATCH"
            ]
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "conspicuousnessFindings": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Presentation changes that need an acknowledgment to publish as a `PATCH`."
          },
          "diff": {
            "type": "object",
            "additionalProperties": true
          },
          "contentHash": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "description": "The AI change summary, when `includeSummary` was set and `aiSummary` is `ENABLED`.",
            "nullable": true
          },
          "summaryModel": {
            "type": "string",
            "nullable": true
          },
          "aiSummary": {
            "type": "string",
            "enum": [
              "ENABLED",
              "DISABLED",
              "UNAVAILABLE"
            ],
            "description": "Whether AI writes the change summary and suggests a level for your organization: `ENABLED`; `DISABLED` until an organization admin turns AI summaries on in Settings, Product Settings; or `UNAVAILABLE` when they are not available for your organization."
          },
          "aiSuggestion": {
            "type": "object",
            "description": "The level AI suggests, with a one-sentence reason in terms of signers’ rights, when `includeSummary` was set and `aiSummary` is `ENABLED`. A suggestion only: you decide the level.",
            "properties": {
              "level": {
                "type": "string",
                "enum": [
                  "MAJOR",
                  "MINOR",
                  "PATCH"
                ]
              },
              "reason": {
                "type": "string",
                "example": "Major: adds binding individual arbitration and a class-action waiver, which changes signers’ rights."
              }
            },
            "required": [
              "level",
              "reason"
            ],
            "nullable": true
          }
        },
        "required": [
          "firstPublish",
          "nothingChanged",
          "nextVersions",
          "suggestedLevel",
          "diff",
          "contentHash",
          "aiSummary"
        ]
      },
      "VersionComparisonDto": {
        "type": "object",
        "properties": {
          "from": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "version": {
                "type": "string",
                "example": "1.1.0"
              }
            },
            "required": [
              "id",
              "version"
            ]
          },
          "to": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "version": {
                "type": "string",
                "example": "1.1.0"
              }
            },
            "required": [
              "id",
              "version"
            ]
          },
          "diff": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "from",
          "to",
          "diff"
        ]
      },
      "DraftTextsDto": {
        "type": "object",
        "description": "The text strings of one locale. A text left out is cleared.",
        "properties": {
          "titleText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Heading shown above the body."
          },
          "descriptionText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Text under the heading."
          },
          "acceptButtonText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Label of the accept button."
          },
          "declineButtonText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Label of the decline button."
          },
          "cancelButtonText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Label of the cancel button."
          },
          "agreementMessageText": {
            "type": "string",
            "maxLength": 2000,
            "description": "The sentence next to the buttons, such as “By continuing you agree to the terms”."
          },
          "checkboxText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Label of the consent checkbox."
          },
          "privacyLinkText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Label of the privacy policy link."
          },
          "termsLinkText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Label of the terms link."
          },
          "successMessage": {
            "type": "string",
            "maxLength": 2000,
            "description": "Shown after an acceptance."
          },
          "errorMessage": {
            "type": "string",
            "maxLength": 2000,
            "description": "Shown when an acceptance fails."
          },
          "requiredFieldsMessage": {
            "type": "string",
            "maxLength": 2000,
            "description": "Shown when a required checkbox is left unchecked."
          },
          "footerText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Footer line."
          },
          "timestampFormat": {
            "type": "string",
            "maxLength": 2000,
            "description": "Format of the timestamp line."
          },
          "loadingText": {
            "type": "string",
            "maxLength": 2000,
            "description": "Shown while the click loads."
          }
        },
        "additionalProperties": false
      },
      "DraftAcknowledgmentDto": {
        "type": "object",
        "properties": {
          "labelText": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "description": "The checkbox label."
          },
          "isRequired": {
            "type": "boolean",
            "default": true,
            "description": "Whether the signer must tick it."
          }
        },
        "required": [
          "labelText"
        ],
        "additionalProperties": false
      },
      "DraftLocaleDto": {
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "example": "en-US",
            "description": "A language tag, such as `en-US` or `fr`."
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          },
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100000,
            "example": "<p>You agree to the Terms of Service.</p>",
            "description": "The body signers are shown, as HTML. Text and structure only: text and structure only (`p`, `br`, `hr`, `strong`, `b`, `em`, `i`, `u`, `s`, `blockquote`, `ul`, `ol`, `li`, `h1` to `h6`, `a`, `table`, `thead`, `tbody`, `tr`, `th`, `td`), no attributes except a link’s `href`, which must be `https` or `mailto`. Formatting is normalized when the draft is saved (`<br>` becomes `<br />`, `&` becomes `&amp;`) and the draft reads back in that form. Anything that would have to be removed, such as a script, an event handler or a disallowed tag, is refused with 422 `CLICK_CONTENT_UNSAFE`, and the message names it."
          },
          "bodyFormat": {
            "type": "string",
            "enum": [
              "html"
            ],
            "default": "html",
            "description": "Only `html` exists today."
          },
          "texts": {
            "$ref": "#/components/schemas/DraftTextsDto"
          },
          "acknowledgments": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/DraftAcknowledgmentDto"
            }
          }
        },
        "required": [
          "locale",
          "title",
          "body"
        ],
        "additionalProperties": false
      },
      "WriteDraftDto": {
        "type": "object",
        "properties": {
          "locales": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/DraftLocaleDto"
            },
            "description": "The locales to write, each once. A locale replaces that locale’s title, body, texts and acknowledgments; locales not named are left as they are."
          }
        },
        "required": [
          "locales"
        ],
        "additionalProperties": false
      },
      "DraftLocaleReadDto": {
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "example": "en-US"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "bodyFormat": {
            "type": "string",
            "enum": [
              "html"
            ]
          },
          "texts": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "acknowledgments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DraftAcknowledgmentDto"
            }
          }
        },
        "required": [
          "locale",
          "title",
          "body",
          "bodyFormat",
          "texts",
          "acknowledgments"
        ]
      },
      "TemplateDraftDto": {
        "type": "object",
        "properties": {
          "templateId": {
            "type": "string",
            "format": "uuid"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the template was last changed."
          },
          "locales": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DraftLocaleReadDto"
            }
          }
        },
        "required": [
          "templateId",
          "updatedAt",
          "locales"
        ]
      },
      "VersionRestoreDto": {
        "type": "object",
        "properties": {
          "templateId": {
            "type": "string",
            "format": "uuid"
          },
          "restoredFrom": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "version": {
                "type": "string",
                "example": "1.1.0"
              }
            },
            "required": [
              "id",
              "version"
            ]
          }
        },
        "required": [
          "templateId",
          "restoredFrom"
        ]
      },
      "MoveDeploymentDto": {
        "type": "object",
        "properties": {
          "versionId": {
            "type": "string",
            "description": "The published version to serve from now on. It must belong to the deployment’s template.",
            "format": "uuid"
          },
          "reason": {
            "type": "string",
            "description": "Why the deployment moves, recorded on the revision.",
            "minLength": 3,
            "maxLength": 2000
          }
        },
        "required": [
          "versionId",
          "reason"
        ]
      },
      "RollbackDeploymentDto": {
        "type": "object",
        "properties": {
          "toRevision": {
            "type": "integer",
            "description": "The number of the revision to return to.",
            "minimum": 1
          },
          "reason": {
            "type": "string",
            "description": "Why the deployment rolls back, recorded on the revision.",
            "minLength": 3,
            "maxLength": 2000
          }
        },
        "required": [
          "toRevision",
          "reason"
        ]
      },
      "DeploymentRevisionDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "integer",
            "description": "1 for the revision a deployment is created with, then counting up."
          },
          "kind": {
            "type": "string",
            "description": "Why it was appended: the deployment was created, followed a newer minor or patch of its major, was moved to another version, had its settings changed, or was rolled back.",
            "enum": [
              "CREATED",
              "FOLLOWED",
              "MOVED",
              "SETTINGS",
              "ROLLBACK"
            ]
          },
          "version": {
            "type": "object",
            "description": "The version this revision serves.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "number": {
                "type": "string",
                "example": "1.1.0"
              },
              "label": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "number",
              "label"
            ]
          },
          "settings": {
            "type": "object",
            "additionalProperties": true
          },
          "settingsHash": {
            "type": "string",
            "description": "SHA-256 over the version and the deployment settings."
          },
          "rolledBackToId": {
            "type": "string",
            "format": "uuid",
            "description": "The revision a rollback returned to.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "actorId": {
            "type": "string",
            "description": "The user or client that made the change."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "number",
          "kind",
          "version",
          "settings",
          "settingsHash",
          "actorId",
          "createdAt"
        ]
      },
      "SignerStatusRequestDto": {
        "type": "object",
        "description": "Whose status to read.",
        "properties": {
          "userRef": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "Your own identifier for the signer, exactly as you sent it when recording the acceptance (`userId`, or `metadata.userRef`).",
            "example": "customer-4821"
          }
        },
        "required": [
          "userRef"
        ],
        "additionalProperties": false
      },
      "MintAcceptanceLinkDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "signerRef": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "Your own opaque identifier for the signer, such as your user id. Not an email address or a name.",
            "example": "customer-4821"
          },
          "returnUrl": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "Where the signer goes back to after answering: an `https` URL on the deployment’s domain, with no credentials, at most 2048 bytes.",
            "example": "https://www.propper.ai/onboarding/done"
          },
          "expiresInSeconds": {
            "type": "integer",
            "minimum": 60,
            "maximum": 604800,
            "default": 3600,
            "description": "How long the link stays usable, in seconds: 60 to 604800 (7 days)."
          }
        },
        "required": [
          "signerRef",
          "returnUrl"
        ]
      },
      "AcceptanceLinkDto": {
        "type": "object",
        "description": "A hosted acceptance link: link fields only, never its secret.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "deploymentId": {
            "type": "string",
            "format": "uuid"
          },
          "signerRef": {
            "type": "string",
            "example": "customer-4821"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "OPENED",
              "ACCEPTED",
              "DECLINED",
              "REVOKED"
            ],
            "description": "`ACTIVE` until the signer opens the page, `OPENED` once they have, then one outcome: `ACCEPTED`, `DECLINED` or `REVOKED` (by a newer mint for the same deployment and signer)."
          },
          "expired": {
            "type": "boolean",
            "description": "True when the link passed `expiresAt` without an outcome."
          },
          "returnUrl": {
            "type": "string",
            "example": "https://www.propper.ai/onboarding/done"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "openedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "revokedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "deploymentId",
          "signerRef",
          "status",
          "expired",
          "returnUrl",
          "expiresAt",
          "createdAt",
          "openedAt",
          "completedAt",
          "revokedAt"
        ],
        "example": {
          "id": "7c0e2a4b-9d1f-4e3a-8b6c-5d4e3f2a1b0c",
          "deploymentId": "3f1c2b7a-5d4e-4a8b-9c0d-1e2f3a4b5c6d",
          "signerRef": "customer-4821",
          "status": "OPENED",
          "expired": false,
          "returnUrl": "https://www.propper.ai/onboarding/done",
          "expiresAt": "2026-10-08T21:00:00.000Z",
          "createdAt": "2026-10-08T20:00:00.000Z",
          "openedAt": "2026-10-08T20:02:13.000Z",
          "completedAt": null,
          "revokedAt": null
        }
      },
      "MintedAcceptanceLinkDto": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AcceptanceLinkDto"
          },
          {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "description": "The page to send the signer to. The part after `#` is a one-time secret, returned only in this response.",
                "example": "https://app.propper.ai/click-session/7c0e2a4b-9d1f-4e3a-8b6c-5d4e3f2a1b0c#q3Jx0cF9..."
              }
            },
            "required": [
              "url"
            ]
          }
        ]
      },
      "SignerStatusDto": {
        "type": "object",
        "description": "Whether a signer has accepted the major a deployment serves.",
        "properties": {
          "deploymentId": {
            "type": "string",
            "format": "uuid"
          },
          "userRef": {
            "type": "string",
            "example": "customer-4821"
          },
          "status": {
            "type": "string",
            "enum": [
              "current",
              "stale"
            ],
            "description": "`current` when the signer has ever accepted the major the deployment serves; `stale` otherwise, including after a rollback to a major they never accepted."
          },
          "reason": {
            "type": "string",
            "enum": [
              "never_accepted",
              "accepted_other_major",
              null
            ],
            "description": "Why the signer is stale: `never_accepted` when they have no acceptance of the template in this environment, `accepted_other_major` when they accepted only other majors. Null when current.",
            "nullable": true
          },
          "accepted": {
            "type": "object",
            "description": "When current, the signer’s latest acceptance of the major that counts; when stale, their latest acceptance of the template through any deployment in this deployment’s environment. Null when they never accepted.",
            "properties": {
              "versionId": {
                "type": "string",
                "format": "uuid"
              },
              "version": {
                "type": "string",
                "example": "2.1.0"
              },
              "major": {
                "type": "integer",
                "example": 2
              },
              "receiptId": {
                "type": "string",
                "format": "uuid",
                "description": "The acceptance, readable at `GET /v1/click/receipts/{receiptId}`."
              },
              "deploymentId": {
                "type": "string",
                "format": "uuid",
                "description": "The deployment it was recorded through: this one, or another deployment of the same template in the same environment."
              },
              "acceptedAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": [
              "versionId",
              "version",
              "major",
              "receiptId",
              "deploymentId",
              "acceptedAt"
            ],
            "nullable": true
          },
          "served": {
            "type": "object",
            "description": "What the deployment serves now.",
            "properties": {
              "versionId": {
                "type": "string",
                "format": "uuid"
              },
              "version": {
                "type": "string",
                "example": "2.3.0"
              },
              "major": {
                "type": "integer",
                "example": 2
              },
              "revision": {
                "type": "integer",
                "description": "The deployment revision that serves it.",
                "example": 4
              }
            },
            "required": [
              "versionId",
              "version",
              "major",
              "revision"
            ]
          },
          "graceEndsAt": {
            "type": "string",
            "format": "date-time",
            "description": "Set when the signer is current only because they accepted, at most 15 minutes before it stopped being served or after, a major this deployment served until less than 15 minutes ago. From this time on they are stale.",
            "nullable": true
          },
          "change": {
            "type": "object",
            "description": "When stale, the change that opened the served major and what changed since the version the signer accepted. Null when current.",
            "properties": {
              "versionId": {
                "type": "string",
                "format": "uuid",
                "description": "The version that opened the served major."
              },
              "version": {
                "type": "string",
                "example": "3.0.0"
              },
              "reason": {
                "type": "string",
                "description": "Why the publisher made the change.",
                "nullable": true
              },
              "summary": {
                "type": "string",
                "description": "A summary of what changed, when one was recorded.",
                "nullable": true
              },
              "gate": {
                "type": "string",
                "enum": [
                  "IMMEDIATE",
                  "BY_DEADLINE",
                  "NEXT_VISIT",
                  null
                ],
                "description": "When the signer must accept again, as the publisher decided. Null for a first version, which has no gate.",
                "nullable": true
              },
              "gateDeadline": {
                "type": "string",
                "format": "date-time",
                "description": "The deadline of a `BY_DEADLINE` gate.",
                "nullable": true
              },
              "sinceAccepted": {
                "type": "string",
                "description": "What changed between the version the signer accepted and the one this deployment serves, in plain sentences built from the two versions, for example \"Consent mechanics changed. Wording changed in en-US: 24 words added, 3 words removed.\" When the signer accepted the version just before the served one and your organization has turned on AI summaries, it is the summary published with the served version instead. Null when the signer never accepted, or when the change cannot be described.",
                "example": "Consent mechanics changed. Wording changed in en-US: 24 words added, 3 words removed.",
                "nullable": true
              }
            },
            "required": [
              "versionId",
              "version",
              "reason",
              "summary",
              "gate",
              "gateDeadline",
              "sinceAccepted"
            ],
            "nullable": true
          }
        },
        "required": [
          "deploymentId",
          "userRef",
          "status",
          "reason",
          "accepted",
          "served",
          "graceEndsAt",
          "change"
        ],
        "example": {
          "deploymentId": "3f1c2b7a-5d4e-4a8b-9c0d-1e2f3a4b5c6d",
          "userRef": "customer-4821",
          "status": "stale",
          "reason": "accepted_other_major",
          "accepted": {
            "versionId": "8a7b6c5d-4e3f-4a1b-8c9d-0e1f2a3b4c5d",
            "version": "2.3.0",
            "major": 2,
            "receiptId": "0d9c8b7a-6f5e-4d3c-8b2a-1f0e9d8c7b6a",
            "deploymentId": "3f1c2b7a-5d4e-4a8b-9c0d-1e2f3a4b5c6d",
            "acceptedAt": "2026-09-14T16:02:11.000Z"
          },
          "served": {
            "versionId": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
            "version": "3.0.0",
            "major": 3,
            "revision": 5
          },
          "graceEndsAt": null,
          "change": {
            "versionId": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
            "version": "3.0.0",
            "reason": "Disputes now go to binding arbitration",
            "summary": "Adds an arbitration clause and a class-action waiver.",
            "gate": "BY_DEADLINE",
            "gateDeadline": "2026-11-01T00:00:00.000Z",
            "sinceAccepted": "Consent mechanics changed. Wording changed in en-US: 24 words added, 3 words removed."
          }
        }
      },
      "DeploymentRevisionListResponseDto": {
        "type": "object",
        "properties": {
          "revisions": {
            "type": "array",
            "description": "The revisions on this page, newest first",
            "items": {
              "$ref": "#/components/schemas/DeploymentRevisionDto"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "revisions",
          "pagination"
        ]
      },
      "DeploymentResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Deployment ID",
            "format": "uuid"
          },
          "orgId": {
            "type": "string",
            "description": "Organization ID",
            "format": "uuid"
          },
          "templateId": {
            "type": "string",
            "description": "Template ID",
            "format": "uuid"
          },
          "versionId": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the version the deployment serves now: its current revision’s version. Read the revisions for the history.",
            "nullable": true
          },
          "currentRevisionId": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the deployment’s latest revision",
            "nullable": true
          },
          "environment": {
            "type": "string",
            "description": "Deployment environment",
            "enum": [
              "PRODUCTION",
              "STAGING",
              "DEVELOPMENT"
            ]
          },
          "domain": {
            "type": "string",
            "description": "Domain"
          },
          "path": {
            "type": "string",
            "description": "URL path"
          },
          "variant": {
            "type": "string",
            "description": "A/B test variant",
            "nullable": true
          },
          "active": {
            "type": "boolean",
            "description": "Whether the deployment is active"
          },
          "priority": {
            "type": "integer",
            "description": "Deployment priority. Higher numbers take precedence."
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the deployment becomes active"
          },
          "endAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the deployment expires",
            "nullable": true
          },
          "settings": {
            "type": "object",
            "description": "Deployment-specific settings, including any `policyFlags` set for this deployment",
            "additionalProperties": true,
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "createdBy": {
            "type": "string",
            "description": "ID of the user who created the deployment",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          },
          "activatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the deployment was last activated",
            "nullable": true
          },
          "deactivatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the deployment was last deactivated",
            "nullable": true
          }
        },
        "required": [
          "id",
          "orgId",
          "templateId",
          "environment",
          "domain",
          "path",
          "active",
          "priority",
          "startAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateDeploymentDto": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "description": "Domain where template will be deployed",
            "example": "example.com"
          },
          "versionId": {
            "type": "string",
            "description": "ID of the published version to deploy. The deployment serves it until it is moved, rolled back, or follows a newer minor or patch of the same major.",
            "format": "uuid"
          },
          "environment": {
            "type": "string",
            "description": "Deployment environment",
            "enum": [
              "production",
              "staging",
              "development"
            ],
            "default": "production"
          },
          "path": {
            "type": "string",
            "description": "URL path where template will be active",
            "example": "/",
            "default": "/"
          },
          "variant": {
            "type": "string",
            "description": "A/B test variant identifier",
            "example": "variant-a"
          },
          "active": {
            "type": "boolean",
            "description": "Whether deployment is active",
            "default": true
          },
          "priority": {
            "type": "number",
            "description": "Deployment priority (higher numbers take precedence)",
            "minimum": 0,
            "maximum": 1000,
            "default": 0
          },
          "startAt": {
            "type": "string",
            "description": "When deployment becomes active (ISO 8601 date)",
            "example": "2024-01-15T10:00:00.000Z"
          },
          "endAt": {
            "type": "string",
            "description": "When deployment expires (ISO 8601 date)",
            "example": "2024-12-31T23:59:59.999Z"
          },
          "policyFlags": {
            "type": "object",
            "description": "Policy flags override for this deployment",
            "properties": {
              "requireScroll": {
                "type": "boolean",
                "description": "Require user to scroll through content"
              },
              "blockUntilAssent": {
                "type": "boolean",
                "description": "Block interaction until consent is given"
              },
              "doubleCheckbox": {
                "type": "boolean",
                "description": "Require double checkbox confirmation"
              }
            }
          },
          "settings": {
            "type": "object",
            "description": "Deployment-specific settings and overrides"
          }
        },
        "required": [
          "domain",
          "versionId"
        ]
      },
      "UpdateDeploymentDto": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "description": "Domain where template will be deployed",
            "example": "example.com"
          },
          "environment": {
            "type": "string",
            "description": "Deployment environment. Omit to leave it unchanged.",
            "enum": [
              "production",
              "staging",
              "development"
            ]
          },
          "path": {
            "type": "string",
            "description": "URL path where template will be active. Omit to leave it unchanged.",
            "example": "/"
          },
          "variant": {
            "type": "string",
            "description": "A/B test variant identifier",
            "example": "variant-a"
          },
          "active": {
            "type": "boolean",
            "description": "Whether deployment is active. Omit to leave it unchanged."
          },
          "priority": {
            "type": "number",
            "description": "Deployment priority (higher numbers take precedence). Omit to leave it unchanged.",
            "minimum": 0,
            "maximum": 1000
          },
          "startAt": {
            "type": "string",
            "description": "When deployment becomes active (ISO 8601 date)",
            "example": "2024-01-15T10:00:00.000Z"
          },
          "endAt": {
            "type": "string",
            "description": "When deployment expires (ISO 8601 date)",
            "example": "2024-12-31T23:59:59.999Z"
          },
          "policyFlags": {
            "type": "object",
            "description": "Policy flags override for this deployment",
            "properties": {
              "requireScroll": {
                "type": "boolean",
                "description": "Require user to scroll through content"
              },
              "blockUntilAssent": {
                "type": "boolean",
                "description": "Block interaction until consent is given"
              },
              "doubleCheckbox": {
                "type": "boolean",
                "description": "Require double checkbox confirmation"
              }
            }
          },
          "settings": {
            "type": "object",
            "description": "Deployment-specific settings and overrides"
          }
        }
      },
      "PolicyFlagsDto": {
        "type": "object",
        "properties": {
          "requireScroll": {
            "type": "boolean",
            "description": "Require users to scroll before accepting"
          },
          "blockUntilAssent": {
            "type": "boolean",
            "description": "Block UI until agreement is accepted"
          },
          "doubleCheckbox": {
            "type": "boolean",
            "description": "Require two separate checkbox confirmations"
          },
          "showAcceptanceDate": {
            "type": "boolean",
            "description": "Show acceptance date in UI"
          },
          "allowDecline": {
            "type": "boolean",
            "description": "Allow users to decline"
          },
          "requireExplicitConsent": {
            "type": "boolean",
            "description": "Require explicit consent confirmation"
          }
        },
        "required": [
          "requireScroll",
          "blockUntilAssent",
          "doubleCheckbox",
          "showAcceptanceDate",
          "allowDecline",
          "requireExplicitConsent"
        ]
      },
      "TemplateSettingsDto": {
        "type": "object",
        "properties": {
          "defaultConsentMethod": {
            "type": "string",
            "description": "Default consent method",
            "enum": [
              "CHECKBOX",
              "CLICK",
              "SCROLL",
              "SIGNIN_WRAP"
            ]
          },
          "allowedConsentMethods": {
            "description": "Allowed consent methods",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "displayMode": {
            "type": "string",
            "description": "Display mode",
            "enum": [
              "modal",
              "inline",
              "banner",
              "wall"
            ]
          },
          "allowedRenderModes": {
            "description": "Allowed render modes",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "requireIdentity": {
            "type": "boolean",
            "description": "Whether identity is required"
          },
          "identityMethods": {
            "description": "Available identity methods",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "minimumAge": {
            "type": "number",
            "description": "Minimum age requirement"
          },
          "policyFlags": {
            "description": "Policy flags configuration",
            "allOf": [
              {
                "$ref": "#/components/schemas/PolicyFlagsDto"
              }
            ]
          },
          "customCss": {
            "type": "string",
            "description": "Custom CSS styles"
          },
          "customJavascript": {
            "type": "string",
            "description": "Custom JavaScript code"
          },
          "metadata": {
            "type": "object",
            "description": "Additional metadata"
          }
        },
        "required": [
          "defaultConsentMethod",
          "allowedConsentMethods",
          "displayMode",
          "allowedRenderModes",
          "requireIdentity",
          "identityMethods",
          "policyFlags"
        ]
      },
      "DefaultTemplateSettingsDto": {
        "type": "object",
        "properties": {
          "clickwrap": {
            "description": "Default settings for clickwrap templates",
            "allOf": [
              {
                "$ref": "#/components/schemas/TemplateSettingsDto"
              }
            ]
          },
          "terms": {
            "description": "Default settings for terms templates",
            "allOf": [
              {
                "$ref": "#/components/schemas/TemplateSettingsDto"
              }
            ]
          },
          "privacy": {
            "description": "Default settings for privacy templates",
            "allOf": [
              {
                "$ref": "#/components/schemas/TemplateSettingsDto"
              }
            ]
          }
        },
        "required": [
          "clickwrap",
          "terms",
          "privacy"
        ]
      },
      "FeatureFlagsDto": {
        "type": "object",
        "properties": {
          "webhooks": {
            "type": "boolean",
            "description": "Enable webhook functionality"
          },
          "multiLocale": {
            "type": "boolean",
            "description": "Enable multi-locale support"
          },
          "abTesting": {
            "type": "boolean",
            "description": "Enable A/B testing features"
          }
        },
        "required": [
          "webhooks",
          "multiLocale",
          "abTesting"
        ]
      },
      "ComplianceSettingsDto": {
        "type": "object",
        "properties": {
          "evidenceRetentionDays": {
            "type": "number",
            "description": "Evidence retention period in days"
          },
          "immutableStorage": {
            "type": "boolean",
            "description": "Enable immutable storage (WORM)"
          },
          "auditLogRetentionDays": {
            "type": "number",
            "description": "Audit log retention period in days"
          },
          "requireApprovalWorkflow": {
            "type": "boolean",
            "description": "Require approval workflow for publishing"
          }
        },
        "required": [
          "evidenceRetentionDays",
          "immutableStorage",
          "auditLogRetentionDays",
          "requireApprovalWorkflow"
        ]
      },
      "OrganizationSettingsDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Organization ID"
          },
          "name": {
            "type": "string",
            "description": "Organization name"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string",
            "description": "Creation timestamp"
          },
          "defaultRetentionDays": {
            "type": "number",
            "description": "Default evidence retention period in days",
            "example": 2555
          },
          "piiMode": {
            "type": "string",
            "description": "PII collection mode",
            "enum": [
              "Minimal",
              "Balanced",
              "Full"
            ],
            "example": "Balanced"
          },
          "defaultTemplateSettings": {
            "description": "Default template settings by type",
            "allOf": [
              {
                "$ref": "#/components/schemas/DefaultTemplateSettingsDto"
              }
            ]
          },
          "features": {
            "description": "Feature flags configuration",
            "allOf": [
              {
                "$ref": "#/components/schemas/FeatureFlagsDto"
              }
            ]
          },
          "complianceSettings": {
            "description": "Compliance and governance settings",
            "allOf": [
              {
                "$ref": "#/components/schemas/ComplianceSettingsDto"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "createdAt",
          "defaultRetentionDays",
          "piiMode",
          "defaultTemplateSettings",
          "features",
          "complianceSettings"
        ]
      },
      "UpdatePolicyFlagsDto": {
        "type": "object",
        "properties": {
          "requireScroll": {
            "type": "boolean",
            "description": "Require users to scroll before accepting"
          },
          "blockUntilAssent": {
            "type": "boolean",
            "description": "Block UI until agreement is accepted"
          },
          "doubleCheckbox": {
            "type": "boolean",
            "description": "Require two separate checkbox confirmations"
          },
          "showAcceptanceDate": {
            "type": "boolean",
            "description": "Show acceptance date in UI"
          },
          "allowDecline": {
            "type": "boolean",
            "description": "Allow users to decline"
          },
          "requireExplicitConsent": {
            "type": "boolean",
            "description": "Require explicit consent confirmation"
          }
        }
      },
      "UpdateTemplateSettingsDto": {
        "type": "object",
        "properties": {
          "defaultConsentMethod": {
            "type": "string",
            "description": "Default consent method",
            "enum": [
              "CHECKBOX",
              "CLICK",
              "SCROLL",
              "SIGNIN_WRAP"
            ]
          },
          "allowedConsentMethods": {
            "description": "Allowed consent methods",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "displayMode": {
            "type": "string",
            "description": "Display mode",
            "enum": [
              "modal",
              "inline",
              "banner",
              "wall"
            ]
          },
          "allowedRenderModes": {
            "description": "Allowed render modes",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "requireIdentity": {
            "type": "boolean",
            "description": "Whether identity is required"
          },
          "identityMethods": {
            "description": "Available identity methods",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "minimumAge": {
            "type": "number",
            "description": "Minimum age requirement"
          },
          "policyFlags": {
            "description": "Policy flags configuration",
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatePolicyFlagsDto"
              }
            ]
          },
          "customCss": {
            "type": "string",
            "description": "Custom CSS styles"
          },
          "customJavascript": {
            "type": "string",
            "description": "Custom JavaScript code"
          },
          "metadata": {
            "type": "object",
            "description": "Additional metadata"
          }
        }
      },
      "UpdateDefaultTemplateSettingsDto": {
        "type": "object",
        "properties": {
          "clickwrap": {
            "description": "Default settings for clickwrap templates",
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdateTemplateSettingsDto"
              }
            ]
          },
          "terms": {
            "description": "Default settings for terms templates",
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdateTemplateSettingsDto"
              }
            ]
          },
          "privacy": {
            "description": "Default settings for privacy templates",
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdateTemplateSettingsDto"
              }
            ]
          }
        }
      },
      "UpdateOrganizationSettingsDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Organization name"
          },
          "defaultRetentionDays": {
            "type": "number",
            "description": "Default evidence retention period in days",
            "minimum": 365,
            "maximum": 3650
          },
          "piiMode": {
            "type": "string",
            "description": "PII collection mode",
            "enum": [
              "Minimal",
              "Balanced",
              "Full"
            ]
          },
          "defaultTemplateSettings": {
            "description": "Default template settings by type",
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdateDefaultTemplateSettingsDto"
              }
            ]
          },
          "features": {
            "description": "Feature flags configuration",
            "allOf": [
              {
                "$ref": "#/components/schemas/FeatureFlagsDto"
              }
            ]
          },
          "complianceSettings": {
            "description": "Compliance and governance settings",
            "allOf": [
              {
                "$ref": "#/components/schemas/ComplianceSettingsDto"
              }
            ]
          }
        }
      },
      "Pagination": {
        "type": "object",
        "description": "Where a page sits in the full result. Rows keep the same order on every page, so walking `page` from 1 while `hasMore` is true visits each row once.",
        "properties": {
          "total": {
            "type": "integer",
            "description": "Number of rows that match the request, across every page",
            "example": 57
          },
          "page": {
            "type": "integer",
            "description": "The page returned, starting at 1",
            "example": 1
          },
          "limit": {
            "type": "integer",
            "description": "The page size used",
            "example": 20
          },
          "hasMore": {
            "type": "boolean",
            "description": "True when a later page has rows",
            "example": true
          }
        },
        "required": [
          "total",
          "page",
          "limit",
          "hasMore"
        ]
      },
      "TemplateListResponseDto": {
        "type": "object",
        "properties": {
          "templates": {
            "type": "array",
            "description": "The templates on this page, newest first",
            "items": {
              "$ref": "#/components/schemas/TemplateResponseDto"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "templates",
          "pagination"
        ]
      },
      "TemplateStatsDto": {
        "type": "object",
        "properties": {
          "versionCount": {
            "type": "integer",
            "description": "Number of versions of the template"
          },
          "publishedVersions": {
            "type": "integer",
            "description": "Number of published versions of the template"
          },
          "totalDeployments": {
            "type": "integer",
            "description": "Number of deployments of the template, active or not"
          },
          "activeDeployments": {
            "type": "integer",
            "description": "Number of active deployments of the template"
          }
        },
        "required": [
          "versionCount",
          "publishedVersions",
          "totalDeployments",
          "activeDeployments"
        ]
      },
      "TemplatePolicyFlagsDto": {
        "type": "object",
        "description": "Behavior switches for a template. Every flag is optional.",
        "properties": {
          "requireEmailVerification": {
            "type": "boolean",
            "description": "Require email verification before acceptance"
          },
          "requireSmsVerification": {
            "type": "boolean",
            "description": "Require SMS verification before acceptance"
          },
          "allowMultipleAcceptances": {
            "type": "boolean",
            "description": "Allow multiple acceptances from the same user"
          },
          "requireReacceptanceOnUpdate": {
            "type": "boolean",
            "description": "Require re-acceptance when the template is updated"
          },
          "enableAutoArchive": {
            "type": "boolean",
            "description": "Archive automatically after the retention period"
          },
          "requireExplicitConsent": {
            "type": "boolean",
            "description": "Require an explicit consent checkbox"
          },
          "trackIpAddress": {
            "type": "boolean",
            "description": "Record the IP address of the acceptance"
          },
          "enableDeviceFingerprint": {
            "type": "boolean",
            "description": "Record a device fingerprint with the acceptance"
          },
          "requireSignature": {
            "type": "boolean",
            "description": "Require signature capture"
          },
          "requireWitness": {
            "type": "boolean",
            "description": "Require a witness"
          },
          "allowDelegation": {
            "type": "boolean",
            "description": "Allow another person to accept on the signer behalf"
          },
          "enableAuditLogging": {
            "type": "boolean",
            "description": "Write an audit log entry for every action"
          },
          "requireManagerApproval": {
            "type": "boolean",
            "description": "Require manager approval before activation"
          },
          "enableVersionControl": {
            "type": "boolean",
            "description": "Keep versions with rollback"
          },
          "sendConfirmationEmail": {
            "type": "boolean",
            "description": "Send an acceptance confirmation email"
          },
          "generateCertificate": {
            "type": "boolean",
            "description": "Generate a PDF certificate on acceptance"
          },
          "enableBlockchainRecording": {
            "type": "boolean",
            "description": "Record the acceptance on a blockchain"
          },
          "requireBiometric": {
            "type": "boolean",
            "description": "Require biometric authentication"
          },
          "enableGeoRestrictions": {
            "type": "boolean",
            "description": "Enable geographic restrictions"
          },
          "requireVideoConsent": {
            "type": "boolean",
            "description": "Require a video consent recording"
          }
        }
      },
      "TemplateTypeValidationRulesDto": {
        "type": "object",
        "properties": {
          "minContentLength": {
            "type": "integer",
            "description": "Minimum content length in characters"
          },
          "maxContentLength": {
            "type": "integer",
            "description": "Maximum content length in characters"
          },
          "requiredSections": {
            "type": "array",
            "description": "Section names the content must contain",
            "items": {
              "type": "string"
            }
          },
          "forbiddenTerms": {
            "type": "array",
            "description": "Terms the content must not contain",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "TemplateTypeConfigDto": {
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string",
            "description": "Display name of the template type"
          },
          "description": {
            "type": "string",
            "description": "What the template type is for"
          },
          "icon": {
            "type": "string",
            "description": "Icon identifier"
          },
          "defaultRetentionDays": {
            "type": "integer",
            "description": "Default retention period in days"
          },
          "minRetentionDays": {
            "type": "integer",
            "description": "Shortest allowed retention period in days"
          },
          "maxRetentionDays": {
            "type": "integer",
            "description": "Longest allowed retention period in days"
          },
          "defaultPolicyFlags": {
            "$ref": "#/components/schemas/TemplatePolicyFlagsDto"
          },
          "requiredPolicyFlags": {
            "$ref": "#/components/schemas/TemplatePolicyFlagsDto"
          },
          "allowedFormats": {
            "type": "array",
            "description": "Content formats the type accepts",
            "items": {
              "type": "string"
            }
          },
          "requiresLegalReview": {
            "type": "boolean",
            "description": "Whether the type calls for legal review"
          },
          "versioningRequired": {
            "type": "boolean",
            "description": "Whether versioning is mandatory"
          },
          "validationRules": {
            "$ref": "#/components/schemas/TemplateTypeValidationRulesDto"
          },
          "complianceStandards": {
            "type": "array",
            "description": "Compliance standards the type supports",
            "items": {
              "type": "string"
            }
          },
          "allowPublicAccess": {
            "type": "boolean",
            "description": "Whether the type can be publicly accessed"
          },
          "supportsBulkOperations": {
            "type": "boolean",
            "description": "Whether the type supports bulk operations"
          },
          "metadataSchema": {
            "type": "object",
            "description": "Schema for the template metadata",
            "additionalProperties": true
          }
        },
        "required": [
          "displayName",
          "description",
          "defaultRetentionDays",
          "minRetentionDays",
          "maxRetentionDays",
          "defaultPolicyFlags",
          "requiredPolicyFlags",
          "allowedFormats",
          "requiresLegalReview",
          "versioningRequired",
          "allowPublicAccess",
          "supportsBulkOperations"
        ]
      },
      "TemplateTypeEntryDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Template type key",
            "enum": [
              "clickwrap",
              "terms",
              "privacy",
              "consent",
              "nda",
              "agreement",
              "custom"
            ]
          },
          "config": {
            "$ref": "#/components/schemas/TemplateTypeConfigDto"
          }
        },
        "required": [
          "type",
          "config"
        ]
      },
      "TemplateConfigurationDto": {
        "type": "object",
        "properties": {
          "template": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Template ID",
                "format": "uuid"
              },
              "name": {
                "type": "string",
                "description": "Template name"
              },
              "type": {
                "type": "string",
                "description": "Template type",
                "enum": [
                  "STATIC",
                  "GENERATED",
                  "CONSENT"
                ]
              },
              "status": {
                "type": "string",
                "description": "Template status",
                "enum": [
                  "DRAFT",
                  "PUBLISHED",
                  "ARCHIVED"
                ]
              }
            },
            "required": [
              "id",
              "name",
              "type",
              "status"
            ]
          },
          "typeConfig": {
            "type": "object",
            "description": "Rules that govern the template type: retention limits, default and required policy flags, allowed formats, validation rules and compliance standards",
            "additionalProperties": true
          },
          "policyFlags": {
            "$ref": "#/components/schemas/TemplatePolicyFlagsDto"
          },
          "complianceStandards": {
            "type": "array",
            "description": "Compliance standards the template type supports",
            "items": {
              "type": "string"
            }
          },
          "validationRules": {
            "$ref": "#/components/schemas/TemplateTypeValidationRulesDto"
          },
          "allowedFormats": {
            "type": "array",
            "description": "Content formats the template type accepts",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "template",
          "typeConfig",
          "policyFlags",
          "complianceStandards",
          "validationRules",
          "allowedFormats"
        ]
      },
      "VerificationRequirementsDto": {
        "type": "object",
        "properties": {
          "requireEmailVerification": {
            "type": "boolean",
            "description": "Email verification is required"
          },
          "requireSmsVerification": {
            "type": "boolean",
            "description": "SMS verification is required"
          },
          "requireSignature": {
            "type": "boolean",
            "description": "A signature is required"
          },
          "requireBiometric": {
            "type": "boolean",
            "description": "Biometric authentication is required"
          },
          "requireVideoConsent": {
            "type": "boolean",
            "description": "A video consent recording is required"
          },
          "requireWitness": {
            "type": "boolean",
            "description": "A witness is required"
          }
        },
        "required": [
          "requireEmailVerification",
          "requireSmsVerification",
          "requireSignature",
          "requireBiometric",
          "requireVideoConsent",
          "requireWitness"
        ]
      },
      "VerificationRequirementsCatalogueDto": {
        "type": "object",
        "properties": {
          "requirements": {
            "type": "array",
            "description": "Every verification requirement a template can enable",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "description": "Requirement key, as used in a template policy flag"
                },
                "defaultValue": {
                  "type": "boolean",
                  "description": "Value a template has when the requirement is not set"
                }
              },
              "required": [
                "key",
                "defaultValue"
              ]
            }
          }
        },
        "required": [
          "requirements"
        ]
      },
      "ContentValidationResultDto": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "Whether the content passed every rule"
          },
          "errors": {
            "type": "array",
            "description": "One message per rule the content failed. Empty when valid.",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "valid",
          "errors"
        ]
      },
      "ScheduledPublishListResponseDto": {
        "type": "object",
        "properties": {
          "scheduledPublishes": {
            "type": "array",
            "description": "The scheduled publish jobs on this page, latest scheduled time first",
            "items": {
              "$ref": "#/components/schemas/ScheduledPublishDto"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "scheduledPublishes",
          "pagination"
        ]
      },
      "ScheduledPublishDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Scheduled publish ID",
            "format": "uuid"
          },
          "orgId": {
            "type": "string",
            "description": "Organization ID",
            "format": "uuid"
          },
          "templateId": {
            "type": "string",
            "description": "Template ID",
            "format": "uuid"
          },
          "versionId": {
            "type": "string",
            "description": "Version ID"
          },
          "scheduledFor": {
            "type": "string",
            "format": "date-time",
            "description": "When the version is scheduled to publish"
          },
          "status": {
            "type": "string",
            "description": "State of the scheduled publish",
            "enum": [
              "PENDING",
              "IN_FLIGHT",
              "SUCCEEDED",
              "FAILED",
              "CANCELLED"
            ]
          },
          "attempts": {
            "type": "integer",
            "description": "Number of times the publish has been attempted"
          },
          "lastError": {
            "type": "string",
            "description": "Error message when the publish failed",
            "nullable": true
          },
          "executedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the publish last ran, whether it succeeded or failed",
            "nullable": true
          },
          "createdBy": {
            "type": "string",
            "description": "ID of the user who scheduled the publish",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        },
        "required": [
          "id",
          "orgId",
          "templateId",
          "versionId",
          "scheduledFor",
          "status",
          "attempts",
          "createdBy",
          "createdAt",
          "updatedAt"
        ]
      },
      "CancelScheduledPublishResultDto": {
        "type": "object",
        "properties": {
          "cancelled": {
            "type": "boolean",
            "description": "True when a pending scheduled publish was cancelled. False when it had already run or been cancelled."
          }
        },
        "required": [
          "cancelled"
        ]
      },
      "DeploymentListResponseDto": {
        "type": "object",
        "properties": {
          "deployments": {
            "type": "array",
            "description": "The deployments on this page, highest priority first",
            "items": {
              "$ref": "#/components/schemas/DeploymentResponseDto"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "deployments",
          "pagination"
        ]
      },
      "DashboardMetricsDto": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": "object",
            "description": "Sessions started in the range, counted by outcome",
            "properties": {
              "total": {
                "type": "integer",
                "description": "All sessions: the sum of the four outcomes"
              },
              "accepted": {
                "type": "integer",
                "description": "Sessions the signer accepted"
              },
              "declined": {
                "type": "integer",
                "description": "Sessions the signer declined"
              },
              "pending": {
                "type": "integer",
                "description": "Sessions still waiting for an answer within their window"
              },
              "expired": {
                "type": "integer",
                "description": "Sessions that closed without an answer"
              },
              "viewed": {
                "type": "integer",
                "description": "Times the agreement was shown to a signer in the range",
                "nullable": true
              }
            },
            "required": [
              "total",
              "accepted",
              "declined",
              "pending",
              "expired",
              "viewed"
            ]
          },
          "conversionRate": {
            "type": "number",
            "description": "Accepted sessions as a percentage of views, to one decimal place. Null while there are no views to divide by, or when more sessions were accepted than viewed.",
            "nullable": true
          },
          "activeTemplates": {
            "type": "integer",
            "description": "Templates in your organization that are not archived"
          },
          "activeDeployments": {
            "type": "integer",
            "description": "Active deployments in your organization"
          },
          "trend": {
            "type": "array",
            "description": "One point per UTC day in the range, oldest first, with zeros for quiet days",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "description": "Day, YYYY-MM-DD (UTC)"
                },
                "total": {
                  "type": "integer",
                  "description": "All sessions: the sum of the four outcomes"
                },
                "accepted": {
                  "type": "integer",
                  "description": "Sessions the signer accepted"
                },
                "declined": {
                  "type": "integer",
                  "description": "Sessions the signer declined"
                },
                "pending": {
                  "type": "integer",
                  "description": "Sessions still waiting for an answer within their window"
                },
                "expired": {
                  "type": "integer",
                  "description": "Sessions that closed without an answer"
                },
                "viewed": {
                  "type": "integer",
                  "description": "Times the agreement was shown that day",
                  "nullable": true
                }
              },
              "required": [
                "date",
                "total",
                "accepted",
                "declined",
                "pending",
                "expired",
                "viewed"
              ]
            }
          },
          "topTemplates": {
            "type": "array",
            "description": "The templates with the most accepted sessions in the range, most first (up to 5). Templates with none are left out.",
            "items": {
              "type": "object",
              "properties": {
                "templateId": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Template ID"
                },
                "name": {
                  "type": "string",
                  "description": "Template name"
                },
                "accepted": {
                  "type": "integer",
                  "description": "Sessions accepted for the template in the range"
                }
              },
              "required": [
                "templateId",
                "name",
                "accepted"
              ]
            }
          },
          "deviceMix": {
            "type": "array",
            "description": "Device class of the signers, from the browser recorded with each acceptance, most common first. Classes that never appear are left out. Empty when there are no acceptances in the range.",
            "items": {
              "type": "object",
              "properties": {
                "device": {
                  "type": "string",
                  "description": "Device class",
                  "enum": [
                    "Desktop",
                    "Mobile",
                    "Tablet",
                    "Other"
                  ]
                },
                "count": {
                  "type": "integer",
                  "description": "Acceptances from this device class"
                },
                "percentage": {
                  "type": "integer",
                  "description": "Share of the counted acceptances, in whole percent"
                }
              },
              "required": [
                "device",
                "count",
                "percentage"
              ]
            }
          },
          "regions": {
            "type": "array",
            "description": "Where acceptances came from, most first, using the location stored with each acceptance. Only acceptances with a stored location are counted. Empty, never estimated, when none has one.",
            "items": {
              "type": "object",
              "properties": {
                "region": {
                  "type": "string",
                  "description": "Region name"
                },
                "count": {
                  "type": "integer",
                  "description": "Acceptances from the region"
                },
                "percentage": {
                  "type": "integer",
                  "description": "Share of the acceptances that have a stored location, in whole percent"
                }
              },
              "required": [
                "region",
                "count",
                "percentage"
              ]
            }
          },
          "recentActivity": {
            "type": "array",
            "description": "The latest events in your organization, newest first (up to 10). Views are not listed.",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "description": "Kind of event"
                },
                "title": {
                  "type": "string",
                  "description": "Short title"
                },
                "timestamp": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When it happened"
                }
              },
              "required": [
                "type",
                "title",
                "timestamp"
              ]
            }
          }
        },
        "required": [
          "sessions",
          "conversionRate",
          "activeTemplates",
          "activeDeployments",
          "trend",
          "topTemplates",
          "deviceMix",
          "regions",
          "recentActivity"
        ]
      },
      "AcceptanceResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Acceptance ID"
          },
          "orgId": {
            "type": "string",
            "description": "Organization ID"
          },
          "templateId": {
            "type": "string",
            "description": "Template ID"
          },
          "templateVersionId": {
            "type": "string",
            "description": "ID of the version record the signer was served (the version you published). Evidence format 1 binds it, with the deployment revision, in the signed receipt.",
            "nullable": true
          },
          "deploymentId": {
            "type": "string",
            "description": "Deployment the acceptance was recorded through"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When the acceptance completed, or started if it has not completed"
          },
          "email": {
            "type": "string",
            "description": "Reference for the user who accepted, as supplied when the acceptance was recorded"
          },
          "userId": {
            "type": "string",
            "description": "Same value as `userRef`"
          },
          "userRef": {
            "type": "string",
            "description": "Reference for the user who accepted, as supplied when the acceptance was recorded"
          },
          "ipAddress": {
            "type": "string",
            "description": "IP address the acceptance came from"
          },
          "userAgent": {
            "type": "string",
            "description": "Browser user agent of the acceptance"
          },
          "url": {
            "type": "string",
            "description": "Page URL where the acceptance happened"
          },
          "referrer": {
            "type": "string",
            "description": "Referrer of the page"
          },
          "locale": {
            "type": "string",
            "description": "Locale of the content that was accepted"
          },
          "screenResolution": {
            "type": "string",
            "description": "Screen size as `<width>x<height>@<pixel ratio>`"
          },
          "sdkVersion": {
            "type": "string",
            "description": "Version of the client software that recorded the acceptance"
          },
          "variant": {
            "type": "string",
            "description": "A/B test variant that was shown"
          },
          "consentMethod": {
            "type": "string",
            "description": "How the user gave consent, as sent on the accept request. `null` for an acceptance recorded before the method was kept.",
            "enum": [
              "BUTTON",
              "CHECKBOX",
              "SCROLL",
              "SIGNIN_WRAP",
              null
            ],
            "nullable": true
          },
          "receiptId": {
            "type": "string",
            "description": "Receipt ID. Use it with the receipt and evidence routes."
          },
          "snapshotUri": {
            "type": "string",
            "description": "Location of the stored evidence artifacts"
          },
          "contentHash": {
            "type": "string",
            "description": "SHA-256 of the content that was presented. `null` when the acceptance has no evidence and no rendered hash.",
            "nullable": true
          },
          "chainHash": {
            "type": "string",
            "description": "Evidence chain hash"
          },
          "environment": {
            "type": "string",
            "description": "Environment of the deployment the acceptance came through",
            "enum": [
              "PRODUCTION",
              "STAGING",
              "DEVELOPMENT",
              null
            ],
            "nullable": true
          },
          "identity": {
            "type": "object",
            "description": "Identity verification recorded with the acceptance. Absent when none was recorded.",
            "properties": {
              "level": {
                "type": "string",
                "description": "Identity verification method used"
              },
              "assertions": {
                "type": "array",
                "items": {
                  "description": "Identity assertion as recorded with the acceptance"
                }
              },
              "verifiedAt": {
                "type": "string",
                "format": "date-time",
                "description": "When the identity was verified"
              }
            }
          },
          "metadata": {
            "type": "object",
            "description": "Metadata recorded with the acceptance",
            "additionalProperties": true
          },
          "evidence": {
            "type": "object",
            "description": "Evidence summary. Present when `includeEvidence` is true and the acceptance has evidence.",
            "properties": {
              "id": {
                "type": "string",
                "description": "Evidence ID"
              },
              "contentHash": {
                "type": "string",
                "description": "SHA-256 of the content that was presented. `null` until the evidence is complete.",
                "nullable": true
              },
              "chainHash": {
                "type": "string",
                "description": "Evidence chain hash. `null` until the evidence is complete.",
                "nullable": true
              },
              "signature": {
                "type": "string",
                "description": "Evidence signature. `null` until the evidence is complete.",
                "nullable": true
              },
              "signatureKeyId": {
                "type": "string",
                "description": "Signing key version"
              }
            }
          },
          "receipt": {
            "type": "object",
            "description": "Receipt summary. Present when `includeReceipt` is true.",
            "properties": {
              "id": {
                "type": "string",
                "description": "Receipt ID"
              },
              "recordId": {
                "type": "string",
                "description": "Record ID"
              },
              "timestamp": {
                "type": "string",
                "format": "date-time",
                "description": "When the acceptance completed, or started if it has not completed"
              },
              "contentHash": {
                "type": "string",
                "description": "SHA-256 of the content that was presented. `null` when the acceptance has no rendered hash.",
                "nullable": true
              },
              "chainHash": {
                "type": "string",
                "description": "Evidence chain hash"
              },
              "signature": {
                "type": "string",
                "description": "Receipt signature"
              },
              "keyId": {
                "type": "string",
                "description": "Signing key version"
              }
            }
          }
        },
        "required": [
          "id",
          "orgId",
          "templateVersionId",
          "timestamp",
          "userAgent",
          "consentMethod",
          "receiptId"
        ]
      },
      "AcceptanceListResponseDto": {
        "type": "object",
        "properties": {
          "acceptances": {
            "type": "array",
            "description": "The acceptances on this page, newest first",
            "items": {
              "$ref": "#/components/schemas/AcceptanceResponseDto"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "acceptances",
          "pagination"
        ]
      },
      "ReceiptResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Receipt id (the acceptance id)."
          },
          "recordId": {
            "type": "string",
            "description": "Record ID"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When the acceptance started"
          },
          "contentHash": {
            "type": "string",
            "description": "SHA-256 of the evidence content."
          },
          "chainHash": {
            "type": "string",
            "description": "Evidence chain hash."
          },
          "signature": {
            "type": "string",
            "description": "Receipt signature. Empty unless evidenceStatus is complete: only complete evidence is signed."
          },
          "keyId": {
            "type": "string",
            "description": "Signing key version."
          },
          "evidenceStatus": {
            "type": "string",
            "enum": [
              "pending",
              "complete",
              "failed"
            ],
            "description": "pending: the acceptance is recorded and evidence is still being produced. complete: evidence is hashed, chained and signed. failed: evidence could not be produced; the acceptance is still recorded, and a click.evidence.failed webhook is sent. A failed status can still become complete if evidence is produced later; a click.acceptance.completed webhook sent after click.evidence.failed is the final state. This field always reflects the latest state."
          },
          "evidence": {
            "type": "object",
            "description": "The evidence record behind the receipt. `null` when no evidence exists yet.",
            "additionalProperties": true,
            "nullable": true
          }
        },
        "required": [
          "id",
          "timestamp",
          "evidenceStatus"
        ]
      },
      "EvidenceBundleDto": {
        "type": "object",
        "properties": {
          "snapshotHtml": {
            "type": "string",
            "description": "Location of the HTML snapshot that was shown"
          },
          "snapshotCss": {
            "type": "string",
            "description": "Location of the style metadata for the snapshot"
          },
          "screenshot": {
            "type": "string",
            "description": "Location of the screenshot"
          },
          "screenshotUrl": {
            "type": "string",
            "description": "Same value as `screenshot`"
          },
          "metadata": {
            "type": "object",
            "properties": {
              "bundleUrl": {
                "type": "string",
                "description": "Location of the evidence bundle archive. `null` when no artifacts are stored.",
                "nullable": true
              },
              "receiptUrl": {
                "type": "string",
                "description": "Location of the receipt document. `null` when no artifacts are stored.",
                "nullable": true
              },
              "contentHash": {
                "type": "string",
                "description": "SHA-256 of the content that was presented. `null` until the evidence is complete.",
                "nullable": true
              },
              "chainHash": {
                "type": "string",
                "description": "Evidence chain hash. `null` until the evidence is complete.",
                "nullable": true
              },
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "description": "When the evidence was recorded"
              },
              "screenshotUrl": {
                "type": "string",
                "description": "Location of the screenshot. `null` when no artifacts are stored.",
                "nullable": true
              },
              "blobBaseUrl": {
                "type": "string",
                "description": "Base location of the stored evidence artifacts. `null` when no artifacts are stored.",
                "nullable": true
              },
              "snapshotHtmlUrl": {
                "type": "string",
                "description": "Location of the HTML snapshot. `null` when no artifacts are stored.",
                "nullable": true
              },
              "snapshotCssUrl": {
                "type": "string",
                "description": "Location of the style metadata. `null` when no artifacts are stored.",
                "nullable": true
              }
            }
          }
        },
        "required": [
          "metadata"
        ]
      },
      "RetentionStatusResponseDto": {
        "type": "object",
        "properties": {
          "acceptances": {
            "type": "array",
            "description": "Retention state of each acceptance on the requested page, oldest first",
            "items": {
              "type": "object",
              "properties": {
                "recordId": {
                  "type": "string",
                  "description": "Acceptance ID"
                },
                "templateId": {
                  "type": "string",
                  "description": "Template ID"
                },
                "acceptanceDate": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When the acceptance started"
                },
                "expiryDate": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When the retention period ends"
                },
                "daysUntilExpiry": {
                  "type": "integer",
                  "description": "Days left in the retention period. Zero or negative once expired."
                },
                "retentionBucket": {
                  "type": "string",
                  "description": "Retention class the evidence is stored under"
                },
                "status": {
                  "type": "string",
                  "description": "EXPIRED once the retention period has ended, WARNING within 30 days of ending, otherwise ACTIVE",
                  "enum": [
                    "ACTIVE",
                    "WARNING",
                    "EXPIRED"
                  ]
                }
              },
              "required": [
                "recordId",
                "templateId",
                "acceptanceDate",
                "expiryDate",
                "daysUntilExpiry",
                "retentionBucket",
                "status"
              ]
            }
          },
          "summary": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "description": "Number of acceptances that match the request, across every page"
              },
              "expiringSoon": {
                "type": "integer",
                "description": "Acceptances on this page with status WARNING"
              },
              "expired": {
                "type": "integer",
                "description": "Acceptances on this page with status EXPIRED"
              }
            },
            "required": [
              "total",
              "expiringSoon",
              "expired"
            ]
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "acceptances",
          "summary",
          "pagination"
        ]
      },
      "EvidenceCheckDto": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "Whether the check passed"
          },
          "status": {
            "type": "string",
            "description": "pass: the check succeeded. fail: the evidence does not match. not_verifiable: the inputs needed to run the check were not available. not_issued: this kind of evidence is not issued yet. not_applicable: this acceptance has no such evidence by design, such as no screenshot or no captured HTML. not_issued and not_applicable never pass and never make the result invalid.",
            "enum": [
              "pass",
              "fail",
              "not_verifiable",
              "not_issued",
              "not_applicable"
            ]
          },
          "message": {
            "type": "string",
            "description": "Result of the check"
          },
          "details": {
            "type": "string",
            "description": "Extra detail, when there is any"
          }
        },
        "required": [
          "valid",
          "status",
          "message"
        ]
      },
      "EvidenceVerificationRecordDto": {
        "type": "object",
        "description": "Integrity fields of the verified record. User-identifying fields are left out.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Evidence ID"
          },
          "sessionId": {
            "type": "string",
            "description": "Acceptance ID"
          },
          "orgId": {
            "type": "string",
            "description": "Organization ID"
          },
          "templateId": {
            "type": "string",
            "description": "Template ID"
          },
          "versionId": {
            "type": "string",
            "description": "ID of the version record the acceptance was served",
            "nullable": true
          },
          "revisionId": {
            "type": "string",
            "description": "ID of the deployment revision that served it",
            "nullable": true
          },
          "formatVersion": {
            "type": "integer",
            "description": "Evidence format of the record. Formats 1 and 2 verify; format 1 is read-only.",
            "nullable": true
          },
          "resolvedSettingsHash": {
            "type": "string",
            "description": "SHA-256 over the four settings layers in force at acceptance: environment defaults, organization settings, the version and the revision"
          },
          "clickType": {
            "type": "string",
            "description": "Template type",
            "enum": [
              "STATIC",
              "GENERATED",
              "CONSENT"
            ]
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the acceptance happened"
          },
          "processingStatus": {
            "type": "string",
            "description": "Evidence processing state",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED"
            ]
          },
          "presentedContentHash": {
            "type": "string",
            "description": "SHA-256 of the content that was presented"
          },
          "chainHash": {
            "type": "string",
            "description": "Evidence chain hash",
            "nullable": true
          },
          "chainSequence": {
            "type": "integer",
            "description": "Position of the record in your evidence chain",
            "nullable": true
          },
          "previousChainHash": {
            "type": "string",
            "description": "Chain hash of the previous record",
            "nullable": true
          },
          "signature": {
            "type": "string",
            "description": "Evidence signature",
            "nullable": true
          },
          "signatureAlgorithm": {
            "type": "string",
            "description": "Signature algorithm",
            "nullable": true
          },
          "signatureKeyId": {
            "type": "string",
            "description": "Signing key version",
            "nullable": true
          },
          "retentionExpiry": {
            "type": "string",
            "format": "date-time",
            "description": "When the retention period ends",
            "nullable": true
          },
          "ipMasked": {
            "type": "string",
            "description": "IP address with the last octet masked"
          }
        },
        "required": [
          "id",
          "sessionId",
          "orgId",
          "templateId",
          "versionId",
          "revisionId",
          "formatVersion",
          "resolvedSettingsHash",
          "clickType",
          "occurredAt",
          "presentedContentHash"
        ]
      },
      "EvidenceVerificationResultDto": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "True when no check that must pass failed. `false` means only that the evidence failed verification; an ID that does not exist is a 404."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When the verification ran"
          },
          "evidenceStatus": {
            "type": "string",
            "enum": [
              "pending",
              "complete",
              "failed"
            ],
            "description": "Evidence state of the record. Only complete evidence is verified: pending and failed evidence return `valid: false` with every check `not_verifiable`. Absent for an uploaded receipt."
          },
          "checks": {
            "type": "object",
            "description": "Result of each check",
            "properties": {
              "contentHash": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              },
              "signature": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              },
              "chainHash": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              },
              "formatVersion": {
                "$ref": "#/components/schemas/EvidenceCheckDto",
                "description": "The receipt is evidence format 1 or 2, binds a version and revision by id, and the record names the same ones. A format 2 receipt also carries well-formed identity commitments and no plaintext identity. Any other format fails."
              },
              "screenshotHash": {
                "$ref": "#/components/schemas/EvidenceCheckDto",
                "description": "The stored screenshot hashes to the SHA-256 the signed receipt binds. A missing or replaced screenshot fails. `not_applicable` when the acceptance has no screenshot."
              },
              "capturedHtmlHash": {
                "$ref": "#/components/schemas/EvidenceCheckDto",
                "description": "The stored captured HTML hashes to the SHA-256 the signed receipt binds. Missing or replaced HTML fails. `not_applicable` when the host sent no captured HTML."
              },
              "tsaToken": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              },
              "merkleProof": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              },
              "externalAnchor": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              },
              "retention": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              },
              "revocation": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              },
              "keyValidity": {
                "$ref": "#/components/schemas/EvidenceCheckDto"
              }
            },
            "required": [
              "contentHash",
              "signature",
              "chainHash",
              "formatVersion",
              "screenshotHash",
              "capturedHtmlHash",
              "tsaToken",
              "merkleProof",
              "externalAnchor",
              "retention",
              "revocation",
              "keyValidity"
            ]
          },
          "environmentChecks": {
            "type": "object",
            "description": "Environment checks. Both count toward `valid`. Absent for an uploaded receipt.",
            "properties": {
              "deployment": {
                "$ref": "#/components/schemas/EvidenceCheckDto",
                "description": "The signed receipt deployment and environment match your deployment"
              },
              "signingKeyProject": {
                "$ref": "#/components/schemas/EvidenceCheckDto",
                "description": "The signing key belongs to the environment of the deployment"
              }
            },
            "required": [
              "deployment",
              "signingKeyProject"
            ]
          },
          "evidence": {
            "$ref": "#/components/schemas/EvidenceVerificationRecordDto"
          },
          "errors": {
            "type": "array",
            "description": "Failed checks and problems that made the result invalid",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "description": "Checks that could not be completed but do not make the result invalid",
            "items": {
              "type": "string"
            }
          },
          "isTestEvidence": {
            "type": "boolean",
            "description": "True unless the acceptance came through a production deployment"
          }
        },
        "required": [
          "valid",
          "timestamp",
          "checks"
        ]
      },
      "IdentityAssertionDto": {
        "type": "object",
        "properties": {
          "level": {
            "type": "string",
            "description": "Identity assertion level/method",
            "example": "email"
          },
          "method": {
            "type": "string",
            "description": "Identity assertion method",
            "enum": [
              "otp",
              "sso",
              "webauthn",
              "email",
              "simple"
            ],
            "example": "email"
          },
          "value": {
            "type": "string",
            "description": "Raw assertion data to be hashed (will not be stored)",
            "example": "e2e-test-recipient+click-docs@propper.ai:verification-code-123"
          },
          "email": {
            "type": "string",
            "description": "User email",
            "example": "e2e-test-recipient+click-docs@propper.ai"
          },
          "name": {
            "type": "string",
            "description": "User name",
            "example": "John Doe"
          },
          "company": {
            "type": "string",
            "description": "User company",
            "example": "Acme Corp"
          },
          "verifiedAt": {
            "type": "number",
            "description": "Verification timestamp",
            "example": 1234567890
          },
          "sessionId": {
            "type": "string",
            "description": "Verification session ID for OTP/2FA methods",
            "example": "550e8400-e29b-41d4-a716-446655440003"
          },
          "verificationToken": {
            "type": "string",
            "description": "Verification token proving identity was verified",
            "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
          }
        }
      },
      "AcceptConsentDto": {
        "type": "object",
        "properties": {
          "templateVersionId": {
            "type": "string",
            "description": "Template version UUID",
            "example": "550e8400-e29b-41d4-a716-446655440000"
          },
          "deploymentId": {
            "type": "string",
            "description": "Deployment ID that served the consent form",
            "example": "550e8400-e29b-41d4-a716-446655440002"
          },
          "checksum": {
            "type": "string",
            "description": "SHA-256 (hex) of the `content` the deployment served, exactly as the render API returned it (its `checksum`). Must match what the deployment serves for the locale in `metadata.locale`, which must be the locale it was rendered with (omitted, the default locale is used, with the same fallback as render), or the acceptance is rejected with 422 `CLICK_CHECKSUM_MISMATCH`. The field is required: a body without it is a 400 validation error, while an empty or non-matching value is a 422.",
            "example": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
          },
          "consentMethod": {
            "type": "string",
            "description": "Consent method used for acceptance",
            "enum": [
              "BUTTON",
              "CHECKBOX",
              "SCROLL",
              "SIGNIN_WRAP"
            ],
            "example": "BUTTON"
          },
          "sessionId": {
            "type": "string",
            "description": "Optional session ID",
            "example": "550e8400-e29b-41d4-a716-446655440001"
          },
          "userId": {
            "type": "string",
            "description": "Optional user ID",
            "example": "user123"
          },
          "email": {
            "type": "string",
            "description": "Optional email address",
            "example": "e2e-test-recipient+click-docs@propper.ai"
          },
          "identityAssertion": {
            "description": "Identity assertion for proof of acceptance",
            "allOf": [
              {
                "$ref": "#/components/schemas/IdentityAssertionDto"
              }
            ]
          },
          "identityAssertions": {
            "description": "Identity assertions array for proof of acceptance",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IdentityAssertionDto"
            }
          },
          "variant": {
            "type": "string",
            "description": "Optional variant identifier",
            "example": "A"
          },
          "capturedHtml": {
            "type": "string",
            "description": "Captured HTML of the page the content was shown on, for evidence generation",
            "example": "<div class=\"propper-modal\">...</div>"
          },
          "templateSnapshot": {
            "type": "object",
            "description": "Template snapshot (HTML + CSS) for screenshot generation",
            "example": {
              "html": "<div>...</div>",
              "css": ".modal { ... }"
            }
          },
          "browserInfo": {
            "type": "object",
            "description": "Browser information for screenshot generation",
            "example": {
              "userAgent": "Mozilla/5.0...",
              "viewport": {
                "width": 1920,
                "height": 1080
              }
            }
          },
          "metadata": {
            "type": "object",
            "description": "Additional metadata. `locale` must be the locale the content was rendered with (the `locale` the render API returned); when it is omitted the checksum is checked against the default locale (en-US, then en, then the first locale the deployment has), so a checksum rendered for another locale is rejected with 422 `CLICK_CHECKSUM_MISMATCH`. Also accepts optional container dimensions of the page the content was shown in.",
            "example": {
              "locale": "en-US",
              "source": "mobile-app",
              "version": "1.2.3",
              "containerDimensions": {
                "width": 800,
                "height": 600
              },
              "verificationSessionId": "550e8400-e29b-41d4-a716-446655440003",
              "verificationToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
            }
          }
        },
        "required": [
          "templateVersionId",
          "deploymentId",
          "checksum",
          "consentMethod"
        ]
      },
      "AcceptConsentResponseDto": {
        "type": "object",
        "properties": {
          "receiptId": {
            "type": "string",
            "description": "Receipt ID for the acceptance",
            "example": "550e8400-e29b-41d4-a716-446655440002"
          },
          "acceptedAt": {
            "type": "string",
            "description": "Timestamp of acceptance in ISO 8601 format",
            "example": "2024-01-15T10:30:00.000Z"
          },
          "message": {
            "type": "string",
            "description": "Success message",
            "example": "Acceptance recorded successfully"
          },
          "evidenceStatus": {
            "type": "string",
            "enum": [
              "pending",
              "complete",
              "failed"
            ],
            "description": "State of the evidence for this acceptance. Evidence is produced asynchronously, so a new acceptance is pending; read the receipt for complete or failed.",
            "example": "pending"
          }
        },
        "required": [
          "receiptId",
          "acceptedAt",
          "message",
          "evidenceStatus"
        ]
      },
      "VariantAssignmentDto": {
        "type": "object",
        "properties": {
          "requestedDeploymentId": {
            "type": "string",
            "description": "Deployment ID the caller asked about.",
            "example": "c54f4b8c-d36d-4670-855d-f454c8d3b7a8"
          },
          "assignedDeploymentId": {
            "type": "string",
            "description": "Deployment the user should be shown. Same as `requestedDeploymentId` when there are no siblings for this route, otherwise the bucketed sibling.",
            "example": "c54f4b8c-d36d-4670-855d-f454c8d3b7a8"
          },
          "variant": {
            "type": "string",
            "description": "Variant label of the assigned deployment (for example `control`). Null when the deployment has no variant set.",
            "example": "control",
            "nullable": true
          },
          "matchedRequested": {
            "type": "boolean",
            "description": "Whether the assigned deployment is the one that was requested.",
            "example": true
          },
          "siblingCount": {
            "type": "integer",
            "description": "Total number of sibling deployments considered in the bucket.",
            "example": 2
          }
        },
        "required": [
          "requestedDeploymentId",
          "assignedDeploymentId",
          "variant",
          "matchedRequested",
          "siblingCount"
        ]
      },
      "ExperienceMetadataDto": {
        "type": "object",
        "properties": {
          "requireIdentity": {
            "type": "boolean",
            "description": "Whether the experience requires user identity verification",
            "example": false
          },
          "identityMethods": {
            "description": "List of allowed identity verification methods",
            "example": [
              "email",
              "sms"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "displayMode": {
            "type": "string",
            "description": "Display mode for the experience",
            "example": "modal",
            "enum": [
              "modal",
              "inline",
              "banner",
              "wall"
            ]
          },
          "templateType": {
            "type": "string",
            "description": "Template type that determines behavior and constraints",
            "example": "clickwrap",
            "enum": [
              "clickwrap",
              "terms",
              "privacy"
            ]
          },
          "allowedConsentMethods": {
            "description": "Allowed consent methods for this template type",
            "example": [
              "CLICK",
              "CHECKBOX"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "defaultConsentMethod": {
            "type": "string",
            "description": "Default consent method for this template type",
            "example": "CLICK"
          },
          "allowedRenderModes": {
            "description": "Allowed render modes for this template type",
            "example": [
              "inline",
              "modal",
              "banner",
              "wall"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "policyFlags": {
            "type": "object",
            "description": "Policy flags that control template behavior",
            "example": {
              "requireScroll": false,
              "blockUntilAssent": true,
              "doubleCheckbox": false
            }
          },
          "format": {
            "type": "string",
            "description": "Format of the served content",
            "example": "html",
            "enum": [
              "html"
            ]
          },
          "additional": {
            "type": "object",
            "description": "Additional metadata fields",
            "example": {
              "customField": "value"
            }
          }
        },
        "required": [
          "requireIdentity",
          "identityMethods",
          "displayMode",
          "templateType",
          "allowedConsentMethods",
          "defaultConsentMethod",
          "allowedRenderModes",
          "policyFlags"
        ]
      },
      "ExperienceDto": {
        "type": "object",
        "properties": {
          "templateId": {
            "type": "string",
            "description": "Unique template identifier",
            "example": "123e4567-e89b-12d3-a456-426614174000"
          },
          "versionId": {
            "type": "string",
            "description": "Template version identifier",
            "example": "456e7890-e89b-12d3-a456-426614174001"
          },
          "deploymentId": {
            "type": "string",
            "description": "Deployment identifier",
            "example": "789e1234-e89b-12d3-a456-426614174002"
          },
          "title": {
            "type": "string",
            "description": "Human-readable title of the experience",
            "example": "Terms of Service"
          },
          "content": {
            "type": "string",
            "description": "HTML content of the experience",
            "example": "<div class=\"terms\">...</div>"
          },
          "checksum": {
            "type": "string",
            "description": "SHA-256 (hex) of `content`, exactly as served. Send it back as the checksum when recording the acceptance.",
            "example": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
          },
          "locale": {
            "type": "string",
            "description": "Locale of the content",
            "example": "en"
          },
          "variant": {
            "type": "string",
            "description": "A/B test variant identifier",
            "example": "control",
            "nullable": true
          },
          "metadata": {
            "description": "Experience metadata",
            "allOf": [
              {
                "$ref": "#/components/schemas/ExperienceMetadataDto"
              }
            ]
          },
          "cacheKey": {
            "type": "string",
            "description": "Cache key used for this response",
            "example": "site123|production|example.com|/terms|en|null"
          }
        },
        "required": [
          "templateId",
          "versionId",
          "deploymentId",
          "title",
          "content",
          "checksum",
          "locale",
          "variant",
          "metadata",
          "cacheKey"
        ]
      }
    }
  }
}