{
  "openapi": "3.1.0",
  "info": {
    "title": "Click Render API",
    "version": "1.0",
    "description": "The Propper Click Render API serves the consent and clickwrap agreement a deployment shows, as JSON, with the checksum to send back on accept.\nYour backend calls this API with an OAuth token to fetch the agreement it shows to the user; there is no browser SDK.\n\n---\n\n## Base URL\n\n`https://api.propper.ai/v1/click/render`\n\n## Authentication\n\nOAuth 2.0 Bearer token:\n\n```\nAuthorization: Bearer <access_token>\n```\n\n## OAuth Scopes\n\n- `click:admin`: Full administrative access\n- `click:read`: Read-only access to rendered experiences\n\n## Key Endpoints\n\n- **Render**: Fetch rendered consent experiences by deployment key\n\n---\n\n## Request correlation\n\nEvery response (success and error) includes an `x-request-id` header (a UUID) and a `traceparent` header (W3C Trace Context). Error bodies also carry the same id as `requestId`. Quote `x-request-id` when contacting support to pinpoint the exact request, and use it to correlate the API with your own logs. Send your own `traceparent` to tie a multi-call workflow under one trace.\n\n---\n\n## Errors\n\nEvery error response has the same JSON body:\n\n```json\n{\n  \"errorCode\": \"CLICK_VALIDATION_FAILED\",\n  \"message\": \"Request validation failed\",\n  \"requestId\": \"0b6f3a52-9a44-4f4b-9c1e-6a1f0e0f7c11\",\n  \"details\": [\n    { \"field\": \"name\", \"message\": \"name must be a string\", \"code\": \"isString\" }\n  ]\n}\n```\n\n- `errorCode` is a stable code you can branch on. The HTTP status says the class of failure; the code says which one. New codes may be added, so treat an unknown code like the default code for its status.\n- `message` is a short explanation for a person. Do not parse it.\n- `requestId` is the same value as the `x-request-id` response header.\n- `details` appears only on validation failures (400 `CLICK_VALIDATION_FAILED`, and a 422 that names the field it rejects). Each entry names the `field`, what is wrong in `message`, and the rule in `code`. A server error (5xx) never carries `details`, and its `message` is generic.\n- `requiredEntitlement` appears only with 403 `ENTITLEMENT_REQUIRED` and names the entitlement your account needs, such as `click.access`.\n\n### Error codes\n\n| Code | Status | Meaning |\n| --- | --- | --- |\n| `CLICK_BAD_REQUEST` | 400 | The request is malformed or cannot be processed as sent. |\n| `CLICK_VALIDATION_FAILED` | 400 | A field of the request is invalid. `details` names each field and the rule it broke. |\n| `CLICK_UNAUTHORIZED` | 401 | The credentials are missing, invalid or expired. |\n| `CLICK_FORBIDDEN` | 403 | The credentials are valid but the token lacks the required scope, or the resource belongs to another organization. |\n| `CLICK_NOT_FOUND` | 404 | The resource does not exist in your organization. |\n| `CLICK_CONFLICT` | 409 | The request conflicts with the current state of a resource, such as a duplicate. |\n| `CLICK_UNPROCESSABLE` | 422 | The request is well formed but cannot be applied. |\n| `CLICK_RATE_LIMITED` | 429 | Too many requests. Retry after a pause. |\n| `CLICK_INTERNAL_ERROR` | 500 | An unexpected error on our side. Quote the `requestId` when contacting support. |\n| `CLICK_SERVICE_UNAVAILABLE` | 503 | The service is temporarily unavailable. Retry with backoff. |\n| `CLICK_DEPLOYMENT_NOT_FOUND` | 404 | No deployment with this ID exists in your organization. |\n| `CLICK_DEPLOYMENT_INACTIVE` | 404 | The deployment exists but is not active, so it serves nothing. |\n| `CLICK_CONTENT_MISSING` | 500 | The deployment has no content to serve. |\n| `CLICK_CONTENT_UNAVAILABLE` | 503 | The deployment's content is temporarily unavailable. Retry with backoff. |\n| `CLICK_RENDER_UPSTREAM_UNAVAILABLE` | 503 | Rendering is temporarily unavailable. Retry with backoff. |\n| `CLICK_ACCEPT_UPSTREAM_UNAVAILABLE` | 503 | Recording the acceptance is temporarily unavailable. Nothing was recorded. Retry with backoff. |\n| `CLICK_ACCEPT_OUTCOME_UNKNOWN` | 504 | The accept call timed out or dropped after the request may have reached the recorder, so 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. |\n| `CLICK_DASHBOARD_UPSTREAM_UNAVAILABLE` | 503 | The dashboard metrics are temporarily unavailable. Retry with backoff. |\n| `CLICK_CHECKSUM_MISMATCH` | 422 | The checksum sent with an acceptance is not the checksum of the content the deployment serves. Nothing is recorded. |\n| `CLICK_VERSION_NOT_SERVED` | 422 | The version named by an acceptance is not the version the deployment serves, nor one it served in the last 15 minutes. Nothing is recorded. |\n| `CLICK_DEPLOYMENT_HAS_REVISIONS` | 409 | A deployment with revisions is history that evidence points at: deactivate it instead of deleting it. |\n| `CLICK_NOTHING_CHANGED` | 409 | The draft equals the latest published version, so there is nothing to publish. |\n| `CLICK_VERSION_CONFLICT` | 409 | Another version was published while this one was being prepared. Review the new version and publish again. |\n| `CLICK_TEMPLATE_ARCHIVED` | 409 | The template is archived, so it cannot be published, edited or deployed. |\n| `CLICK_FIRST_PUBLISH_MUST_BE_MAJOR` | 422 | The first publish of a template is version 1.0.0 and must be a MAJOR. |\n| `CLICK_CONSPICUOUSNESS_ACK_REQUIRED` | 422 | The presentation changes were flagged, and publishing them as a PATCH needs a conspicuousness acknowledgment. |\n| `CLICK_REACCEPT_GATE_REQUIRED` | 422 | A MAJOR that follows an earlier version needs a re-acceptance gate: IMMEDIATE, BY_DEADLINE (with a future deadline) or NEXT_VISIT. |\n| `CLICK_GATE_NOT_APPLICABLE` | 422 | A re-acceptance gate, deadline or affected set applies only to a MAJOR that follows an earlier version. |\n| `CLICK_LINKED_DOCUMENT_UNREACHABLE` | 422 | A document linked from the template could not be fetched and hashed, so the version was not published. |\n| `CLICK_TEMPLATE_NOT_PUBLISHABLE` | 422 | The draft cannot be published, for example because it has no content in any locale. |\n| `CLICK_CONTENT_UNSAFE` | 422 | A body contains markup that would have to be removed, such as a script, an event handler or a tag outside the allowed set. Nothing was written; the message names what would be removed. |\n| `CLICK_DEPLOYMENT_SLOT_TAKEN` | 409 | A deployment already exists for this environment, domain, path and variant. |\n| `CLICK_REVISION_CONFLICT` | 409 | The deployment changed while this request was being applied. Read it again and retry. |\n| `CLICK_NOTHING_TO_CHANGE` | 409 | The deployment already serves that version, or already has those settings. |\n| `CLICK_VERSION_TEMPLATE_MISMATCH` | 409 | The version belongs to a different template than the deployment. |\n| `CLICK_IDEMPOTENCY_KEY_REUSED` | 422 | The `X-Idempotency-Key` was already used for a different request body. Nothing is recorded. |\n| `CLICK_DEPLOYMENT_ENVIRONMENT_LOCKED` | 409 | The deployment has recorded acceptances, so its environment cannot change. Create a new deployment for the other environment. |\n| `CLICK_RETURN_URL_INVALID` | 400 | The return URL is not allowed: it must use `https`, carry no credentials and be an allowed origin for the deployment. `details` names the reason. |\n| `CLICK_HOSTED_TYPE_UNSUPPORTED` | 422 | The hosted acceptance page serves static agreements only; this deployment's template is of another type. |\n| `CLICK_ACCEPTANCE_LINK_NOT_FOUND` | 404 | No acceptance link with this ID exists in your organization. |\n| `CLICK_ACCEPTANCE_LINK_COMPLETED` | 409 | The signer already accepted or declined through this link, so it can no longer be revoked. |\n| `CLICK_ACCEPTANCE_LINK_MINT_CONFLICT` | 409 | Another mint for the same deployment and signer is in progress. Retry the request. |\n| `ENTITLEMENT_REQUIRED` | 403 | Your account does not include Click. `requiredEntitlement` names the entitlement to add. This is the platform code every Propper API returns for a missing entitlement, so it has no `CLICK_` prefix. |",
    "contact": {
      "name": "Propper Support",
      "url": "https://propper.ai",
      "email": "support@propper.ai"
    }
  },
  "tags": [
    {
      "name": "Render",
      "description": "Fetch rendered consent experiences by deployment key"
    },
    {
      "name": "Variant",
      "description": "Assign an A/B test variant to a user"
    }
  ],
  "servers": [
    {
      "url": "https://api.propper.ai",
      "description": "Production server"
    }
  ],
  "security": [
    {
      "bearer": []
    }
  ],
  "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>`."
      }
    },
    "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"
        ]
      },
      "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",
              "null"
            ],
            "description": "Variant label of the assigned deployment (for example `control`). Null when the deployment has no variant set.",
            "example": "control"
          },
          "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",
              "null"
            ],
            "description": "A/B test variant identifier",
            "example": "control"
          },
          "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"
        ]
      }
    }
  },
  "paths": {
    "/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"
            ]
          }
        ]
      }
    }
  }
}