{
  "openapi": "3.1.0",
  "info": {
    "title": "Bolrach Push API",
    "version": "3.1.0",
    "description": "Multi-tenant notification delivery. PROVIDER_ACCEPTED never means device delivery, and provider-accepted remote push cannot be recalled."
  },
  "servers": [{"url": "https://api.bolrach.com/push/v1"}],
  "security": [{"bearerAuth": []}],
  "paths": {
    "/event-destination-kinds": {"get": {"operationId": "listEventDestinationKinds", "summary": "Destination kinds and how each is proven", "description": "Every native connector with its configuration fields (secret ones are encrypted and never returned), batch size and verification: production, emulator (proven against a local implementation of the protocol) or contract (proven against a server that checks the vendor's documented request).", "tags": ["Event streams"], "responses": {"200": {"description": "OK"}}}},
    "/event-destinations/{id}:test": {"post": {"operationId": "testEventDestination", "summary": "Run the connection test again", "description": "Calls the destination with the least intrusive request it offers (S3: a small marker object; Kafka: topic metadata; Kinesis: DescribeStreamSummary; BigQuery: tables.get with a column check; Snowflake: a zero-row SELECT; Segment/RudderStack: an identify for a test user; Amplitude/Mixpanel: an empty upload) and records the outcome.", "tags": ["Event streams"], "responses": {"200": {"description": "OK"}}, "parameters": [{"$ref": "#/components/parameters/Id"}]}},
    "/event-destinations/{id}/configuration": {"put": {"operationId": "updateEventDestinationConfiguration", "summary": "Replace credentials or settings", "description": "Secret fields that are left out (or sent as \"set\") keep their stored value. The new configuration must pass the connection test before it replaces the old one; the version increments and the change is audited.", "tags": ["Event streams"], "responses": {"200": {"description": "Updated and tested"}, "422": {"description": "Validation or connection test failed; nothing changed"}}, "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"configuration": {"type": "object"}, "reason": {"type": "string"}}, "required": ["configuration", "reason"]}}}}}},
    "/event-destinations/{id}/backfill": {"post": {"operationId": "backfillEventDestination", "summary": "Send history to a destination", "description": "Queues replay jobs of 10,000 events each from from_sequence (to to_sequence, default the latest), at most 100 jobs per call; the answer gives next_from_sequence when more remains.", "tags": ["Event streams"], "responses": {"202": {"description": "Queued"}}, "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"from_sequence": {"type": "integer", "minimum": 1}, "to_sequence": {"type": "integer"}, "event_types": {"type": "array", "items": {"type": "string"}}, "reason": {"type": "string"}}, "required": ["from_sequence", "reason"]}}}}}},
    "/event-sources": {"get": {"operationId": "listEventSources", "summary": "Inbound Segment and RudderStack sources", "description": "", "tags": ["Event streams"], "responses": {"200": {"description": "OK"}}}, "post": {"operationId": "createEventSource", "summary": "Create an inbound source", "description": "Returns a write key once. Point a Segment library (apiHost), a Segment Webhooks destination or a RudderStack HTTP destination at /sources/segment.", "tags": ["Event streams"], "responses": {"201": {"description": "Created; write_key shown once"}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"app_id": {"type": "string"}, "kind": {"type": "string", "enum": ["segment", "rudderstack"]}, "name": {"type": "string"}}, "required": ["kind", "name"]}}}}}},
    "/event-sources/{id}:revoke": {"post": {"operationId": "revokeEventSource", "summary": "Revoke a source's write key", "description": "", "tags": ["Event streams"], "responses": {"200": {"description": "OK"}}, "parameters": [{"$ref": "#/components/parameters/Id"}]}},
    "/sources/segment": {"post": {"operationId": "ingestSegment", "summary": "Segment-compatible ingestion", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/sources/segment/v1/batch": {"post": {"operationId": "ingestSegment_batch", "summary": "Segment-compatible ingestion (batch)", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/sources/segment/v1/track": {"post": {"operationId": "ingestSegment_track", "summary": "Segment-compatible ingestion (track)", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/sources/segment/v1/identify": {"post": {"operationId": "ingestSegment_identify", "summary": "Segment-compatible ingestion (identify)", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/sources/segment/v1/page": {"post": {"operationId": "ingestSegment_page", "summary": "Segment-compatible ingestion (page)", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/sources/segment/v1/screen": {"post": {"operationId": "ingestSegment_screen", "summary": "Segment-compatible ingestion (screen)", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/sources/segment/v1/group": {"post": {"operationId": "ingestSegment_group", "summary": "Segment-compatible ingestion (group)", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/sources/segment/v1/alias": {"post": {"operationId": "ingestSegment_alias", "summary": "Segment-compatible ingestion (alias)", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/sources/segment/v1/import": {"post": {"operationId": "ingestSegment_import", "summary": "Segment-compatible ingestion (import)", "description": "Segment's HTTP Tracking API. Basic auth with the source write key as the user (or Authorization: Bearer). track, page and screen become Push events (Segment e-commerce names map to Push names: Order Completed is order.placed); identify merges traits into the person's attributes; messageId makes every call idempotent.", "tags": ["Event streams"], "responses": {"200": {"description": "{\"success\": true} as Segment answers"}, "401": {"description": "Unknown or revoked write key"}}, "security": []}},
    "/installations/{id}/remote-config": {"get": {"operationId": "fetchRemoteConfig", "summary": "Fetch this device's configuration", "description": "Called by SDKs with the installation's own token. Device facts go in the query (app_version, locale, os_version, attr.<name>=...). Answers with an ETag; send If-None-Match to get 304 when nothing changed. Cache-Control max-age is the template's minimum fetch interval. Parameters bound to an experiment record one exposure per person.", "tags": ["Remote Config"], "responses": {"200": {"description": "version, values, etag"}, "304": {"description": "Not modified"}, "401": {"description": "Invalid installation token"}}, "parameters": [{"$ref": "#/components/parameters/Id"}], "security": [{"receiptToken": []}]}, "post": {"operationId": "fetchRemoteConfigWithContext", "summary": "Fetch with a JSON context", "description": "As GET, with {\"context\": {...}} in the body.", "tags": ["Remote Config"], "responses": {"200": {"description": "version, values, etag"}, "304": {"description": "Not modified"}}, "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"context": {"type": "object"}}}}}}, "security": [{"receiptToken": []}]}},
    "/apps/{id}/remote-config": {"get": {"operationId": "getRemoteConfig", "summary": "Published template, versions, history and fetch counts", "description": "", "tags": ["Remote Config"], "responses": {"200": {"description": "OK"}}, "parameters": [{"$ref": "#/components/parameters/Id"}]}},
    "/apps/{id}/remote-config/versions": {"post": {"operationId": "createRemoteConfigVersion", "summary": "Save a new template version", "description": "Validated before it is stored: types, condition references, experiment variants (people-assigned experiments of this app), segments of this app.", "tags": ["Remote Config"], "responses": {"201": {"description": "Saved"}, "422": {"description": "Template refused, with the reason"}}, "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"template": {"type": "object", "description": "{settings:{minimum_fetch_interval_seconds}, conditions:[{name, expression}], parameters:{name:{type, default, conditional:[{condition, value}], experiment:{experiment_id, variant_values}}}}. Expressions: all/any/not, {attr, op, value|values} with op eq, neq, in, not_in, contains, prefix, exists, gt, gte, lt, lte, semver_eq/gt/gte/lt/lte; {percent:{seed, from, to}}; {segment: <segment id>}."}, "description": {"type": "string"}}, "required": ["template"]}}}}}},
    "/apps/{id}/remote-config/versions/{version}:publish": {"post": {"operationId": "publishRemoteConfigVersion", "summary": "Publish a version", "description": "Live within 10 seconds on every API process.", "tags": ["Remote Config"], "responses": {"200": {"description": "OK"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "version", "in": "path", "required": true, "schema": {"type": "integer"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"reason": {"type": "string"}}, "required": ["reason"]}}}}}},
    "/apps/{id}/remote-config:rollback": {"post": {"operationId": "rollbackRemoteConfig", "summary": "Publish an earlier version again", "description": "", "tags": ["Remote Config"], "responses": {"200": {"description": "OK"}}, "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"version": {"type": "integer"}, "reason": {"type": "string"}}, "required": ["version", "reason"]}}}}}},
    "/apps/{id}/remote-config:evaluate": {"post": {"operationId": "evaluateRemoteConfig", "summary": "Values for a person or device, explained", "description": "Each value says whether it came from the default, a condition (named) or an experiment variant. A preview records nothing; record_exposures=true is the server-side fetch. Pass version to preview a draft.", "tags": ["Remote Config"], "responses": {"200": {"description": "OK"}}, "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"user_id": {"type": "string"}, "installation_id": {"type": "string"}, "context": {"type": "object"}, "version": {"type": "integer"}, "record_exposures": {"type": "boolean"}}}}}}}},
    "/apps/{id}/rate-limit": {"get": {"operationId": "getAppRateLimit", "summary": "The app's request allowance", "description": "Requests are charged at once to the API key, the tenant, the app and the plane (token buckets: a sustained rate per second and a burst). The answer says which plan or staff override sets each number. Every API response carries X-RateLimit-Limit, X-RateLimit-Burst, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 carries Retry-After and names the bucket that refused (scope, reason). A batch is charged one request per item; fan-out from one request to many devices is not charged as requests.", "tags": ["Limits"], "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Plan, source (plan, app_override or tenant_override) and the app, tenant and plane capacities", "content": {"application/json": {"schema": {"type": "object", "properties": {"app_id": {"type": "string"}, "plan": {"type": "string"}, "source": {"type": "string", "enum": ["plan", "app_override", "tenant_override"]}, "app": {"$ref": "#/components/schemas/RateCapacity"}, "tenant": {"$ref": "#/components/schemas/RateCapacity"}, "plane": {"$ref": "#/components/schemas/RateCapacity"}, "plans": {"type": "object", "additionalProperties": {"$ref": "#/components/schemas/RateCapacity"}}}}}}}, "404": {"description": "App not found"}}}},
    "/health": {"get": {"security": [], "operationId": "getHealth", "responses": {"200": {"description": "Public liveness: the process is up (never touches the database)"}}}},
    "/ready": {"get": {"security": [], "operationId": "getReady", "responses": {"200": {"description": "Ready: Postgres answered within 2 s"}, "503": {"description": "Not ready: Postgres did not answer"}}}},
    "/openapi.json": {"get": {"security": [], "operationId": "getOpenAPI", "responses": {"200": {"description": "OpenAPI 3.1 document"}}}},
    "/me": {"get": {"operationId": "getCaller", "responses": {"200": {"description": "Authenticated caller and bindings"}}}},
    "/messages": {"get": {"operationId": "listMessages", "summary": "List sent messages with delivery counts", "description": "The caller tenant's messages, newest first, with delivery counts. Dry runs are left out. Page with next_before and next_before_id. Requires push:messages:read; an app_id of another tenant answers 404.", "parameters": [{"name": "app_id", "in": "query", "required": false, "schema": {"type": "string", "format": "uuid"}, "description": "Only this app's messages"}, {"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 25}}, {"name": "before", "in": "query", "required": false, "schema": {"type": "string", "format": "date-time"}, "description": "next_before from the previous page"}, {"name": "before_id", "in": "query", "required": false, "schema": {"type": "string", "format": "uuid"}, "description": "next_before_id from the previous page; only with before"}], "responses": {"200": {"description": "One page of messages", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageList"}}}}, "403": {"description": "Missing push:messages:read"}, "404": {"description": "app_id not found in caller tenant"}, "422": {"description": "Invalid limit, cursor or app_id"}}}, "post": {"operationId": "sendMessage", "summary": "Accept a notification", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendRequest"}}}}, "responses": {"202": {"description": "Durably queued or scheduled"}, "200": {"description": "Idempotent replay or dry run"}, "422": {"description": "Validation or policy violation"}, "503": {"description": "Committed to the durable outbox but queue production is pending; retry with the same idempotency key"}}}},
    "/messages:send": {"post": {"operationId": "sendMessageCanonical", "summary": "Canonical send alias", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendRequest"}}}}, "responses": {"202": {"description": "Durably queued or scheduled"}, "200": {"description": "Idempotent replay or dry run"}}}},
    "/messages:send-batch": {"post": {"operationId": "sendMessageBatch", "summary": "Validate and durably accept an idempotent batch of up to 100 messages", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageBatchRequest"}}}}, "responses": {"202": {"description": "Every item accepted through a resumable batch job"}, "207": {"description": "Partial item results; accepted messages remain durable and safe to replay with the same batch key"}, "409": {"description": "Same batch key used with different content"}, "422": {"description": "Whole batch rejected before mutation because an item is invalid"}}}},
    "/apps/{id}/recurring-messages": {"get": {"operationId": "listRecurringMessages", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Calendar-aware recurring schedules for the bound application"}}}, "post": {"operationId": "createRecurringMessage", "summary": "Create an idempotent DST-aware recurring message schedule", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RecurringMessageRequest"}}}}, "responses": {"201": {"description": "Recurring schedule created"}, "200": {"description": "Idempotent replay"}, "409": {"description": "Same key used with different content"}, "422": {"description": "Invalid message or recurrence"}}}},
    "/recurring-messages/{id}": {"get": {"operationId": "getRecurringMessage", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Schedule state and immutable occurrence evidence"}, "404": {"description": "Not found in a bound application"}}}},
    "/recurring-messages/{id}:pause": {"post": {"operationId": "pauseRecurringMessage", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RecurringMessageStateRequest"}}}}, "responses": {"200": {"description": "Schedule paused and generation advanced, or exact replay returned"}, "409": {"description": "Schedule is not active or replay content differs"}}}},
    "/recurring-messages/{id}:resume": {"post": {"operationId": "resumeRecurringMessage", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RecurringMessageStateRequest"}}}}, "responses": {"200": {"description": "Schedule resumed and generation advanced, or exact replay returned"}, "409": {"description": "Schedule is not paused or replay content differs"}}}},
    "/recurring-messages/{id}:cancel": {"post": {"operationId": "cancelRecurringMessage", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RecurringMessageStateRequest"}}}}, "responses": {"200": {"description": "Future occurrences permanently canceled, or exact replay returned"}, "409": {"description": "Schedule is already terminal or replay content differs"}}}},
    "/message-stream-jobs": {"post": {"operationId": "createMessageStreamJob", "summary": "Create a resumable asynchronous message-ingestion job", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageStreamJobRequest"}}}}, "responses": {"201": {"description": "Open ingestion job created"}, "200": {"description": "Idempotent replay"}, "409": {"description": "Same key used with different content"}}}},
    "/message-stream-jobs/{id}": {"get": {"operationId": "getMessageStreamJob", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Monotonic job counters and immutable batch evidence"}, "404": {"description": "Job not found in caller tenant"}}}},
    "/message-stream-jobs/{id}/batches": {"post": {"operationId": "ingestMessageStreamBatch", "summary": "Stream a replay-safe batch as JSON or newline-delimited JSON", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "X-Bolrach-Batch-Key", "in": "header", "schema": {"type": "string", "maxLength": 200}, "description": "Required for application/x-ndjson"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageStreamBatchRequest"}}, "application/x-ndjson": {"schema": {"type": "string"}, "example": "{\"record_key\":\"event-1\",\"message\":{\"app_id\":\"00000000-0000-0000-0000-000000000000\",\"target\":{\"type\":\"user\",\"id\":\"user-1\"},\"title\":\"Hello\",\"body\":\"World\"}}\n"}}}, "responses": {"202": {"description": "Batch records durably accepted with per-record results"}, "409": {"description": "Replay mismatch or closed job"}, "422": {"description": "Whole batch rejected before mutation"}}}},
    "/message-stream-jobs/{id}:complete": {"post": {"operationId": "completeMessageStreamJob", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Job closed as completed, partial, or failed; terminal retries return the recorded state"}, "404": {"description": "Job not found in caller tenant"}}}},
    "/messages:validate": {"post": {"operationId": "validateMessage", "summary": "Validate without dispatch", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendRequest"}}}}, "responses": {"200": {"description": "Validation result"}, "422": {"description": "Request does not satisfy message or policy validation"}}}},
    "/messages:preview": {"post": {"operationId": "previewMessage", "summary": "Persist a deterministic no-provider policy and payload preview", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendRequest"}}}}, "responses": {"200": {"description": "Canonical APNs, FCM, and Web Push payload previews plus recipient policy decisions; no provider call occurs"}, "409": {"description": "Same preview key used with different content"}}}},
    "/messages:estimate": {"post": {"operationId": "estimateMessage", "summary": "Persist a deterministic no-provider audience and cost estimate", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendRequest"}}}}, "responses": {"200": {"description": "Sendable and suppressed recipient counts; cost remains null when no approved rate exists"}, "409": {"description": "Same estimate key used with different content"}}}},
    "/messages/{id}": {"get": {"operationId": "getMessage", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Tenant-scoped message state"}, "404": {"description": "Not found in caller tenant"}}}},
    "/messages/{id}:cancel": {"post": {"operationId": "cancelMessage", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Canceled before provider dispatch"}, "409": {"description": "Dispatch began; provider recall is not possible"}}}},
    "/messages/{id}:pause": {"post": {"operationId": "pauseMessage", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageControlRequest"}}}}, "responses": {"200": {"description": "Every still-unsent delivery paused and prior broker generations invalidated"}, "409": {"description": "Dispatch began; provider recall is not possible"}}}},
    "/messages/{id}:resume": {"post": {"operationId": "resumeMessage", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageControlRequest"}}}}, "responses": {"200": {"description": "Paused deliveries re-armed with the current dispatch generation"}, "409": {"description": "Message is not paused"}}}},
    "/messages/{id}:retry": {"post": {"operationId": "retryMessage", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageRetryRequest"}}}}, "responses": {"202": {"description": "Selected failed deliveries re-armed through accounted replay jobs"}, "409": {"description": "No selected delivery is safely retryable"}, "422": {"description": "Selection exceeds the 100-delivery safety bound"}}}},
    "/messages/{id}/trace": {"get": {"operationId": "getMessageTrace", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Delivery decisions and state trace"}}}},
    "/projects": {"get": {"operationId": "listProjects", "responses": {"200": {"description": "Projects"}}}, "post": {"operationId": "createProject", "responses": {"201": {"description": "Created"}}}},
    "/workspace-templates": {"get": {"operationId": "listWorkspaceTemplates", "responses": {"200": {"description": "Tenant-private workspace templates and current immutable publication pointers"}}}, "post": {"operationId": "createWorkspaceTemplate", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkspaceTemplateCreateRequest"}}}}, "responses": {"201": {"description": "Draft workspace template created"}, "409": {"description": "Template key already exists"}, "422": {"description": "Template metadata is invalid"}}}},
    "/workspace-templates/{id}": {"get": {"operationId": "getWorkspaceTemplate", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Template, immutable versions, publication request and decision evidence"}, "404": {"description": "Template not found in caller tenant"}}}},
    "/workspace-templates/{id}/versions": {"post": {"operationId": "createWorkspaceTemplateVersion", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkspaceTemplateVersionRequest"}}}}, "responses": {"201": {"description": "Immutable secret-free workspace template version created"}, "404": {"description": "Active template not found"}, "422": {"description": "Blueprint violates environment or secret-free configuration rules"}}}},
    "/workspace-template-versions/{id}:request-publication": {"post": {"operationId": "requestWorkspaceTemplatePublication", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkspaceTemplatePublicationRequest"}}}}, "responses": {"201": {"description": "Immutable template version awaits a distinct publishing actor"}, "409": {"description": "Version unavailable or already decided"}}}},
    "/workspace-template-publication-requests/{id}:approve": {"post": {"operationId": "approveWorkspaceTemplatePublication", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkspaceTemplatePublicationDecision"}}}}, "responses": {"200": {"description": "Distinct actor atomically moved the current published template pointer"}, "409": {"description": "Self-approval or non-pending decision rejected"}}}},
    "/workspace-template-publication-requests/{id}:reject": {"post": {"operationId": "rejectWorkspaceTemplatePublication", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkspaceTemplatePublicationDecision"}}}}, "responses": {"200": {"description": "Distinct actor rejected the immutable template version"}, "409": {"description": "Self-decision or non-pending decision rejected"}}}},
    "/workspace-templates/{id}:instantiate": {"post": {"operationId": "instantiateWorkspaceTemplate", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkspaceTemplateInstantiationRequest"}}}}, "responses": {"201": {"description": "Published blueprint atomically created one workspace and its secret-free application environments"}, "200": {"description": "Idempotent instantiation replay"}, "409": {"description": "Workspace slug or idempotency conflict"}}}},
    "/workspace-template-instantiations": {"get": {"operationId": "listWorkspaceTemplateInstantiations", "responses": {"200": {"description": "Append-only workspace-template instantiation evidence"}}}},
    "/apps": {"get": {"operationId": "listApps", "responses": {"200": {"description": "Applications"}}}, "post": {"operationId": "createApp", "responses": {"201": {"description": "Created"}}}},
    "/apps/{id}": {"get": {"operationId": "getApp", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Application"}}}, "patch": {"operationId": "updateApp", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Updated"}}}},
    "/apps/{id}/preference-centre": {"get": {"operationId": "listPreferenceCentreVersions", "summary": "List immutable preference-centre versions", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Newest-first immutable preference-centre configurations"}}}, "put": {"operationId": "publishPreferenceCentreVersion", "summary": "Publish a new immutable hosted and embeddable preference-centre version", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreferenceCentreRequest"}}}}, "responses": {"201": {"description": "Immutable version published"}, "200": {"description": "Exact idempotent replay"}, "409": {"description": "Idempotency mismatch"}, "422": {"description": "Unsafe or invalid configuration"}}}},
    "/apps/{id}/preference-compliance-policy": {"get": {"operationId": "getPreferenceCompliancePolicy", "summary": "Get the application evidence-retention policy", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Effective consent and preference-access evidence retention policy"}}}, "put": {"operationId": "updatePreferenceCompliancePolicy", "summary": "Version-fence and update future evidence-retention windows", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreferenceCompliancePolicyRequest"}}}}, "responses": {"200": {"description": "Policy updated or exact idempotent replay returned"}, "409": {"description": "State-version or idempotency conflict"}, "422": {"description": "Retention policy outside governed bounds"}}}},
    "/apps/{id}/preference-legal-holds": {"get": {"operationId": "listPreferenceLegalHolds", "summary": "List application and recipient legal holds", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Newest-first legal-hold ledger"}}}, "post": {"operationId": "createPreferenceLegalHold", "summary": "Create an application-wide or recipient-scoped legal hold", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreferenceLegalHoldRequest"}}}}, "responses": {"201": {"description": "Legal hold created with immutable evidence"}, "200": {"description": "Exact idempotent replay"}, "404": {"description": "Application or recipient not found"}, "409": {"description": "Idempotency conflict"}, "422": {"description": "Invalid legal authority, review, or expiry"}}}},
    "/preference-legal-holds/{id}:release": {"post": {"operationId": "releasePreferenceLegalHold", "summary": "Release an active legal hold with immutable reason evidence", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreferenceLegalHoldReleaseRequest"}}}}, "responses": {"200": {"description": "Legal hold released or exact idempotent replay returned"}, "404": {"description": "Legal hold not visible to this credential"}, "409": {"description": "Hold state or idempotency conflict"}, "422": {"description": "Invalid release reason"}}}},
    "/apps/{id}/users/{user}/preference-access-grants": {"post": {"operationId": "issuePreferenceAccessGrant", "summary": "Issue a recipient-bound signed magic link", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreferenceAccessGrantRequest"}}}}, "responses": {"201": {"description": "Access grant and fragment-token magic URL issued; customer manages delivery"}, "200": {"description": "Exact replay returns the same deterministic signed token"}, "409": {"description": "No published centre or idempotency mismatch"}}}},
    "/preference-access-grants/{id}/revoke": {"post": {"operationId": "revokePreferenceAccessGrant", "summary": "Immediately revoke a recipient preference link", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreferenceAccessRevokeRequest"}}}}, "responses": {"200": {"description": "Grant revoked with append-only evidence"}, "409": {"description": "Grant is no longer active or replay content differs"}}}},
    "/preference-centre/state": {"get": {"security": [{"preferenceAccess": []}], "operationId": "getRecipientPreferenceState", "summary": "Load recipient controls through a signed access grant", "responses": {"200": {"description": "Version-bound centre configuration and current recipient state", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreferenceState"}}}}, "401": {"description": "Grant invalid, expired, revoked, or exhausted"}, "403": {"description": "Origin is not allowed"}}}, "put": {"security": [{"preferenceAccess": []}], "operationId": "updateRecipientPreferenceState", "summary": "Atomically update recipient controls with optimistic concurrency", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreferenceStatePatch"}}}}, "responses": {"200": {"description": "Change applied or exact replay returned"}, "202": {"description": "Double-opt-in confirmation queued through a verified destination"}, "409": {"description": "State version or idempotency conflict"}, "422": {"description": "Invalid control or confirmation delivery unavailable"}}}, "options": {"security": [], "responses": {"204": {"description": "Exact-origin CORS preflight"}}}},
    "/preference-centre/confirm": {"post": {"security": [{"preferenceConfirmation": []}], "operationId": "confirmRecipientPreferenceChange", "summary": "Apply a separately signed double-opt-in confirmation", "responses": {"200": {"description": "Stored version-fenced change confirmed or exact confirmation replay"}, "401": {"description": "Confirmation token invalid"}, "409": {"description": "Recipient state changed after confirmation request"}, "410": {"description": "Confirmation expired"}}}, "options": {"security": [], "responses": {"204": {"description": "Exact-origin CORS preflight"}}}},
    "/preference-centre/export": {"get": {"security": [{"preferenceAccess": []}], "operationId": "exportRecipientPreferenceProof", "summary": "Download recipient state and append-only consent/access evidence", "responses": {"200": {"description": "JSON proof excluding secrets and raw network identifiers"}, "401": {"description": "Grant invalid, expired, revoked, or exhausted"}}}, "options": {"security": [], "responses": {"204": {"description": "Exact-origin CORS preflight"}}}},
    "/apps/{id}/environment-snapshots": {"get": {"operationId": "listEnvironmentSnapshots", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Immutable secret-free configuration snapshots and source generations"}}}, "post": {"operationId": "createEnvironmentSnapshot", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentSnapshotRequest"}}}}, "responses": {"201": {"description": "Immutable current or configuration-as-code snapshot created"}, "409": {"description": "Idempotency key reused with different configuration"}, "422": {"description": "Unsafe, secret-shaped, or invalid configuration"}}}},
    "/apps/{id}:clone": {"post": {"operationId": "cloneEnvironment", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentCloneRequest"}}}}, "responses": {"201": {"description": "Development, preview, or staging clone created in enforced sandbox mode without credentials or recipient data"}, "200": {"description": "Idempotent clone replay"}, "409": {"description": "Target or idempotency conflict"}}}},
    "/environment-promotions": {"get": {"operationId": "listEnvironmentPromotions", "responses": {"200": {"description": "Tenant-scoped pending and decided promotion ledger"}}}, "post": {"operationId": "requestEnvironmentPromotion", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentPromotionRequest"}}}}, "responses": {"201": {"description": "Generation-bound promotion awaiting a distinct approver"}, "200": {"description": "Idempotent promotion replay"}, "422": {"description": "No change or invalid environment direction"}}}},
    "/environment-promotions/{id}:approve": {"post": {"operationId": "approveEnvironmentPromotion", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentPromotionDecision"}}}}, "responses": {"200": {"description": "Distinct actor atomically applied the immutable snapshot at the expected target generation"}, "409": {"description": "Requester attempted approval, state changed, or target generation drifted"}}}},
    "/environment-promotions/{id}:reject": {"post": {"operationId": "rejectEnvironmentPromotion", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentPromotionDecision"}}}}, "responses": {"200": {"description": "Distinct actor rejected the immutable promotion request"}, "409": {"description": "Requester attempted decision or promotion is no longer pending"}}}},
    "/apps/{id}/vapid": {"get": {"security": [], "operationId": "getVapidKey", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Public VAPID key"}}}},
    "/apps/{id}/vapid/rotate": {"post": {"operationId": "rotateVapidKey", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Rotated and activated"}, "202": {"description": "Validated encrypted candidate awaits a distinct approver"}}}},
    "/apps/{id}/credentials/fcm": {"put": {"operationId": "putFCMCredentials", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Encrypted, validated, and activated"}, "202": {"description": "Validated encrypted candidate awaits a distinct approver"}}}},
    "/apps/{id}/credentials/{provider}": {"delete": {"operationId": "revokeProviderCredential", "responses": {"200": {"description": "Credential revoked: out of service, its secret destroyed (fcm, apns, hms, adm or webpush)"}, "404": {"description": "No credential of that provider to revoke"}}}},
    "/apps/{id}/credentials/apns": {"put": {"operationId": "putAPNsCredentials", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Encrypted, validated, and activated"}, "202": {"description": "Validated encrypted candidate awaits a distinct approver"}}}},
    "/apps/{id}/credentials/hms": {"put": {"operationId": "putHMSCredentials", "summary": "Huawei Push Kit credential: AppGallery Connect app id and client secret", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["app_id", "client_secret"], "properties": {"app_id": {"type": "string", "pattern": "^[0-9]{5,20}$"}, "client_secret": {"type": "string", "writeOnly": true}}}}}}, "responses": {"200": {"description": "Checked with Huawei, encrypted, and activated"}, "202": {"description": "Validated encrypted candidate awaits a distinct approver"}, "422": {"description": "Huawei refused the credential"}}}},
    "/apps/{id}/credentials/adm": {"put": {"operationId": "putADMCredentials", "summary": "Amazon Device Messaging credential: Login with Amazon client id, secret and region", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["client_id", "client_secret"], "properties": {"client_id": {"type": "string"}, "client_secret": {"type": "string", "writeOnly": true}, "region": {"type": "string", "enum": ["na", "eu", "fe"], "default": "na"}}}}}}, "responses": {"200": {"description": "Checked with Amazon, encrypted, and activated"}, "202": {"description": "Validated encrypted candidate awaits a distinct approver"}, "422": {"description": "Amazon refused the credential"}}}},
    "/plans": {"get": {"operationId": "listPlans", "summary": "Free and pay as you go: the free allowance of monthly active users, throughput, and what every plan includes", "security": [], "responses": {"200": {"description": "Plan catalogue"}}}},
    "/plan": {"get": {"operationId": "getTenantPlan", "summary": "This tenant's plan and this month's reach against it", "responses": {"200": {"description": "Plan, people reached this month against the free allowance, how many are billable, web subscribers, and whether new people are held back (free tier only)"}}}},
    "/integrations/shopify/connect": {"post": {"operationId": "connectShopifyStore", "summary": "Start connecting a Shopify store to a Push app: answers the Shopify approval URL (15 minutes)", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["app_id", "shop"], "properties": {"app_id": {"type": "string"}, "shop": {"type": "string", "description": "my-store or my-store.myshopify.com"}}}}}}, "responses": {"200": {"description": "authorize_url"}, "503": {"description": "The Shopify app is not configured on this server"}}}},
    "/integrations/shopify/callback": {"get": {"operationId": "shopifyOAuthCallback", "summary": "Shopify's signed OAuth redirect (not called directly)", "security": [], "responses": {"302": {"description": "Connected; back to the Push console"}, "400": {"description": "Not signed by Shopify, or the request expired"}}}},
    "/integrations/shopify/webhooks": {"post": {"operationId": "shopifyWebhook", "summary": "Shopify webhooks, signed with the app secret (not called directly): orders, checkouts, products, inventory, uninstall and the privacy topics", "security": [], "responses": {"200": {"description": "Accepted"}, "401": {"description": "Not signed by Shopify"}}}},
    "/integrations/shopify/connections": {"get": {"operationId": "listShopifyConnections", "summary": "A Push app's connected Shopify stores and pending privacy requests (never a token)", "parameters": [{"name": "app_id", "in": "query", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Stores"}}}},
    "/integrations/shopify/connections/{id}": {"delete": {"operationId": "disconnectShopifyStore", "summary": "Disconnect a store: its token is destroyed and its events stop", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Disconnected"}}}},
    "/integrations/shopify/proxy/bolrach-push-sw.js": {"get": {"operationId": "shopifyProxyServiceWorker", "summary": "The service worker a Shopify storefront registers through the app proxy", "security": [], "responses": {"200": {"description": "JavaScript"}}}},
    "/apps/{id}/stats": {"get": {"operationId": "getAppStats", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Application statistics"}}}},
    "/apps/{id}/insights": {"get": {"operationId": "getAppInsights", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Delivery analytics with honest state separation"}}}},
    "/apps/{id}/installations": {"get": {"operationId": "listInstallations", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Installations"}}}},
    "/apps/{id}/sdk-health": {"get": {"operationId": "listSDKHealth", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Latest secret-free SDK health evidence and stale/missing counts for active installations"}}}},
    "/apps/{id}/sdk-configuration": {"get": {"operationId": "listSDKConfiguration", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Immutable SDK configuration versions and active publication pointer"}}}},
    "/apps/{id}/sdk-configuration/versions": {"post": {"operationId": "createSDKConfigurationVersion", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SDKConfigurationRequest"}}}}, "responses": {"201": {"description": "Immutable secret-free SDK configuration version created"}, "409": {"description": "Identical configuration or concurrent version conflict"}, "422": {"description": "Unsafe or invalid SDK configuration"}}}},
    "/apps/{id}/sdk-configuration/versions/{version}:publish": {"post": {"operationId": "publishSDKConfigurationVersion", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}], "responses": {"200": {"description": "SDK configuration publication pointer moved atomically"}, "409": {"description": "Production publishing actor must differ from creator"}}}},
    "/apps/{id}/deliveries": {"get": {"operationId": "listDeliveries", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Provider and device delivery states"}}}},
    "/apps/{id}/keys": {"post": {"operationId": "createAppKey", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Key returned once"}}}},
    "/installations": {"post": {"security": [], "operationId": "registerInstallation", "parameters": [{"$ref": "#/components/parameters/AppHeader"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InstallationRequest"}}}}, "responses": {"200": {"description": "Idempotently registered installation and receipt token"}, "401": {"description": "identity_token_required, identity_token_invalid, identity_token_expired or identity_token_replayed, when user_id is sent from a client"}}}},
    "/installations/{id}": {"patch": {"security": [{"receiptToken": []}], "operationId": "updateInstallation", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/AppHeader"}], "responses": {"200": {"description": "Identity, permission, capability, or version updated"}, "401": {"description": "identity_token_required, identity_token_invalid, identity_token_expired or identity_token_replayed (identity verification required)"}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InstallationUpdate"}}}}}, "delete": {"security": [{"receiptToken": []}], "operationId": "revokeInstallation", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/AppHeader"}], "responses": {"200": {"description": "Installation and subscriptions revoked"}}}},
    "/apps/{id}/identity-verification": {"get": {"operationId": "getIdentityVerification", "summary": "Identity verification mode and key ids", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Mode and key ids (never secrets)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityVerification"}}}}}}, "patch": {"operationId": "setIdentityVerification", "summary": "Set identity verification to report or required", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["mode"], "properties": {"mode": {"type": "string", "enum": ["report", "required"]}}}}}}, "responses": {"200": {"description": "Mode saved and audited"}}}},
    "/apps/{id}/identity-keys:rotate": {"post": {"operationId": "rotateIdentityKey", "summary": "Create a new identity key (secret returned once)", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "New identity key; its secret is returned once. The previous key keeps verifying until the next rotation"}, "202": {"description": "Candidate awaits a distinct approver"}}}},
    "/installations/{id}:negotiate": {"post": {"security": [{"receiptToken": []}], "operationId": "negotiateSDKCapabilities", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/AppHeader"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SDKNegotiationRequest"}}}}, "responses": {"200": {"description": "Compatible protocol and checksum-aware remote configuration, or an explicit fail-closed upgrade status"}, "409": {"description": "SDK identity does not match the registered installation"}}}},
    "/installations/{id}:rotate-token": {"post": {"security": [{"receiptToken": []}], "operationId": "rotateInstallationToken", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/AppHeader"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TokenRotationRequest"}}}}, "responses": {"200": {"description": "Provider token or Web Push subscription rotated with append-only hashed evidence"}, "409": {"description": "Idempotency key reused with different token material"}}}},
    "/installations/{id}/live-tokens": {"put": {"security": [{"receiptToken": []}], "operationId": "putLiveActivityToken", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LiveTokenRequest"}}}}, "responses": {"200": {"description": "ActivityKit update or push-to-start token envelope-encrypted with replay evidence"}, "409": {"description": "Idempotency or installation platform mismatch"}}}},
    "/installations/{id}/live-tokens:revoke": {"post": {"security": [{"receiptToken": []}], "operationId": "revokeLiveActivityTokens", "responses": {"200": {"description": "Installation-scoped ActivityKit tokens revoked"}}}},
    "/installations/{id}/live-event-subscriptions": {"put": {"security": [{"receiptToken": []}], "operationId": "putLiveEventSubscription", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LiveEventSubscriptionRequest"}}}}, "responses": {"200": {"description": "Identified user's explicit live event subscription updated"}}}},
    "/installations/{id}/live-events": {"post": {"security": [{"receiptToken": []}], "operationId": "recordLiveLifecycleEvent", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LiveLifecycleEventRequest"}}}}, "responses": {"202": {"description": "Append-only rendered, stale, dismissed, or ended lifecycle evidence recorded"}}}},
    "/installations/{id}/sdk-health": {"post": {"security": [{"receiptToken": []}], "operationId": "reportSDKHealth", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/AppHeader"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SDKHealthRequest"}}}}, "responses": {"202": {"description": "Append-only secret-free SDK health evidence accepted"}, "409": {"description": "Idempotency or negotiated-version mismatch"}}}},
    "/installations/{id}/preferences": {"get": {"security": [{"receiptToken": []}], "operationId": "getInstallationPreferences", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/AppHeader"}], "responses": {"200": {"description": "Installation-authorized explicit consent preferences, including anonymous state"}}}},
    "/installations/{id}/preferences/{category}": {"put": {"security": [{"receiptToken": []}], "operationId": "putInstallationPreference", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Category"}, {"$ref": "#/components/parameters/AppHeader"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InstallationPreferenceRequest"}}}}, "responses": {"200": {"description": "Replay-safe explicit preference and append-only consent evidence stored"}, "409": {"description": "Idempotency or optimistic state-version conflict"}}}},
    "/subscriptions": {"post": {"operationId": "upsertSubscription", "responses": {"201": {"description": "Subscription created"}, "200": {"description": "Token rotated"}}}},
    "/users": {"post": {"operationId": "upsertUser", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserProfileRequest"}}}}, "responses": {"201": {"description": "Versioned user profile created with immutable evidence"}, "200": {"description": "Profile updated or exact idempotent replay"}, "409": {"description": "Identity or idempotency conflict"}}}},
    "/apps/{id}/users/{user}": {"get": {"operationId": "getUserProfile", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Versioned user identity profile"}}}, "patch": {"operationId": "patchUserProfile", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserProfilePatch"}}}}, "responses": {"200": {"description": "Optimistic replay-safe profile update"}, "409": {"description": "Profile version, identifier, or idempotency conflict"}}}},
    "/apps/{id}/users/{user}:forget": {"post": {"operationId": "forgetUser", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserForgetRequest"}}}}, "responses": {"200": {"description": "Profile and device identifiers erased, devices detached, push credentials and live tokens erased, subscriptions disabled, and immutable proof retained"}, "409": {"description": "Idempotency conflict"}}}},
    "/apps/{id}/users/{user}/export": {"get": {"operationId": "exportUserIdentity", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Privacy export of profile, aliases, relationships, devices, preferences, consents, and evidence without credential material"}}}},
    "/apps/{id}/users/{user}/aliases": {"get": {"operationId": "listUserAliases", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Governed user aliases"}}}, "post": {"operationId": "addUserAlias", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserAliasRequest"}}}}, "responses": {"201": {"description": "Alias added with append-only evidence"}, "409": {"description": "Alias belongs to another user"}}}},
    "/apps/{id}/user-aliases/{alias}": {"delete": {"operationId": "removeUserAlias", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "alias", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"204": {"description": "Alias removed with append-only evidence"}}}},
    "/apps/{id}/users/{user}/relationships": {"get": {"operationId": "listUserRelationships", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Organization, household, account, application, and custom identity relationships"}}}, "post": {"operationId": "addUserRelationship", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserRelationshipRequest"}}}}, "responses": {"201": {"description": "Relationship activated with immutable evidence"}, "409": {"description": "Relationship conflicts or crosses applications"}}}},
    "/apps/{id}/user-relationships/{relationship}:end": {"post": {"operationId": "endUserRelationship", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "relationship", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConfirmedReason"}}}}, "responses": {"200": {"description": "Relationship ended without deleting history"}}}},
    "/apps/{id}/users/{user}/identity-events": {"get": {"operationId": "listUserIdentityEvents", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Append-only profile, alias, relationship, and device identity evidence"}}}},
    "/apps/{id}/users/{user}/devices": {"get": {"operationId": "getUserDeviceGraph", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Privacy-safe device and subscription-health graph without tokens or endpoint credentials"}}}},
    "/apps/{id}/users/{user}/devices/{installation}:transfer-anonymous-history": {"post": {"operationId": "transferAnonymousHistory", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"name": "installation", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityHistoryTransferRequest"}}}}, "responses": {"200": {"description": "Anonymous events attributed, future anonymous events linked, and the active installation attached with immutable replay evidence"}, "409": {"description": "Profile/session generation, owner, alias, or idempotency conflict"}}}},
    "/apps/{id}/users/{user}/devices/{installation}:detach": {"post": {"operationId": "detachUserDevice", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"name": "installation", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityDeviceLifecycleRequest"}}}}, "responses": {"200": {"description": "Device detached while preserving an anonymous active session and immutable ownership history"}, "409": {"description": "Session generation, owner, or idempotency conflict"}}}},
    "/apps/{id}/users/{user}/devices/{installation}:delete": {"post": {"operationId": "deleteUserDevice", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"name": "installation", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityDeviceLifecycleRequest"}}}}, "responses": {"200": {"description": "Device identifiers and push credentials erased or revoked; a non-deliverable tombstone and immutable proof remain"}, "409": {"description": "Session generation, owner, or idempotency conflict"}}}},
    "/apps/{id}/users/{user}/identity-cluster": {"get": {"operationId": "getUserIdentityCluster", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Canonical identity cluster, members, generations, and immutable merge/split history"}}}},
    "/apps/{id}/identity-merge-previews": {"post": {"operationId": "previewUserIdentityMerge", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityMergePreviewRequest"}}}}, "responses": {"201": {"description": "Expiring generation-bound merge preview with conflicts and impact"}, "409": {"description": "Identity conflict"}}}},
    "/apps/{id}/identity-merges": {"post": {"operationId": "executeUserIdentityMerge", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityOperationRequest"}}}}, "responses": {"200": {"description": "Reversible identity merge or exact replay"}, "409": {"description": "Preview expiry, generation drift, or idempotency conflict"}}}},
    "/apps/{id}/identity-split-previews": {"post": {"operationId": "previewUserIdentitySplit", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentitySplitPreviewRequest"}}}}, "responses": {"201": {"description": "Expiring generation-bound split preview with impact"}, "409": {"description": "Cluster membership conflict"}}}},
    "/apps/{id}/identity-splits": {"post": {"operationId": "executeUserIdentitySplit", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityOperationRequest"}}}}, "responses": {"200": {"description": "Non-destructive identity split or exact replay"}, "409": {"description": "Preview expiry, generation drift, or idempotency conflict"}}}},
    "/apps/{id}/identity-sync-sources": {"get": {"operationId": "listIdentitySyncSources", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "SCIM, CRM, and CDP identity sources with credentials excluded"}}}, "post": {"operationId": "createIdentitySyncSource", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentitySyncSourceRequest"}}}}, "responses": {"201": {"description": "Governed field mapping and vault reference created"}, "409": {"description": "Source identifier conflict"}, "422": {"description": "Unsafe or invalid source mapping"}}}},
    "/apps/{id}/identity-sync-sources/{source}": {"get": {"operationId": "getIdentitySyncSource", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Source cursor, mappings, and recent jobs without credential material"}, "404": {"description": "Source not found"}}}},
    "/apps/{id}/identity-sync-sources/{source}:pause": {"post": {"operationId": "pauseIdentitySyncSource", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "New jobs and SCIM mutations paused"}}}},
    "/apps/{id}/identity-sync-sources/{source}:resume": {"post": {"operationId": "resumeIdentitySyncSource", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Validated source resumed"}}}},
    "/apps/{id}/identity-sync-sources/{source}/jobs": {"post": {"operationId": "startIdentitySyncJob", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentitySyncJobRequest"}}}}, "responses": {"201": {"description": "Cursor-bound full or incremental job started"}, "200": {"description": "Exact job replay"}, "409": {"description": "Cursor, running-job, or idempotency conflict"}}}},
    "/identity-sync-jobs/{job}/records:batch": {"post": {"operationId": "ingestIdentitySyncBatch", "parameters": [{"name": "job", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentitySyncBatchRequest"}}}}, "responses": {"200": {"description": "Up to 500 records applied through independent savepoints with exact batch replay"}, "409": {"description": "Batch key or record conflict"}, "422": {"description": "Invalid batch"}}}},
    "/identity-sync-jobs/{job}:complete": {"post": {"operationId": "completeIdentitySyncJob", "parameters": [{"name": "job", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Cursor advanced atomically; full jobs reconcile missing links"}, "409": {"description": "Cursor changed"}}}},
    "/identity-sync-jobs/{job}": {"get": {"operationId": "getIdentitySyncJob", "parameters": [{"name": "job", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Job counters, batches, and outcome totals"}, "404": {"description": "Job not found"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/ServiceProviderConfig": {"get": {"operationId": "getSCIMServiceProviderConfig", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "RFC 7644 service capabilities"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/Schemas": {"get": {"operationId": "listSCIMSchemas", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "SCIM User and Group schemas"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/Schemas/{scim_id}": {"get": {"operationId": "getSCIMSchema", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "SCIM schema"}, "404": {"description": "Schema not found"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/ResourceTypes": {"get": {"operationId": "listSCIMResourceTypes", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "SCIM User and Group resource types"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/ResourceTypes/{scim_id}": {"get": {"operationId": "getSCIMResourceType", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "SCIM resource type"}, "404": {"description": "Resource type not found"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/Users": {"get": {"operationId": "listSCIMUsers", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Filtered and paginated SCIM Users"}, "400": {"description": "Unsupported filter or pagination"}}}, "post": {"operationId": "createSCIMUser", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/scim+json": {"schema": {"$ref": "#/components/schemas/SCIMUserRequest"}}}}, "responses": {"201": {"description": "SCIM User provisioned with append-only sync evidence"}, "200": {"description": "Exact replay"}, "409": {"description": "Identity or idempotency conflict"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/Users/{scim_id}": {"get": {"operationId": "getSCIMUser", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "SCIM User with ETag and groups"}, "404": {"description": "User not found"}}}, "put": {"operationId": "replaceSCIMUser", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/scim+json": {"schema": {"$ref": "#/components/schemas/SCIMUserRequest"}}}}, "responses": {"200": {"description": "SCIM User replaced under If-Match"}, "412": {"description": "ETag mismatch"}}}, "patch": {"operationId": "patchSCIMUser", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/scim+json": {"schema": {"$ref": "#/components/schemas/SCIMPatchRequest"}}}}, "responses": {"200": {"description": "SCIM PatchOp applied under If-Match"}, "412": {"description": "ETag mismatch"}}}, "delete": {"operationId": "deleteSCIMUser", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"204": {"description": "Source link deactivated and identity safely blocked or unlinked"}, "412": {"description": "ETag mismatch"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/Groups": {"get": {"operationId": "listSCIMGroups", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Filtered and paginated SCIM Groups"}}}, "post": {"operationId": "createSCIMGroup", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"required": true, "content": {"application/scim+json": {"schema": {"$ref": "#/components/schemas/SCIMGroupRequest"}}}}, "responses": {"201": {"description": "SCIM Group and exact memberships created"}, "409": {"description": "Group externalId conflict"}}}},
    "/apps/{id}/identity-sync-sources/{source}/scim/v2/Groups/{scim_id}": {"get": {"operationId": "getSCIMGroup", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "SCIM Group with ETag and members"}, "404": {"description": "Group not found"}}}, "put": {"operationId": "replaceSCIMGroup", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/scim+json": {"schema": {"$ref": "#/components/schemas/SCIMGroupRequest"}}}}, "responses": {"200": {"description": "SCIM Group and memberships replaced under If-Match"}, "412": {"description": "ETag mismatch"}}}, "patch": {"operationId": "patchSCIMGroup", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/scim+json": {"schema": {"$ref": "#/components/schemas/SCIMPatchRequest"}}}}, "responses": {"200": {"description": "SCIM Group PatchOp and filtered member removal applied"}, "412": {"description": "ETag mismatch"}}}, "delete": {"operationId": "deleteSCIMGroup", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "source", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "scim_id", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"204": {"description": "Group deactivated and memberships ended"}, "412": {"description": "ETag mismatch"}}}},
    "/apps/{id}/topics": {"get": {"operationId": "listTopics", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Topics"}}}, "post": {"operationId": "upsertTopic", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Topic saved"}}}},
    "/apps/{id}/topics/{key}/members/{user}": {"put": {"operationId": "addTopicMember", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Key"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Member added"}}}, "delete": {"operationId": "removeTopicMember", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Key"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Member removed"}}}},
    "/apps/{id}/users/{user}/preferences": {"get": {"operationId": "getPreferences", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Effective explicit preferences"}}}},
    "/apps/{id}/users/{user}/preferences/{category}": {"put": {"operationId": "putPreference", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"$ref": "#/components/parameters/Category"}], "responses": {"200": {"description": "Preference saved and audited"}}}},
    "/apps/{id}/users/{user}/consents": {"get": {"operationId": "getConsents", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Consent ledger"}}}, "post": {"operationId": "recordConsent", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"201": {"description": "Append-only consent evidence recorded"}}}},
    "/receipts": {"post": {"security": [{"receiptToken": []}], "operationId": "recordReceipt", "responses": {"200": {"description": "Authenticated monotonic device or engagement receipt"}, "409": {"description": "Invalid state transition"}}}},
    "/stream": {"get": {"security": [{"streamToken": []}], "operationId": "openInboxStream", "responses": {"200": {"description": "Server-sent event stream"}}}},
    "/webhooks": {"get": {"operationId": "listWebhooks", "responses": {"200": {"description": "Webhooks"}}}, "post": {"operationId": "createWebhook", "responses": {"201": {"description": "SSRF-validated webhook and signing secret"}}}},
    "/webhooks/{id}": {"delete": {"operationId": "deleteWebhook", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Deleted"}}}},
    "/webhooks/{id}/test": {"post": {"operationId": "testWebhook", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Test queued"}}}},
    "/templates": {"get": {"operationId": "listTemplates", "responses": {"200": {"description": "Templates with their rich content (image, buttons, deep link, per-locale variants, sample data)"}}}, "post": {"operationId": "publishTemplateVersion", "description": "Title, body and every content string may use Liquid-style logic: {% if %}/{% elsif %}/{% else %}, {% unless %}, {% case %}, {% for x in list %} with forloop, {% assign %}, {% capture %}, and filters (default, upcase, downcase, capitalize, truncate, money, number, date, plus, minus, times, round, join, size, first, last, sort, where, map, pluralize, replace, append, prepend, url_encode, escape). Syntax errors are refused with the line they are on.", "responses": {"201": {"description": "Immutable template version published"}, "422": {"description": "A template field does not parse (the message names the field and line)"}}}},
    "/templates:render": {"post": {"operationId": "renderTemplate", "summary": "Render a stored or inline template for one person and locale", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"app_id": {"type": "string", "format": "uuid"}, "template_id": {"type": "string", "format": "uuid"}, "title": {"type": "string"}, "body": {"type": "string"}, "content": {"type": "object"}, "variables": {"type": "object"}, "locale": {"type": "string"}, "user_id": {"type": "string", "description": "External or Push user id; their attributes become {{ user.* }}"}}}}}}, "responses": {"200": {"description": "The rendered message (title, body, url, image_url, actions), the locale used and warnings for variables that were missing"}, "422": {"description": "The template does not render (field, line and reason)"}}}},
    "/events": {"post": {"operationId": "ingestEvent", "summary": "Idempotently ingest a customer event", "responses": {"202": {"description": "Durably accepted"}}}},
    "/events:batch": {"post": {"operationId": "ingestEventBatch", "summary": "Ingest up to 100 events atomically", "responses": {"202": {"description": "Durably accepted"}}}},
    "/recipes": {"get": {"operationId": "listRecipes", "summary": "One-click journey recipes for shops and social apps, with their parameters and the events they read", "responses": {"200": {"description": "Recipe catalogue"}}}},
    "/event-catalog": {"get": {"operationId": "getEventCatalog", "summary": "The standard event schema (cart.updated, order.placed with items/amount/currency, product.viewed, post.liked, message.received, catalog.price_changed ...)", "responses": {"200": {"description": "Event catalogue"}}}},
    "/apps/{id}/recipes": {"get": {"operationId": "listAppRecipes", "summary": "Which recipes are enabled for an app", "responses": {"200": {"description": "Recipes with their journey and state"}}, "parameters": [{"$ref": "#/components/parameters/Id"}]}},
    "/apps/{id}/recipes/{key}:enable": {"post": {"operationId": "enableRecipe", "summary": "Create or update the recipe's journey with these parameters and publish it (idempotent)", "responses": {"200": {"description": "Published journey"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Key"}], "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string"}, "params": {"type": "object", "additionalProperties": {"type": "string"}}}}}}}}},
    "/apps/{id}/recipes/{key}:disable": {"post": {"operationId": "disableRecipe", "summary": "Pause the recipe's journey: nobody new enters, people in it finish", "responses": {"200": {"description": "Paused"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Key"}]}},
    "/apps/{id}/journeys": {"get": {"operationId": "listJourneys", "summary": "Journeys of an app with entered, active, completed, exited, goal met, messages and attributed revenue", "responses": {"200": {"description": "Journey summaries"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "days", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "maximum": 365, "default": 30}}]}},
    "/workflows/{id}/stats": {"get": {"operationId": "getJourneyStats", "summary": "Per-step counts, sends, opens, exit reasons and revenue for one journey", "responses": {"200": {"description": "Journey statistics"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "days", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "maximum": 365, "default": 30}}]}},
    "/apps/{id}/revenue": {"get": {"operationId": "getRevenue", "summary": "Revenue attributed to the messages that drove it (last touch, opened first, 7 days; journey goals credit their own run)", "responses": {"200": {"description": "Revenue report"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "days", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "maximum": 365, "default": 30}}]}},
    "/apps/{id}/users/{user}/watchers": {"get": {"operationId": "listWatchers", "summary": "A person's product watches (price drop, back in stock, wishlist)", "responses": {"200": {"description": "Watchers"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}]}},
    "/apps/{id}/users/{user}/watchers/{product}": {"put": {"operationId": "putWatcher", "summary": "Watch a product for a person", "responses": {"200": {"description": "Watching"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"name": "product", "in": "path", "required": true, "schema": {"type": "string"}}], "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "required": ["kinds"], "properties": {"kinds": {"type": "array", "items": {"type": "string", "enum": ["price_drop", "back_in_stock", "wishlist"]}}, "target_price": {"type": "number"}, "currency": {"type": "string"}, "product": {"type": "object"}}}}}}}, "delete": {"operationId": "deleteWatcher", "summary": "Stop watching a product (all kinds, or ?kind=)", "responses": {"200": {"description": "Removed"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"name": "product", "in": "path", "required": true, "schema": {"type": "string"}}]}},
    "/apps/{id}/users/{user}/mutes": {"get": {"operationId": "listMutes", "summary": "A person's mutes (group, thread or actor:<id>)", "responses": {"200": {"description": "Mutes"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}]}},
    "/apps/{id}/users/{user}/mutes/{key}": {"put": {"operationId": "putMute", "summary": "Mute a group, a thread or one actor for a person, optionally until a time", "responses": {"200": {"description": "Muted"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"$ref": "#/components/parameters/Key"}], "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "properties": {"until": {"type": "string", "format": "date-time"}}}}}}}, "delete": {"operationId": "deleteMute", "summary": "Unmute", "responses": {"200": {"description": "Unmuted"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"$ref": "#/components/parameters/Key"}]}},
    "/apps/{id}/users/{user}/badge": {"get": {"operationId": "getBadge", "summary": "Unread inbox count (a notification group counts once) and the latest groups", "responses": {"200": {"description": "Badge"}}, "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}]}},
    "/event-destinations": {"get": {"operationId": "listEventDestinations", "responses": {"200": {"description": "Bound destinations with encrypted configuration redacted and honest activation state"}}}, "post": {"operationId": "createEventDestination", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EventDestinationRequest"}}}}, "responses": {"201": {"description": "Executable signed HTTPS destination created; generated secret is shown once"}, "202": {"description": "External cloud or warehouse adapter recorded as pending_external, not falsely activated"}}}},
    "/event-destinations/{id}:pause": {"post": {"operationId": "pauseEventDestination", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Destination paused with an audited reason"}}}},
    "/event-destinations/{id}:resume": {"post": {"operationId": "resumeEventDestination", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Validated signed HTTPS destination resumed"}, "409": {"description": "Adapter is not executable or state is invalid"}}}},
    "/event-destinations/{id}:rotate-secret": {"post": {"operationId": "rotateEventDestinationSecret", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Signing secret envelope rotated and new secret shown once"}}}},
    "/event-destinations/{id}/deliveries": {"get": {"operationId": "listEventDestinationDeliveries", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Delivery, retry, dead-letter, response, cursor, and payload-checksum evidence"}}}},
    "/event-destinations/{id}/replays": {"post": {"operationId": "replayEventDestination", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EventReplayRequest"}}}}, "responses": {"202": {"description": "Confirmed bounded replay queued"}, "409": {"description": "Replay idempotency key reused with changed input"}}}},
    "/event-replays": {"get": {"operationId": "listEventReplays", "responses": {"200": {"description": "Caller-app-bound replay and backfill jobs"}}}},
    "/apps/{id}/event-stream": {"get": {"operationId": "listCanonicalEventStream", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Stable tenant sequence cursor, ordering key, schema version, and canonical payload"}}}},
    "/apps/{id}/event-schemas": {"get": {"operationId": "listEventSchemas", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Immutable versioned schemas and PII classifications"}}}},
    "/event-schemas": {"post": {"operationId": "createEventSchema", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EventSchemaRequest"}}}}, "responses": {"201": {"description": "New immutable active schema version; prior version retired"}}}},
    "/apps/{id}/inbox/feeds": {"get": {"operationId": "listInboxFeeds", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Inbox feeds"}}}, "post": {"operationId": "upsertInboxFeed", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Versioned feed configuration saved"}}}},
    "/inbox/notifications": {"get": {"security": [{"receiptToken": []}], "operationId": "listDeviceInboxNotifications", "parameters": [{"name": "installation_id", "in": "query", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"$ref": "#/components/parameters/InboxLimit"}, {"$ref": "#/components/parameters/InboxCursor"}, {"$ref": "#/components/parameters/InboxFeed"}, {"$ref": "#/components/parameters/InboxCategory"}, {"$ref": "#/components/parameters/InboxThreadKey"}, {"$ref": "#/components/parameters/InboxStatus"}, {"$ref": "#/components/parameters/InboxSearch"}, {"$ref": "#/components/parameters/InboxRevealSensitive"}], "responses": {"200": {"description": "Authenticated cursor-paginated device inbox, feed counts, unread count, and masked sensitive content"}, "422": {"description": "Invalid cursor or filter"}}}, "post": {"operationId": "createInboxNotification", "responses": {"202": {"description": "Inbox notification durably queued"}, "422": {"description": "Invalid or duplicate action declaration"}}}},
    "/apps/{id}/users/{user}/notifications": {"get": {"operationId": "listInboxNotifications", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"$ref": "#/components/parameters/InboxLimit"}, {"$ref": "#/components/parameters/InboxCursor"}, {"$ref": "#/components/parameters/InboxFeed"}, {"$ref": "#/components/parameters/InboxCategory"}, {"$ref": "#/components/parameters/InboxThreadKey"}, {"$ref": "#/components/parameters/InboxStatus"}, {"$ref": "#/components/parameters/InboxSearch"}, {"$ref": "#/components/parameters/InboxRevealSensitive"}], "responses": {"200": {"description": "Cursor-paginated user inbox with cross-device versioned state"}, "422": {"description": "Invalid cursor or filter"}}}},
    "/inbox/notifications/{id}:read": {"post": {"operationId": "markInboxRead", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Marked read with authoritative state version"}, "409": {"description": "Optimistic state conflict"}}}},
    "/inbox/notifications/{id}:unread": {"post": {"operationId": "markInboxUnread", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Marked unread with authoritative state version"}, "409": {"description": "Optimistic state conflict"}}}},
    "/inbox/notifications/{id}:archive": {"post": {"operationId": "archiveInboxNotification", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Archived with authoritative state version"}, "409": {"description": "Optimistic state conflict"}}}},
    "/inbox/notifications/{id}:restore": {"post": {"operationId": "restoreInboxNotification", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Restored with authoritative state version"}, "409": {"description": "Optimistic state conflict"}}}},
    "/inbox/notifications/{id}:snooze": {"post": {"operationId": "snoozeInboxNotification", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Snoozed until a validated future time"}, "409": {"description": "Optimistic state conflict"}}}},
    "/inbox/notifications/{id}:pin": {"post": {"operationId": "pinInboxNotification", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Pinned"}}}},
    "/inbox/notifications/{id}:unpin": {"post": {"operationId": "unpinInboxNotification", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Unpinned"}}}},
    "/inbox/notifications/{id}:save": {"post": {"operationId": "saveInboxNotification", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Saved"}}}},
    "/inbox/notifications/{id}:unsave": {"post": {"operationId": "unsaveInboxNotification", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Unsaved"}}}},
    "/inbox/notifications/{id}:delete": {"post": {"operationId": "deleteInboxNotification", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/OptionalIdempotencyKey"}], "requestBody": {"$ref": "#/components/requestBodies/InboxState"}, "responses": {"200": {"description": "Soft-deleted for this user"}}}},
    "/inbox/notifications:read-all": {"post": {"security": [{"receiptToken": []}], "operationId": "markAllInboxRead", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InboxReadAllRequest"}}}}, "responses": {"200": {"description": "Replay-safe mark-all result and remaining unread count"}}}},
    "/inbox/notifications/{id}:action": {"post": {"security": [{"bearerAuth": []}, {"receiptToken": []}], "operationId": "performInboxAction", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InboxActionRequest"}}}}, "responses": {"202": {"description": "Declared action accepted or identically replayed"}, "409": {"description": "Same action replay key used with different action or input"}, "422": {"description": "Action was not declared or replay key is missing"}}}},
    "/inbox/threads:mute": {"post": {"security": [{"bearerAuth": []}, {"receiptToken": []}], "operationId": "muteInboxThread", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InboxRelationRequest"}}}}, "responses": {"200": {"description": "Thread muted with authoritative state version"}, "409": {"description": "Optimistic state or replay conflict"}}}},
    "/inbox/threads:unmute": {"post": {"security": [{"bearerAuth": []}, {"receiptToken": []}], "operationId": "unmuteInboxThread", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InboxRelationRequest"}}}}, "responses": {"200": {"description": "Thread unmuted with authoritative state version"}, "409": {"description": "Optimistic state or replay conflict"}}}},
    "/inbox/objects:follow": {"post": {"security": [{"bearerAuth": []}, {"receiptToken": []}], "operationId": "followInboxObject", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InboxRelationRequest"}}}}, "responses": {"200": {"description": "Object followed with authoritative state version"}, "409": {"description": "Optimistic state or replay conflict"}}}},
    "/inbox/objects:unfollow": {"post": {"security": [{"bearerAuth": []}, {"receiptToken": []}], "operationId": "unfollowInboxObject", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InboxRelationRequest"}}}}, "responses": {"200": {"description": "Object unfollowed with authoritative state version"}, "409": {"description": "Optimistic state or replay conflict"}}}},
    "/inbox/attachments/{id}": {"get": {"security": [], "operationId": "downloadInboxAttachment", "parameters": [{"$ref": "#/components/parameters/Id"}, {"name": "notification_id", "in": "query", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "installation_id", "in": "query", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "expires", "in": "query", "required": true, "schema": {"type": "integer", "format": "int64"}}, {"name": "signature", "in": "query", "required": true, "schema": {"type": "string"}}], "responses": {"307": {"description": "Short-lived installation-bound redirect to the validated active asset"}, "401": {"description": "Grant invalid or expired"}, "404": {"description": "Attachment unavailable"}}}},
    "/workflows": {"get": {"operationId": "listWorkflows", "responses": {"200": {"description": "Workflows"}}}, "post": {"operationId": "upsertWorkflow", "responses": {"201": {"description": "Workflow shell saved"}}}},
    "/workflows/{id}": {"get": {"operationId": "getWorkflow", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Workflow and immutable version history"}}}, "patch": {"operationId": "updateWorkflow", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Mutable workflow name or pause state updated"}, "404": {"description": "Not found or archived"}}}, "delete": {"operationId": "archiveWorkflow", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"204": {"description": "Workflow archived"}, "409": {"description": "Active runs prevent archival"}}}},
    "/workflows/{id}/versions": {"post": {"operationId": "createWorkflowVersion", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Immutable validated version created"}, "409": {"description": "Idempotency mismatch"}}}},
    "/workflows/{id}/versions/{version}": {"get": {"operationId": "getWorkflowVersion", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}], "responses": {"200": {"description": "Exact immutable workflow-as-code specification and qualification state"}, "404": {"description": "Not found"}}}},
    "/workflows/{id}/versions/{version}:publish": {"post": {"operationId": "publishWorkflowVersion", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}], "responses": {"200": {"description": "Published"}, "409": {"description": "Four-eyes approval required for P0"}}}},
    "/workflows/{id}/versions/{version}:request-approval": {"post": {"operationId": "requestWorkflowApproval", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}], "responses": {"202": {"description": "Approval requested"}}}},
    "/workflows/{id}/versions/{version}:approve": {"post": {"operationId": "approveWorkflowVersion", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}], "responses": {"200": {"description": "Approved by a distinct authenticated subject"}}}},
    "/workflows/{id}:trigger": {"post": {"operationId": "triggerWorkflow", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"202": {"description": "Durable idempotent run queued"}}}},
    "/workflows/{id}/canvas": {"get": {"operationId": "getJourneyCanvas", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Latest revisioned visual journey canvas"}}}, "put": {"operationId": "saveJourneyCanvas", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "New optimistic-concurrency canvas revision saved"}, "409": {"description": "Revision conflict"}, "422": {"description": "Canvas saved with validation errors"}}}},
    "/workflows/{id}/canvas:validate": {"post": {"operationId": "validateJourneyCanvas", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Exact graph, layout, and workflow validation result"}}}},
    "/workflows/{id}/canvas:compile": {"post": {"operationId": "compileJourneyCanvas", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Valid canvas compiled idempotently to an immutable workflow version"}}}},
    "/workflows/{id}/canvas:simulate": {"post": {"operationId": "simulateJourneyCanvas", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Bounded deterministic trace with no external side effects"}}}},
    "/workflow-runs/{id}": {"get": {"operationId": "getWorkflowRun", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Run and step trace"}}}},
    "/workflow-runs/{id}:cancel": {"post": {"operationId": "cancelWorkflowRun", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Canceled"}}}},
    "/workflow-runs/{id}:approve": {"post": {"operationId": "approveWorkflowRun", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"202": {"description": "Distinct authenticated approver resumed run"}}}},
    "/segments": {"get": {"operationId": "listSegments", "responses": {"200": {"description": "Versioned audience segments, each with its current criteria (manual, or rules with match and rules)"}}}, "post": {"operationId": "createSegment", "responses": {"201": {"description": "Segment created"}}}},
    "/segments:preview": {"post": {"operationId": "previewSegment", "responses": {"200": {"description": "How many people and live push subscriptions a rules segment matches now"}, "422": {"description": "The rules do not compile"}}}},
    "/segments/{id}": {"delete": {"operationId": "deleteSegment", "responses": {"200": {"description": "Segment archived: gone from the list, no new campaign can target it"}, "404": {"description": "No such segment"}}}},
    "/segments/{id}/members": {"get": {"operationId": "listSegmentMembers", "description": "Who matches the segment at this moment; behaviour rules are evaluated against the events received so far. Page with limit (1-500) and after (the previous page next).", "responses": {"200": {"description": "Members, next cursor and evaluation time"}, "404": {"description": "Segment not found"}}}},
    "/segments/{id}/export": {"get": {"operationId": "exportSegment", "description": "CSV of the current members (at most 100,000 rows); requires push:users:export and is audited.", "responses": {"200": {"description": "text/csv"}, "404": {"description": "Segment not found"}}}},
    "/segments/{id}/members/{user}": {"get": {"operationId": "checkSegmentMember", "responses": {"200": {"description": "Whether this person (external id or Push user id) is in the segment now"}}}, "put": {"operationId": "addSegmentMember", "responses": {"200": {"description": "Membership activated"}}}, "delete": {"operationId": "removeSegmentMember", "responses": {"200": {"description": "Membership exited"}}}},
    "/campaigns": {"get": {"operationId": "listCampaigns", "responses": {"200": {"description": "Campaigns"}}}, "post": {"operationId": "createCampaign", "responses": {"201": {"description": "Campaign shell created"}}}},
    "/campaigns/{id}": {"get": {"operationId": "getCampaign", "responses": {"200": {"description": "Campaign and immutable versions"}}}},
    "/campaigns/{id}/versions": {"post": {"operationId": "createCampaignVersion", "responses": {"201": {"description": "Validated immutable campaign version"}}}},
    "/campaigns/{id}/versions/{version}:preview": {"post": {"operationId": "previewCampaignVersion", "responses": {"200": {"description": "Canonical render and policy warnings"}}}},
    "/campaigns/{id}/versions/{version}:estimate": {"post": {"operationId": "estimateCampaignVersion", "responses": {"200": {"description": "Live recipient and dispatch estimate; cost is never fabricated"}}}},
    "/campaigns/{id}/versions/{version}:request-approval": {"post": {"operationId": "requestCampaignApproval", "responses": {"202": {"description": "Approval requested"}}}},
    "/campaigns/{id}/versions/{version}:approve": {"post": {"operationId": "approveCampaignVersion", "responses": {"200": {"description": "Approved by a distinct subject"}}}},
    "/campaigns/{id}/versions/{version}:publish": {"post": {"operationId": "publishCampaignVersion", "responses": {"200": {"description": "Qualified campaign published"}}}},
    "/campaigns/{id}:launch": {"post": {"operationId": "launchCampaign", "responses": {"202": {"description": "Idempotent durable run queued"}}}},
    "/campaign-runs/{id}": {"get": {"operationId": "getCampaignRun", "responses": {"200": {"description": "Snapshot and dispatch counters"}}}},
    "/campaign-runs/{id}:pause": {"post": {"operationId": "pauseCampaignRun", "responses": {"200": {"description": "Unsent fan-out paused"}}}},
    "/campaign-runs/{id}:resume": {"post": {"operationId": "resumeCampaignRun", "responses": {"200": {"description": "Durable fan-out resumed"}}}},
    "/campaign-runs/{id}:cancel": {"post": {"operationId": "cancelCampaignRun", "responses": {"200": {"description": "Unsent fan-out canceled; provider-accepted messages cannot be recalled"}}}},
    "/experiments": {"get": {"operationId": "listExperiments", "responses": {"200": {"description": "Experiments and assignment counts"}}}, "post": {"operationId": "createExperiment", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentDefinition"}}}}, "responses": {"201": {"description": "Weighted deterministic experiment created"}, "409": {"description": "A non-draft definition is immutable"}, "422": {"description": "Invalid allocation, control, metric, stop rule, or safeguard"}}}},
    "/experiments/{id}:start": {"post": {"operationId": "startExperiment", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentTransition"}}}}, "responses": {"200": {"description": "Experiment started after weight, control, metric, and collision validation"}, "409": {"description": "State conflict or mutually exclusive experiment is already running"}}}},
    "/experiments/{id}:pause": {"post": {"operationId": "pauseExperiment", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentTransition"}}}}, "responses": {"200": {"description": "Experiment assignment paused; existing evidence remains immutable"}}}},
    "/experiments/{id}:resume": {"post": {"operationId": "resumeExperiment", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentTransition"}}}}, "responses": {"200": {"description": "Experiment resumed after mutual-exclusion check"}, "409": {"description": "State or collision conflict"}}}},
    "/experiments/{id}:complete": {"post": {"operationId": "completeExperiment", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentTransition"}}}}, "responses": {"200": {"description": "Experiment manually completed without automatic winner rollout"}}}},
    "/experiments/{id}:assign": {"post": {"operationId": "assignExperimentSubject", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentSubject"}}}}, "responses": {"200": {"description": "Stable user- or organization-level assignment; this does not record exposure"}}}},
    "/experiments/{id}/exposures": {"post": {"operationId": "recordExperimentExposure", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentExposure"}}}}, "responses": {"202": {"description": "Privacy-safe exposure durably recorded"}, "409": {"description": "Idempotency key reused with different evidence"}}}},
    "/experiments/{id}/observations": {"post": {"operationId": "recordExperimentObservation", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentObservation"}}}}, "responses": {"202": {"description": "Declared metric observation recorded after a proven exposure"}, "409": {"description": "Idempotency key reused with different evidence"}}}},
    "/experiments/{id}:analyze": {"post": {"operationId": "analyzeExperiment", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "responses": {"201": {"description": "Append-only frequentist and Bayesian sequential analysis created"}, "409": {"description": "Experiment state or evidence is not analyzable"}}}},
    "/experiments/{id}/results": {"get": {"operationId": "getExperimentResults", "responses": {"200": {"description": "Latest append-only result with samples, lift, confidence intervals, p-values, Bayesian probability and guardrails"}}}},
    "/experiments/{id}:request-winner-approval": {"post": {"operationId": "requestExperimentWinnerApproval", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentWinnerDecision"}}}}, "responses": {"200": {"description": "Evidence-backed winner sent for four-eyes approval"}}}},
    "/experiments/{id}:approve-winner": {"post": {"operationId": "approveExperimentWinner", "parameters": [{"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExperimentWinnerDecision"}}}}, "responses": {"200": {"description": "Different actor approved the recommended winner; no rollout is performed automatically"}, "409": {"description": "Recommendation mismatch or four-eyes violation"}}}},
    "/conversions": {"post": {"operationId": "recordConversion", "responses": {"202": {"description": "Idempotent conversion and revenue attribution accepted"}}}},
    "/apps/{id}/analytics-policy": {"get": {"operationId": "getAnalyticsPolicy", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Retention, minimum aggregation, user-level analytics, IP masking, and deletion-propagation policy"}}}, "put": {"operationId": "putAnalyticsPolicy", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnalyticsPolicy"}}}}, "responses": {"200": {"description": "Privacy policy saved and audited"}}}},
    "/apps/{id}/attribution-models": {"get": {"operationId": "listAttributionModels", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Versioned draft, published, and retired attribution models"}}}},
    "/attribution-models": {"post": {"operationId": "createAttributionModel", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttributionModelRequest"}}}}, "responses": {"201": {"description": "Draft attribution model version created"}, "200": {"description": "Exact idempotent replay"}, "409": {"description": "Idempotency mismatch"}}}},
    "/attribution-models/{id}:publish": {"post": {"operationId": "publishAttributionModel", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ApprovalDecision"}}}}, "responses": {"200": {"description": "Published by an actor different from the author; prior published version retired"}, "409": {"description": "Four-eyes, state, or idempotency conflict"}}}},
    "/apps/{id}/reports": {"get": {"operationId": "listReportDefinitions", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Saved and scheduled report definitions"}}}},
    "/reports": {"post": {"operationId": "createReportDefinition", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReportDefinitionRequest"}}}}, "responses": {"201": {"description": "Saved report definition created"}, "200": {"description": "Exact definition replay"}, "409": {"description": "Report key exists with different content"}}}},
    "/reports:run": {"post": {"operationId": "runAdHocReport", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReportRunRequest"}}}}, "responses": {"201": {"description": "Bounded privacy-filtered report completed"}, "200": {"description": "Exact idempotent report replay"}, "422": {"description": "Invalid report or retention range"}}}},
    "/reports/{id}:run": {"post": {"operationId": "runSavedReport", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReportRunRequest"}}}}, "responses": {"201": {"description": "Saved report completed"}, "200": {"description": "Exact idempotent replay"}}}},
    "/apps/{id}/report-runs": {"get": {"operationId": "listReportRuns", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Latest 200 immutable report run records"}}}},
    "/report-runs/{id}": {"get": {"operationId": "getReportRun", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Report columns, bounded rows, summary, and checksum"}, "404": {"description": "Not found in an app bound to the caller"}}}},
    "/exports": {"post": {"operationId": "createDataExport", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DataExportRequest"}}}}, "responses": {"201": {"description": "Checksum-addressed bounded export generated"}, "200": {"description": "Exact idempotent replay"}, "422": {"description": "Report is not ready"}}}},
    "/exports/{id}": {"get": {"operationId": "getDataExport", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Export lifecycle, size, expiry, and SHA-256 metadata"}}}},
    "/exports/{id}/download": {"get": {"operationId": "downloadDataExport", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "CSV or JSON Lines artifact", "content": {"text/csv": {"schema": {"type": "string", "contentEncoding": "binary"}}, "application/x-ndjson": {"schema": {"type": "string", "contentEncoding": "binary"}}}}, "410": {"description": "Export expired or unavailable"}}}},
    "/apps/{id}/digest-rules": {"get": {"operationId": "listDigestRules", "responses": {"200": {"description": "Latest immutable digest-rule versions"}}}},
    "/digest-rules": {"post": {"operationId": "publishDigestRule", "responses": {"201": {"description": "Immutable digest rule version published"}, "200": {"description": "Identical definition replay"}}}},
    "/digest-rules/{id}/users/{user}/preference": {"put": {"operationId": "putDigestPreference", "responses": {"200": {"description": "User-controlled digest schedule saved"}}}},
    "/digest-items": {"post": {"operationId": "enqueueDigestItem", "responses": {"202": {"description": "Idempotent digest item enqueued"}}}},
    "/digest-rules/{id}:preview": {"post": {"operationId": "previewDigest", "responses": {"200": {"description": "Deterministic non-delivering digest preview with overflow evidence"}}}},
    "/digest-batches": {"get": {"operationId": "listDigestBatches", "responses": {"200": {"description": "Durable materialization, render, and dispatch lifecycle"}}}},
    "/apps/{id}/users/{user}/attention": {"get": {"operationId": "getAttentionLedger", "responses": {"200": {"description": "Explainable 30-day attention ledger and deterministic fatigue score"}}}},
    "/apps/{id}/users/{user}/delivery-profile": {"get": {"operationId": "getDeliveryProfile", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Locale, timezone, channel, device, and business-hours delivery preferences"}}}, "put": {"operationId": "putDeliveryProfile", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}], "responses": {"200": {"description": "Validated delivery profile saved"}}}},
    "/apps/{id}/attention-policies": {"get": {"operationId": "listAttentionPolicies", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Effective tenant and application attention policies"}}}, "put": {"operationId": "putAttentionPolicy", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Frequency and fatigue policy saved"}}}},
    "/routing:plan": {"post": {"operationId": "planRouting", "summary": "Explainably choose channel, device, provider, and delivery time", "responses": {"200": {"description": "Deterministic routing decision with machine-readable scores, reasons, and evidence"}, "422": {"description": "No safe plan or invalid timing inputs"}}}},
    "/in-app-experiences": {"get": {"operationId": "listInAppExperiences", "responses": {"200": {"description": "Tenant-scoped in-app authoring versions and qualification state"}}}, "post": {"operationId": "createInAppExperience", "responses": {"201": {"description": "Immutable validated in-app experience version created for one of the 22 canonical formats"}, "422": {"description": "Unsupported format, unsafe raw HTML/CSS, invalid targeting, or out-of-bounds content"}}}},
    "/in-app-experiences/{id}:preview": {"post": {"operationId": "previewInAppExperience", "responses": {"200": {"description": "Canonical format, eligibility, frequency, and content preview; records the publish gate"}}}},
    "/in-app-experiences/{id}:publish": {"post": {"operationId": "publishInAppExperience", "responses": {"200": {"description": "Previewed experience version published by a distinct actor"}, "409": {"description": "Preview or four-eyes qualification missing"}}}},
    "/in-app-experiences:eligible": {"get": {"security": [{"receiptToken": []}], "operationId": "listEligibleInAppExperiences", "responses": {"200": {"description": "Authenticated device feed with specification and policy, filtered by device, user, bounded runtime context, session/mutual exclusion, terminal state, frequency caps, and cooldown"}, "400": {"description": "Unsupported or oversized runtime context"}}}},
    "/in-app-experiences/{id}/events": {"post": {"security": [{"receiptToken": []}], "operationId": "recordInAppEvent", "responses": {"202": {"description": "Checksum-bound idempotent eligibility, impression, dismissal, action, completion, or conversion event"}, "409": {"description": "Idempotency key was reused for a different event or payload"}, "422": {"description": "Unsupported event or out-of-bounds data"}}}},
    "/live-notifications": {"get": {"operationId": "listLiveNotifications", "responses": {"200": {"description": "Tenant-scoped live lifecycle and rail summary"}}}, "post": {"operationId": "startLiveNotification", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LiveNotificationRequest"}}}}, "responses": {"202": {"description": "Canonical cross-platform live object durably resolved to native and fallback rails"}}}},
    "/live-notifications/{id}": {"get": {"operationId": "getLiveNotification", "responses": {"200": {"description": "Canonical state, monotonic updates, and redacted per-installation rail evidence"}}}},
    "/live-notifications/{id}:update": {"post": {"operationId": "updateLiveNotification", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LiveMutationRequest"}}}}, "responses": {"202": {"description": "Monotonic rate-protected live update"}}}},
    "/live-notifications/{id}:end": {"post": {"operationId": "endLiveNotification", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LiveMutationRequest"}}}}, "responses": {"202": {"description": "Terminal live state queued across every eligible rail with final content and dismissal date"}}}},
    "/live-notifications:simulate": {"post": {"operationId": "simulateLiveNotification", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LiveSimulationRequest"}}}}, "responses": {"200": {"description": "Persisted provider-call-free Apple, Android, Web, in-app, and fallback projection"}}}},
    "/live-templates": {"post": {"operationId": "createLiveTemplateVersion", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LiveTemplateRequest"}}}}, "responses": {"201": {"description": "Immutable versioned cross-platform live template created"}}}},
    "/apps/{id}/brand-kits": {"get": {"operationId": "listBrandKits", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Versioned brand kits"}}}, "post": {"operationId": "createBrandKit", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Draft brand kit created"}}}},
    "/brand-kits/{id}/versions": {"post": {"operationId": "createBrandKitVersion", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Immutable validated brand version created"}}}},
    "/brand-kits/{id}/versions/{version}:publish": {"post": {"operationId": "publishBrandKitVersion", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}], "responses": {"200": {"description": "Brand version published by a distinct actor"}, "409": {"description": "Four-eyes approval required"}}}},
    "/apps/{id}/media-assets": {"get": {"operationId": "listMediaAssets", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Integrity-addressed media registry"}}}, "post": {"operationId": "createMediaAsset", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "HTTPS media metadata registered"}}}},
    "/apps/{id}/content-bundles": {"get": {"operationId": "listContentBundles", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Localized content bundles"}}}, "post": {"operationId": "createContentBundle", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Draft content bundle created"}}}},
    "/content-bundles/{id}/versions": {"post": {"operationId": "createContentBundleVersion", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"201": {"description": "Immutable content version with strict variables created"}}}},
    "/content-bundles/{id}/versions/{version}/localizations/{locale}": {"put": {"operationId": "putContentLocalization", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}, {"name": "locale", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Locale overlay saved as draft"}}}},
    "/content-bundles/{id}/versions/{version}/localizations/{locale}:approve": {"post": {"operationId": "approveContentLocalization", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}, {"name": "locale", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Localization approved by a distinct actor"}, "409": {"description": "Four-eyes approval required"}}}},
    "/content-bundles/{id}/versions/{version}:publish": {"post": {"operationId": "publishContentBundleVersion", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/Version"}], "responses": {"200": {"description": "Content version published after translation approval"}}}},
    "/content-bundles/{id}:render": {"post": {"operationId": "renderContentBundle", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Strict variable-safe localized render, fallback trace, direction, and warnings"}, "422": {"description": "Invalid variables or content schema"}}}},
    "/apps/{id}/channel-connectors": {"get": {"operationId": "listChannelConnectors", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Redacted replaceable channel connectors"}}}, "post": {"operationId": "createChannelConnector", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChannelConnectorRequest"}}}}, "responses": {"201": {"description": "Validated connector stored with encrypted credentials"}, "422": {"description": "Invalid provider, endpoint, or credentials"}}}},
    "/channel-connectors/{id}": {"delete": {"operationId": "disableChannelConnector", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"204": {"description": "Connector disabled and encrypted configuration erased"}}}},
    "/apps/{id}/users/{user}/destinations/{channel}": {"put": {"operationId": "putChannelDestination", "parameters": [{"$ref": "#/components/parameters/Id"}, {"$ref": "#/components/parameters/User"}, {"$ref": "#/components/parameters/Channel"}], "responses": {"200": {"description": "Normalized user channel destination saved"}, "422": {"description": "Invalid destination"}}}},
    "/channel-messages": {"post": {"operationId": "sendChannelMessage", "summary": "Durably accept an email, SMS, WhatsApp, RCS, collaboration, or custom-channel message", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChannelMessageRequest"}}}}, "responses": {"202": {"description": "Queued, scheduled, or policy-suppressed; cost is null unless provider-reported"}, "200": {"description": "Idempotent replay"}, "409": {"description": "Idempotency mismatch"}, "422": {"description": "Missing connector, verified destination, consent, or valid content"}}}},
    "/channel-messages/{id}": {"get": {"operationId": "getChannelMessage", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Tenant-scoped channel state; provider acceptance is not confirmed delivery"}, "404": {"description": "Not found"}}}},
    "/channel-messages/{id}:receipt": {"post": {"operationId": "recordChannelReceipt", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChannelReceipt"}}}}, "responses": {"200": {"description": "Idempotent monotonic provider receipt recorded"}, "409": {"description": "Invalid state transition"}}}},
    "/apps/{id}/migration-sources": {"get": {"operationId": "listMigrationSources", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Migration sources with encrypted configuration redacted"}}}, "post": {"operationId": "createMigrationSource", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MigrationSourceRequest"}}}}, "responses": {"201": {"description": "Encrypted migration source created"}, "422": {"description": "Unsupported source or invalid configuration"}}}},
    "/migration-sources/{id}/jobs": {"post": {"operationId": "createMigrationJob", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MigrationJobRequest"}}}}, "responses": {"201": {"description": "Validation or apply job started"}, "200": {"description": "Idempotent replay"}, "409": {"description": "Idempotency mismatch"}}}},
    "/migration-jobs/{id}/records:batch": {"post": {"operationId": "importMigrationRecords", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MigrationBatchRequest"}}}}, "responses": {"202": {"description": "Records normalized, secret fields redacted from staging, and optionally applied transactionally"}, "409": {"description": "Job is terminal"}, "422": {"description": "Batch size invalid"}}}},
    "/migration-jobs/{id}:complete": {"post": {"operationId": "completeMigrationJob", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Readiness score, gates, counts, and remediation recommendations"}, "409": {"description": "Job is already terminal"}}}},
    "/migration-jobs/{id}": {"get": {"operationId": "getMigrationJob", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Import counts and redacted record evidence"}, "404": {"description": "Not found"}}}},
    "/shadow:evaluate": {"post": {"operationId": "evaluateMigrationShadow", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ShadowEvaluationRequest"}}}}, "responses": {"200": {"description": "Persisted no-delivery audience, suppression, channel, and render comparison; unknown cost and latency remain null"}, "409": {"description": "Idempotency mismatch"}}}},
    "/apps/{id}/shadow-evaluations": {"get": {"operationId": "listMigrationShadowEvaluations", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Recent persisted shadow comparison evidence"}}}},
    "/apps/{id}/dual-run-config": {"get": {"operationId": "getDualRunConfig", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Deterministic migration allocation, rollback generation, and latest readiness evidence"}}}, "put": {"operationId": "putDualRunConfig", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DualRunConfigRequest"}}}}, "responses": {"200": {"description": "Dual-run allocation saved without changing existing cohort assignments"}, "422": {"description": "Invalid allocation or completion state"}}}},
    "/apps/{id}/dual-run:rollback": {"post": {"operationId": "rollbackDualRun", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "New routes atomically switched to the source provider; existing delivery ownership is unchanged"}, "409": {"description": "Migration is already completed or not configured"}}}},
    "/apps/{id}/dual-run:readiness": {"post": {"operationId": "createDualRunReadiness", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Persisted cohort sample, duplicate, stale-route, and success-rate readiness gates"}}}},
    "/dual-run:route": {"post": {"operationId": "routeDualRun", "summary": "Assign exactly one delivery owner using a stable deterministic cohort", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DualRunRouteRequest"}}}}, "responses": {"200": {"description": "Replay-safe source-or-Bolrach ownership decision and required caller action"}, "409": {"description": "Idempotency mismatch or dual-run not configured"}}}},
    "/dual-run-routes/{id}:source-result": {"post": {"operationId": "recordDualRunSourceResult", "parameters": [{"$ref": "#/components/parameters/Id"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DualRunSourceResult"}}}}, "responses": {"200": {"description": "Idempotent monotonic source-provider outcome recorded"}, "409": {"description": "Event idempotency mismatch or invalid state transition"}}}},
    "/apps/{id}/dual-run-routes": {"get": {"operationId": "listDualRunRoutes", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Recent delivery-owner assignments and cross-provider evidence"}}}},
    "/roles": {"get": {"operationId": "listRoles", "responses": {"200": {"description": "Built-in and tenant custom roles with effective permissions"}}}, "post": {"operationId": "createCustomRole", "responses": {"201": {"description": "Custom role created by tenant owner"}, "422": {"description": "Unsupported permission"}}}},
    "/roles/{id}": {"put": {"operationId": "updateCustomRole", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Custom role replaced and assigned sessions revoked"}}}, "delete": {"operationId": "deleteCustomRole", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"204": {"description": "Custom role and assignments removed; assigned sessions revoked"}}}},
    "/role-assignments": {"put": {"operationId": "assignCustomRole", "responses": {"200": {"description": "Custom role assigned and existing subject sessions revoked"}}}},
    "/role-assignments/{id}": {"delete": {"operationId": "removeCustomRoleAssignment", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"204": {"description": "Assignment removed and existing subject sessions revoked"}}}},
    "/member-app-access": {"put": {"operationId": "replaceMemberAppAccess", "responses": {"200": {"description": "Application and environment access replaced; existing sessions revoked"}}}},
    "/security-policy": {"get": {"operationId": "getTenantSecurityPolicy", "responses": {"200": {"description": "IP, mTLS, authentication, credential-approval and session policy"}}}, "put": {"operationId": "putTenantSecurityPolicy", "responses": {"200": {"description": "Owner-updated policy; prior sessions revoked"}, "422": {"description": "Invalid CIDR, auth method, or session TTL"}}}},
    "/sessions": {"get": {"operationId": "listConsoleSessions", "responses": {"200": {"description": "Current subject sessions or administrator-selected subject sessions"}}}},
    "/sessions/{id}": {"delete": {"operationId": "revokeConsoleSession", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"204": {"description": "Session revoked immediately"}}}},
    "/security-alerts": {"get": {"operationId": "listSecurityAlerts", "responses": {"200": {"description": "New-session-device and future tenant security evidence"}}}},
    "/security-alerts/{id}:acknowledge": {"post": {"operationId": "acknowledgeSecurityAlert", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Alert acknowledged with actor and time evidence"}}}},
    "/support-access": {"get": {"operationId": "listSupportAccess", "responses": {"200": {"description": "Complete customer-controlled support access trail"}}}, "post": {"operationId": "requestSupportAccess", "responses": {"201": {"description": "Bounded support access request awaiting a distinct owner"}}}},
    "/support-access/{id}:approve": {"post": {"operationId": "approveSupportAccess", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Distinct owner approved time-limited scopes"}, "409": {"description": "Expired, non-pending, or same-actor request"}}}},
    "/support-access/{id}:revoke": {"post": {"operationId": "revokeSupportAccess", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Support access revoked immediately"}}}},
    "/apps/{id}/provider-credentials": {"get": {"operationId": "listProviderCredentialMetadata", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Redacted active credential and candidate approval metadata"}}}},
    "/provider-credential-changes/{id}:approve": {"post": {"operationId": "approveProviderCredentialChange", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Distinct actor atomically activates a validated encrypted candidate"}, "409": {"description": "Candidate cannot be approved"}}}},
    "/audit-events": {"get": {"operationId": "listAuditEvents", "responses": {"200": {"description": "Filtered append-only hash-chained tenant audit events"}}}},
    "/audit-events:verify": {"get": {"operationId": "verifyAuditEvents", "responses": {"200": {"description": "Full-row hash and predecessor-link verification for the tenant audit chain"}}}},
    "/audit-events:export": {"post": {"operationId": "createAuditExport", "responses": {"201": {"description": "Bounded immutable audit snapshot ready for download"}, "422": {"description": "Range exceeds export limits"}}}},
    "/audit-exports/{id}/download": {"get": {"operationId": "downloadAuditExport", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Tenant-scoped NDJSON or JSON audit evidence"}, "410": {"description": "Export expired"}}}},
    "/customer-key-configuration": {"get": {"operationId": "getCustomerKeyConfiguration", "responses": {"200": {"description": "Customer key provider metadata and honest validation status"}}}, "put": {"operationId": "putCustomerKeyConfiguration", "responses": {"202": {"description": "KMS/HSM metadata recorded pending external validation; not falsely activated"}}}},
    "/status": {"get": {"security": [], "operationId": "getPublicStatus", "responses": {"200": {"description": "Customer-visible current and recent public incident history"}}}},
    "/dead-letters": {"get": {"operationId": "listDeadLetters", "responses": {"200": {"description": "Tenant-scoped redacted dead-letter ledger"}}}},
    "/dead-letters/{id}:replay": {"post": {"operationId": "replayDeadLetter", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"202": {"description": "Confirmed idempotent replay started from authoritative outbox state"}, "409": {"description": "Dead letter is not open"}}}},
    "/replay-jobs": {"get": {"operationId": "listReplayJobs", "responses": {"200": {"description": "Manual replay request and terminal outcome evidence"}}}},
    "/provider-health": {"get": {"operationId": "listProviderHealth", "responses": {"200": {"description": "Current circuit state and latest provider health snapshots"}}}},
    "/provider-circuits/{id}:reset": {"post": {"operationId": "resetProviderCircuit", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Confirmed audited circuit reset for a bound application"}}}},
    "/channel-connectors/{id}:reset-circuit": {"post": {"operationId": "resetConnectorCircuit", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Confirmed audited circuit reset for a tenant connector"}}}},
    "/incidents": {"get": {"operationId": "listIncidents", "responses": {"200": {"description": "Tenant-specific and public incident history with updates"}}}},
    "/usage": {"get": {"operationId": "getUsage", "responses": {"200": {"description": "Live idempotent meter totals, budgets, and null cost when no approved rate exists"}}}},
    "/usage-budgets": {"put": {"operationId": "putUsageBudget", "responses": {"200": {"description": "Application or tenant meter budget and hard limit stored"}}}},
    "/usage-budget-alerts/{id}:acknowledge": {"post": {"operationId": "acknowledgeUsageBudgetAlert", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Budget threshold alert acknowledged with actor evidence"}}}},
    "/slo-report": {"get": {"operationId": "getSLOReport", "responses": {"200": {"description": "Approved SLO definitions, latest measurements, and live backlog evidence"}}}},
    "/messages/{id}/diagnostics": {"get": {"operationId": "downloadMessageDiagnostics", "parameters": [{"$ref": "#/components/parameters/Id"}], "responses": {"200": {"description": "Exportable tenant-scoped diagnostic bundle without provider secrets"}}}},
    "/demo": {"get": {"security": [], "operationId": "getPushDemo", "responses": {"200": {"description": "Interactive first-party device test page"}}}},
    "/demo-sw.js": {"get": {"security": [], "operationId": "getPushDemoWorker", "responses": {"200": {"description": "Service worker for the device test page"}}}}
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {"type": "http", "scheme": "bearer", "description": "Scoped bt_live_/bt_test_ key or Authvio session JWT"},
      "receiptToken": {"type": "http", "scheme": "bearer", "description": "Per-installation HMAC receipt token"},
      "streamToken": {"type": "apiKey", "in": "query", "name": "token"}
      ,"preferenceAccess": {"type": "apiKey", "in": "header", "name": "Authorization", "description": "Recipient-bound Authorization: Preference <signed-token>; never persist or place this fragment credential in a query string"}
      ,"preferenceConfirmation": {"type": "apiKey", "in": "header", "name": "Authorization", "description": "Separate Authorization: Preference-Confirmation <signed-token> for one version-fenced double-opt-in operation"}
    },
    "parameters": {
      "Id": {"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}},
      "Key": {"name": "key", "in": "path", "required": true, "schema": {"type": "string"}},
      "User": {"name": "user", "in": "path", "required": true, "schema": {"type": "string"}},
      "Category": {"name": "category", "in": "path", "required": true, "schema": {"type": "string"}},
      "Channel": {"name": "channel", "in": "path", "required": true, "schema": {"type": "string", "enum": ["email", "sms", "whatsapp", "rcs", "slack", "teams", "discord", "custom"]}},
      "Version": {"name": "version", "in": "path", "required": true, "schema": {"type": "integer", "minimum": 1}},
      "AppHeader": {"name": "X-Bolrach-App-ID", "in": "header", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "Required on browser CORS requests so the origin can be checked before the request body is available"}
      ,"IdempotencyKey": {"name": "Idempotency-Key", "in": "header", "required": true, "schema": {"type": "string", "minLength": 1, "maxLength": 200}, "description": "Operation-scoped replay key; reusing it with different content is rejected"}
      ,"OptionalIdempotencyKey": {"name": "Idempotency-Key", "in": "header", "required": false, "schema": {"type": "string", "minLength": 1, "maxLength": 200}, "description": "When supplied, replay returns the original state result and rejects reuse for any different target, transition input, or expected version"}
      ,"InboxLimit": {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}}
      ,"InboxCursor": {"name": "cursor", "in": "query", "schema": {"type": "string"}, "description": "Opaque stable cursor returned as next_cursor"}
      ,"InboxFeed": {"name": "feed", "in": "query", "schema": {"type": "string", "maxLength": 200}}
      ,"InboxCategory": {"name": "category", "in": "query", "schema": {"type": "string", "maxLength": 200}}
      ,"InboxThreadKey": {"name": "thread_key", "in": "query", "schema": {"type": "string", "maxLength": 200}}
      ,"InboxStatus": {"name": "status", "in": "query", "schema": {"type": "string", "enum": ["all", "active", "unread", "read", "archived", "snoozed", "pinned", "saved"], "default": "all"}}
      ,"InboxSearch": {"name": "q", "in": "query", "schema": {"type": "string", "maxLength": 200}, "description": "Literal title/body search; masked sensitive content is excluded unless explicitly revealed"}
      ,"InboxRevealSensitive": {"name": "reveal_sensitive", "in": "query", "schema": {"type": "boolean", "default": false}}
    },
    "requestBodies": {
      "InboxState": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InboxStateRequest"}}}}
    },
    "schemas": {
      "MessageSummary": {"type": "object", "required": ["id", "app_id", "status", "created_at", "deliveries", "delivered", "failed", "opened"], "properties": {"id": {"type": "string", "format": "uuid"}, "app_id": {"type": "string", "format": "uuid"}, "status": {"type": "string"}, "category": {"type": "string"}, "priority": {"type": "integer", "minimum": 0, "maximum": 4}, "title": {"type": "string"}, "target_type": {"type": "string"}, "created_at": {"type": "string", "format": "date-time"}, "deliveries": {"type": "integer", "minimum": 0}, "delivered": {"type": "integer", "minimum": 0, "description": "Accepted by the provider or any later state"}, "failed": {"type": "integer", "minimum": 0}, "opened": {"type": "integer", "minimum": 0, "description": "Deliveries with an opened receipt"}}},
      "MessageList": {"type": "object", "required": ["messages", "next_before", "next_before_id"], "properties": {"messages": {"type": "array", "items": {"$ref": "#/components/schemas/MessageSummary"}}, "next_before": {"type": ["string", "null"], "format": "date-time"}, "next_before_id": {"type": ["string", "null"], "format": "uuid"}}},
      "RateCapacity": {"type": "object", "properties": {"requests_per_second": {"type": "integer"}, "burst": {"type": "integer"}, "requests_per_day": {"type": "integer", "description": "0 means no daily quota"}}},
      "Target": {"type": "object", "required": ["type"], "properties": {"type": {"type": "string", "enum": ["user", "users", "installation", "alias", "topic"]}, "id": {"type": "string"}, "ids": {"type": "array", "items": {"type": "string"}}, "alias": {"type": "object", "properties": {"kind": {"type": "string"}, "value": {"type": "string"}}}}},
      "TextInputAction": {"type": "object", "additionalProperties": false, "properties": {"button_title": {"type": "string", "maxLength": 128}, "placeholder": {"type": "string", "maxLength": 256}}},
      "MediaAttachment": {"type": "object", "required": ["url"], "additionalProperties": false, "properties": {"url": {"type": "string", "format": "uri", "pattern": "^https://"}, "type": {"type": "string", "enum": ["image", "audio", "video"]}}},
      "CriticalSound": {"type": "object", "required": ["name"], "additionalProperties": false, "properties": {"name": {"type": "string", "maxLength": 128}, "critical": {"type": "boolean"}, "volume": {"type": "number", "minimum": 0, "maximum": 1}}},
      "Action": {"type": "object", "required": ["id", "title"], "properties": {"id": {"type": "string"}, "title": {"type": "string"}, "url": {"type": "string", "format": "uri"}, "destructive": {"type": "boolean"}, "foreground": {"type": "boolean"}, "authentication_required": {"type": "boolean"}, "text_input": {"$ref": "#/components/schemas/TextInputAction"}}},
      "MessageContent": {"type": "object", "properties": {"title": {"type": "string", "maxLength": 256}, "subtitle": {"type": "string", "maxLength": 256}, "body": {"type": "string", "maxLength": 4096}, "data": {"type": "object", "additionalProperties": {"type": "string"}}, "image_url": {"type": "string", "format": "uri", "pattern": "^https://"}, "icon_url": {"type": "string", "format": "uri", "pattern": "^https://"}, "badge": {"type": "integer", "minimum": 0}, "sound": {"type": "string"}, "url": {"type": "string", "format": "uri"}, "actions": {"type": "array", "maxItems": 4, "items": {"$ref": "#/components/schemas/Action"}}, "apns": {"type": "object", "properties": {"thread_id": {"type": "string"}, "category": {"type": "string"}, "target_content_id": {"type": "string"}, "interruption_level": {"type": "string", "enum": ["passive", "active", "time-sensitive", "critical"]}, "relevance_score": {"type": "number", "minimum": 0, "maximum": 1}, "mutable_content": {"type": "boolean"}, "content_available": {"type": "boolean"}, "push_type": {"type": "string", "enum": ["alert", "background", "voip", "complication", "fileprovider", "mdm", "liveactivity"]}, "priority": {"type": "integer", "enum": [5, 10]}, "title_loc_key": {"type": "string"}, "title_loc_args": {"type": "array", "maxItems": 10, "items": {"type": "string", "maxLength": 256}}, "subtitle_loc_key": {"type": "string"}, "subtitle_loc_args": {"type": "array", "maxItems": 10, "items": {"type": "string", "maxLength": 256}}, "body_loc_key": {"type": "string"}, "body_loc_args": {"type": "array", "maxItems": 10, "items": {"type": "string", "maxLength": 256}}, "launch_image": {"type": "string"}, "summary_arg": {"type": "string"}, "summary_arg_count": {"type": "integer", "minimum": 0}, "critical_sound": {"$ref": "#/components/schemas/CriticalSound"}, "media_attachments": {"type": "array", "maxItems": 4, "items": {"$ref": "#/components/schemas/MediaAttachment"}}}}, "android": {"type": "object", "properties": {"channel_id": {"type": "string"}, "click_action": {"type": "string"}, "icon": {"type": "string"}, "tag": {"type": "string"}, "color": {"type": "string"}, "visibility": {"type": "string", "enum": ["private", "public", "secret"]}, "notification_count": {"type": "integer", "minimum": 0}, "direct_boot_ok": {"type": "boolean"}, "title_loc_key": {"type": "string"}, "title_loc_args": {"type": "array", "maxItems": 10, "items": {"type": "string", "maxLength": 256}}, "body_loc_key": {"type": "string"}, "body_loc_args": {"type": "array", "maxItems": 10, "items": {"type": "string", "maxLength": 256}}, "ticker": {"type": "string"}, "event_time": {"type": "integer"}, "local_only": {"type": "boolean"}, "sticky": {"type": "boolean"}, "default_sound": {"type": "boolean"}, "notification_priority": {"type": "string", "enum": ["min", "low", "default", "high", "max"]}}}, "web": {"type": "object", "properties": {"tag": {"type": "string"}, "badge_url": {"type": "string", "format": "uri", "pattern": "^https://"}, "require_interaction": {"type": "boolean"}, "renotify": {"type": "boolean"}, "silent": {"type": "boolean"}, "direction": {"type": "string", "enum": ["auto", "ltr", "rtl"]}, "language": {"type": "string"}, "vibration": {"type": "array", "maxItems": 20, "items": {"type": "integer", "minimum": 0, "maximum": 10000}}, "timestamp": {"type": "integer"}}}}},
      "SendRequest": {"allOf": [{"$ref": "#/components/schemas/MessageContent"}, {"type": "object", "required": ["app_id"], "properties": {"app_id": {"type": "string", "format": "uuid"}, "target": {"$ref": "#/components/schemas/Target"}, "user_id": {"type": "string", "deprecated": true}, "priority": {"type": "integer", "minimum": 0, "maximum": 4}, "ttl_seconds": {"type": "integer", "minimum": 1, "maximum": 2419200}, "collapse_id": {"type": "string", "maxLength": 64}, "environment": {"type": "string", "enum": ["development", "preview", "staging", "production"]}, "category": {"type": "string"}, "correlation_id": {"type": "string"}, "scheduled_at": {"type": "string", "format": "date-time"}, "deduplication_key": {"type": "string"}, "deduplication_window_seconds": {"type": "integer", "minimum": 1, "maximum": 2592000}, "semantic_deduplication": {"type": "object", "properties": {"enabled": {"type": "boolean"}, "event_type": {"type": "string"}, "object_type": {"type": "string"}, "object_id": {"type": "string"}, "text": {"type": "string", "maxLength": 8192}, "window_seconds": {"type": "integer", "minimum": 1, "maximum": 2592000}, "similarity_threshold": {"type": "number", "minimum": 0.5, "maximum": 1}, "action": {"type": "string", "enum": ["suppress", "digest"]}, "digest_rule_key": {"type": "string"}}}, "policy": {"type": "object", "properties": {"require_consent": {"type": "boolean"}, "respect_quiet_hours": {"type": "boolean"}, "max_per_user_per_hour": {"type": "integer", "minimum": 1}}}, "dry_run": {"type": "boolean"}, "idempotency_key": {"type": "string"}, "template_id": {"type": "string", "format": "uuid", "description": "Render this stored template for the target person; fields the request sets itself win"}, "variables": {"type": "object", "description": "Template variables; the target person attributes are available as user.*"}, "locale": {"type": "string", "description": "Picks the template locale variant (pt-BR falls back to pt, then the default)"}}}]},
      "MessageBatchRequest": {"type": "object", "required": ["idempotency_key", "messages"], "additionalProperties": false, "properties": {"idempotency_key": {"type": "string", "minLength": 1, "maxLength": 200}, "messages": {"type": "array", "minItems": 1, "maxItems": 100, "description": "Fully validated before mutation. Per-item idempotency_key must be omitted; stable item keys derive from the batch job and position.", "items": {"$ref": "#/components/schemas/SendRequest"}}}},
      "Recurrence": {"type": "object", "required": ["frequency", "timezone", "local_time", "starts_at"], "additionalProperties": false, "properties": {"frequency": {"type": "string", "enum": ["hourly", "daily", "weekly", "monthly"]}, "interval_count": {"type": "integer", "minimum": 1, "maximum": 365, "default": 1}, "timezone": {"type": "string", "description": "IANA timezone used for calendar recurrence and daylight-saving transitions"}, "local_time": {"type": "string", "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"}, "weekdays": {"type": "array", "uniqueItems": true, "items": {"type": "integer", "minimum": 0, "maximum": 6}}, "month_day": {"type": "integer", "minimum": 1, "maximum": 31}, "starts_at": {"type": "string", "format": "date-time"}, "ends_at": {"type": "string", "format": "date-time"}, "max_occurrences": {"type": "integer", "minimum": 1, "maximum": 1000000}}},
      "RecurringMessageRequest": {"type": "object", "required": ["name", "idempotency_key", "message", "recurrence"], "additionalProperties": false, "properties": {"name": {"type": "string", "minLength": 1, "maxLength": 120}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}, "message": {"$ref": "#/components/schemas/SendRequest"}, "recurrence": {"$ref": "#/components/schemas/Recurrence"}}},
      "RecurringMessageStateRequest": {"type": "object", "required": ["reason", "idempotency_key"], "additionalProperties": false, "properties": {"reason": {"type": "string", "minLength": 3, "maxLength": 1000}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "MessageStreamJobRequest": {"type": "object", "required": ["name", "idempotency_key"], "additionalProperties": false, "properties": {"name": {"type": "string", "minLength": 1, "maxLength": 120}, "expected_records": {"type": "integer", "minimum": 1, "maximum": 1000000000}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "MessageStreamRecord": {"type": "object", "required": ["record_key", "message"], "additionalProperties": false, "properties": {"record_key": {"type": "string", "minLength": 1, "maxLength": 300}, "message": {"$ref": "#/components/schemas/SendRequest"}}},
      "MessageStreamBatchRequest": {"type": "object", "required": ["batch_key", "records"], "additionalProperties": false, "properties": {"batch_key": {"type": "string", "minLength": 1, "maxLength": 200}, "records": {"type": "array", "minItems": 1, "maxItems": 500, "items": {"$ref": "#/components/schemas/MessageStreamRecord"}}}},
      "PreferenceBranding": {"type": "object", "additionalProperties": false, "properties": {"company_name": {"type": "string", "maxLength": 120}, "logo_url": {"type": "string", "format": "uri", "pattern": "^https://"}, "primary_color": {"type": "string", "pattern": "^#[0-9A-Fa-f]{6}$"}}},
      "PreferenceCategory": {"type": "object", "required": ["key", "name"], "additionalProperties": false, "properties": {"key": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,119}$"}, "name": {"type": "string", "minLength": 1, "maxLength": 120}, "description": {"type": "string", "maxLength": 1000}, "required": {"type": "boolean"}, "default_opt_in": {"type": "boolean"}, "channels": {"type": "array", "uniqueItems": true, "items": {"type": "string", "enum": ["push", "email", "sms", "whatsapp", "rcs", "in_app"]}}}},
      "PreferenceCentreRequest": {"type": "object", "required": ["title", "categories", "idempotency_key"], "additionalProperties": false, "properties": {"title": {"type": "string", "minLength": 1, "maxLength": 120}, "default_locale": {"type": "string", "default": "en"}, "supported_locales": {"type": "array", "maxItems": 50, "uniqueItems": true, "items": {"type": "string"}}, "allowed_origins": {"type": "array", "maxItems": 50, "uniqueItems": true, "items": {"type": "string", "format": "uri", "pattern": "^https://"}}, "custom_domain": {"type": "string", "description": "Hostname only"}, "categories": {"type": "array", "minItems": 1, "maxItems": 200, "items": {"$ref": "#/components/schemas/PreferenceCategory"}}, "branding": {"$ref": "#/components/schemas/PreferenceBranding"}, "translations": {"type": "object", "maxProperties": 50, "additionalProperties": {"type": "object", "additionalProperties": {"type": "string", "maxLength": 2000}}}, "jurisdiction_templates": {"type": "object", "maxProperties": 25, "additionalProperties": {"type": "object", "additionalProperties": {"type": "string", "maxLength": 2000}}}, "double_opt_in_categories": {"type": "array", "maxItems": 200, "uniqueItems": true, "items": {"type": "string"}}, "confirmation_channel": {"type": "string", "enum": ["email", "sms"], "default": "email"}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "PreferenceAccessGrantRequest": {"type": "object", "required": ["idempotency_key"], "additionalProperties": false, "properties": {"expires_in_seconds": {"type": "integer", "minimum": 300, "maximum": 2592000, "default": 86400}, "max_uses": {"type": "integer", "minimum": 1, "maximum": 100000, "default": 1000}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "PreferenceAccessRevokeRequest": {"type": "object", "required": ["reason", "idempotency_key"], "additionalProperties": false, "properties": {"reason": {"type": "string", "minLength": 3, "maxLength": 1000}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "PreferenceCompliancePolicyRequest": {"type": "object", "required": ["consent_retention_days", "access_event_retention_days", "expected_state_version", "idempotency_key"], "additionalProperties": false, "properties": {"consent_retention_days": {"type": "integer", "minimum": 30, "maximum": 3650}, "access_event_retention_days": {"type": "integer", "minimum": 30, "maximum": 3650}, "expected_state_version": {"type": "integer", "minimum": 0}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "PreferenceLegalHoldRequest": {"type": "object", "required": ["legal_basis", "authority", "reference", "reason", "review_at", "idempotency_key"], "additionalProperties": false, "properties": {"user": {"type": "string", "minLength": 1, "maxLength": 500, "description": "Optional external or internal user identifier; omission creates an application-wide hold"}, "legal_basis": {"type": "string", "minLength": 3, "maxLength": 500}, "authority": {"type": "string", "minLength": 2, "maxLength": 300}, "reference": {"type": "string", "minLength": 2, "maxLength": 300}, "reason": {"type": "string", "minLength": 3, "maxLength": 2000}, "review_at": {"type": "string", "format": "date-time", "description": "Future review time no more than three years away"}, "expires_at": {"type": "string", "format": "date-time", "description": "Optional time after review and no more than ten years away"}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "PreferenceLegalHoldReleaseRequest": {"type": "object", "required": ["reason", "idempotency_key"], "additionalProperties": false, "properties": {"reason": {"type": "string", "minLength": 3, "maxLength": 2000}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "PreferenceQuietHours": {"type": "object", "required": ["enabled", "starts_at", "ends_at"], "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "timezone": {"type": "string", "description": "IANA timezone"}, "starts_at": {"type": "string", "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"}, "ends_at": {"type": "string", "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"}, "weekdays": {"type": "array", "uniqueItems": true, "items": {"type": "integer", "minimum": 0, "maximum": 6}}}},
      "PreferenceVacation": {"type": "object", "required": ["starts_at", "ends_at"], "additionalProperties": false, "properties": {"starts_at": {"type": "string", "format": "date-time"}, "ends_at": {"type": "string", "format": "date-time"}}},
      "PreferenceDigestPatch": {"type": "object", "required": ["rule_id", "enabled"], "additionalProperties": false, "properties": {"rule_id": {"type": "string", "format": "uuid"}, "enabled": {"type": "boolean"}, "timezone": {"type": "string"}, "delivery_local_time": {"type": "string", "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"}, "weekdays": {"type": "array", "uniqueItems": true, "items": {"type": "integer", "minimum": 0, "maximum": 6}}, "max_items": {"type": "integer", "minimum": 1, "maximum": 1000}}},
      "PreferenceStatePatch": {"type": "object", "required": ["expected_state_version", "idempotency_key"], "additionalProperties": false, "properties": {"global_enabled": {"type": "boolean"}, "categories": {"type": "object", "maxProperties": 200, "additionalProperties": {"type": "boolean"}}, "channels": {"type": "object", "maxProperties": 6, "additionalProperties": {"type": "boolean"}}, "topics": {"type": "object", "maxProperties": 500, "additionalProperties": {"type": "boolean"}}, "digests": {"type": "array", "maxItems": 100, "items": {"$ref": "#/components/schemas/PreferenceDigestPatch"}}, "quiet_hours": {"$ref": "#/components/schemas/PreferenceQuietHours"}, "pause_non_critical_until": {"type": "string", "format": "date-time"}, "clear_pause": {"type": "boolean"}, "vacation": {"$ref": "#/components/schemas/PreferenceVacation"}, "clear_vacation": {"type": "boolean"}, "timezone": {"type": "string"}, "locale": {"type": "string"}, "jurisdiction": {"type": "string"}, "unsubscribe_reason": {"type": "string", "maxLength": 500}, "expected_state_version": {"type": "integer", "minimum": 0}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}, "metadata": {"type": "object", "maxProperties": 20}}},
      "PreferenceState": {"type": "object", "required": ["centre", "controls", "categories", "channels", "topics", "quiet_hours", "digests", "consent_history"], "properties": {"centre": {"type": "object"}, "controls": {"type": "object", "properties": {"global_enabled": {"type": "boolean"}, "pause_non_critical_until": {"type": ["string", "null"], "format": "date-time"}, "vacation_starts_at": {"type": ["string", "null"], "format": "date-time"}, "vacation_ends_at": {"type": ["string", "null"], "format": "date-time"}, "timezone": {"type": "string"}, "locale": {"type": "string"}, "state_version": {"type": "integer", "minimum": 0}}}, "categories": {"type": "array", "items": {"type": "object"}}, "channels": {"type": "array", "items": {"type": "object"}}, "topics": {"type": "array", "items": {"type": "object"}}, "quiet_hours": {"type": "array", "items": {"type": "object"}}, "digests": {"type": "array", "items": {"type": "object"}}, "consent_history": {"type": "array", "maxItems": 200, "items": {"type": "object"}}}},
      "MessageControlRequest": {"type": "object", "required": ["reason"], "additionalProperties": false, "properties": {"reason": {"type": "string", "minLength": 3, "maxLength": 500}}},
      "MessageRetryRequest": {"type": "object", "required": ["reason"], "additionalProperties": false, "properties": {"reason": {"type": "string", "minLength": 3, "maxLength": 500}, "delivery_ids": {"type": "array", "maxItems": 100, "uniqueItems": true, "items": {"type": "string", "format": "uuid"}}}},
      "InboxStateRequest": {"type": "object", "properties": {"installation_id": {"type": "string", "format": "uuid"}, "user_id": {"type": "string"}, "snoozed_until": {"type": "string", "format": "date-time"}, "state_version": {"type": "integer", "minimum": 0}}, "description": "Exactly one installation_id or user_id is required. state_version enables optimistic concurrency."},
      "InboxReadAllRequest": {"type": "object", "required": ["installation_id"], "additionalProperties": false, "properties": {"installation_id": {"type": "string", "format": "uuid"}, "feed": {"type": "string", "maxLength": 200}, "before_at": {"type": "string", "format": "date-time"}}},
      "InboxActionRequest": {"type": "object", "required": ["action"], "properties": {"installation_id": {"type": "string", "format": "uuid"}, "user_id": {"type": "string"}, "action": {"type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[A-Za-z0-9._-]+$"}, "input": {"type": "object"}}, "description": "Exactly one installation_id or user_id is required. The action must be declared on the notification; identical repeats are replay-safe."},
      "InboxRelationRequest": {"type": "object", "required": ["key"], "additionalProperties": false, "properties": {"installation_id": {"type": "string", "format": "uuid"}, "app_id": {"type": "string", "format": "uuid"}, "user_id": {"type": "string"}, "key": {"type": "string", "minLength": 1, "maxLength": 200}, "muted_until": {"type": "string", "format": "date-time"}, "state_version": {"type": "integer", "minimum": 0}}, "description": "Exactly one installation_id or user_id is required. app_id is required with user_id and optional with installation_id. state_version enables optimistic concurrency."},
      "SDKConfigurationRequest": {"type": "object", "additionalProperties": false, "properties": {"protocol_min": {"type": "integer", "minimum": 1, "maximum": 255, "default": 1}, "protocol_max": {"type": "integer", "minimum": 1, "maximum": 255, "default": 1}, "minimum_sdk_versions": {"type": "object", "maxProperties": 40, "additionalProperties": {"type": "string", "pattern": "^v?[0-9]+(?:\\.[0-9]+){0,3}(?:[-+][0-9A-Za-z.-]+)?$"}}, "configuration": {"type": "object", "description": "Secret-free bounded runtime settings. Credential-shaped keys are rejected recursively."}, "refresh_after_seconds": {"type": "integer", "minimum": 60, "maximum": 86400, "default": 3600}}},
      "EnvironmentConfiguration": {"type": "object", "additionalProperties": false, "properties": {"origin_allowlist": {"type": "array", "maxItems": 100, "uniqueItems": true, "items": {"type": "string", "format": "uri"}}, "apns_topic": {"type": "string", "maxLength": 255}, "android_package": {"type": "string", "maxLength": 255}, "sandbox_mode": {"type": "boolean"}, "test_user_allowlist": {"type": "array", "maxItems": 500, "uniqueItems": true, "items": {"type": "string", "maxLength": 200}}, "sdk_configuration": {"$ref": "#/components/schemas/SDKConfigurationRequest"}}, "description": "Secret-free environment configuration. Provider credentials, API keys, users, installations, tokens, and provider endpoints are excluded by construction."},
      "EnvironmentSnapshotRequest": {"type": "object", "additionalProperties": false, "properties": {"configuration": {"$ref": "#/components/schemas/EnvironmentConfiguration"}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 160}}, "description": "Omit configuration to capture authoritative current state; include it for configuration-as-code validation and immutable staging."},
      "EnvironmentCloneRequest": {"type": "object", "required": ["name", "environment"], "additionalProperties": false, "properties": {"name": {"type": "string", "minLength": 1, "maxLength": 160}, "environment": {"type": "string", "enum": ["development", "preview", "staging"]}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 160}}},
      "EnvironmentPromotionRequest": {"type": "object", "required": ["source_app_id", "target_app_id", "reason"], "additionalProperties": false, "properties": {"source_app_id": {"type": "string", "format": "uuid"}, "target_app_id": {"type": "string", "format": "uuid"}, "snapshot_id": {"type": "string", "format": "uuid", "description": "Optional immutable configuration-as-code snapshot; current source state is snapshotted when omitted."}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 160}}},
      "EnvironmentPromotionDecision": {"type": "object", "required": ["confirm", "reason"], "additionalProperties": false, "properties": {"confirm": {"type": "boolean", "const": true}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}}},
      "UserProfileRequest": {"type": "object", "required": ["app_id"], "additionalProperties": false, "anyOf": [{"required": ["external_id"]}, {"required": ["authvio_subject"]}], "properties": {"app_id": {"type": "string", "format": "uuid"}, "external_id": {"type": "string", "minLength": 1, "maxLength": 300}, "authvio_subject": {"type": "string", "minLength": 1, "maxLength": 300}, "locale": {"type": "string", "maxLength": 35}, "timezone": {"type": "string", "maxLength": 100}, "country": {"type": "string", "pattern": "^[A-Z]{2}$"}, "preferred_language": {"type": "string", "maxLength": 35}, "attributes": {"type": "object"}, "computed_traits": {"type": "object"}, "notification_risk_state": {"type": "string", "enum": ["normal", "elevated", "high", "blocked"], "default": "normal"}, "engagement_score": {"type": "number", "minimum": 0, "maximum": 100}, "last_activity_at": {"type": "string", "format": "date-time"}, "last_notification_interaction_at": {"type": "string", "format": "date-time"}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 160}}},
      "UserProfilePatch": {"type": "object", "required": ["expected_version"], "additionalProperties": false, "properties": {"external_id": {"type": "string", "maxLength": 300}, "authvio_subject": {"type": "string", "maxLength": 300}, "locale": {"type": "string", "maxLength": 35}, "timezone": {"type": "string", "maxLength": 100}, "country": {"type": "string", "pattern": "^[A-Z]{2}$"}, "preferred_language": {"type": "string", "maxLength": 35}, "attributes": {"type": "object"}, "computed_traits": {"type": "object"}, "notification_risk_state": {"type": "string", "enum": ["normal", "elevated", "high", "blocked"]}, "engagement_score": {"type": "number", "minimum": 0, "maximum": 100}, "last_activity_at": {"type": "string", "format": "date-time"}, "last_notification_interaction_at": {"type": "string", "format": "date-time"}, "expected_version": {"type": "integer", "minimum": 1}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 160}}},
      "UserForgetRequest": {"type": "object", "required": ["confirm", "reason"], "additionalProperties": false, "properties": {"confirm": {"const": true}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 160}}},
      "UserAliasRequest": {"type": "object", "required": ["kind", "value"], "additionalProperties": false, "properties": {"kind": {"type": "string", "enum": ["external_id", "anonymous_id", "authvio_subject", "email_hash", "phone_hash", "application_identity", "custom"]}, "value": {"type": "string", "minLength": 1, "maxLength": 300, "description": "Email and phone aliases must be lowercase SHA-256 values; raw addresses are rejected."}}},
      "UserRelationshipRequest": {"type": "object", "required": ["kind", "target_type", "target_key"], "additionalProperties": false, "properties": {"kind": {"type": "string", "enum": ["organization_membership", "household", "account", "application_identity", "custom"]}, "target_type": {"type": "string", "enum": ["organization", "user", "household", "account", "application", "custom"]}, "target_key": {"type": "string", "minLength": 1, "maxLength": 300}, "related_user_id": {"type": "string", "format": "uuid", "description": "Required exactly when target_type is user."}, "attributes": {"type": "object"}}},
      "IdentityMergePreviewRequest": {"type": "object", "required": ["primary_user", "users"], "additionalProperties": false, "properties": {"primary_user": {"type": "string", "minLength": 1, "maxLength": 300}, "users": {"type": "array", "minItems": 1, "maxItems": 999, "uniqueItems": true, "items": {"type": "string", "minLength": 1, "maxLength": 300}}}},
      "IdentitySplitPreviewRequest": {"type": "object", "required": ["cluster_user", "users", "new_primary"], "additionalProperties": false, "properties": {"cluster_user": {"type": "string", "minLength": 1, "maxLength": 300}, "users": {"type": "array", "minItems": 1, "maxItems": 999, "uniqueItems": true, "items": {"type": "string", "minLength": 1, "maxLength": 300}}, "new_primary": {"type": "string", "minLength": 1, "maxLength": 300}}},
      "IdentityOperationRequest": {"type": "object", "required": ["preview_id", "confirm", "reason"], "additionalProperties": false, "properties": {"preview_id": {"type": "string", "format": "uuid"}, "confirm": {"const": true}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "IdentityHistoryTransferRequest": {"type": "object", "required": ["confirm", "reason", "expected_profile_version", "expected_session_generation"], "additionalProperties": false, "properties": {"confirm": {"const": true}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}, "expected_profile_version": {"type": "integer", "minimum": 1}, "expected_session_generation": {"type": "integer", "minimum": 1}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "IdentityDeviceLifecycleRequest": {"type": "object", "required": ["confirm", "reason", "expected_session_generation"], "additionalProperties": false, "properties": {"confirm": {"const": true}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}, "expected_session_generation": {"type": "integer", "minimum": 1}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "IdentitySyncSourceRequest": {"type": "object", "required": ["name", "category", "adapter", "external_source_id"], "additionalProperties": false, "properties": {"name": {"type": "string", "minLength": 1, "maxLength": 120}, "category": {"type": "string", "enum": ["scim", "crm", "cdp"]}, "adapter": {"type": "string", "enum": ["scim", "salesforce", "hubspot", "dynamics", "segment", "rudderstack", "mparticle", "generic_crm", "generic_cdp"]}, "external_source_id": {"type": "string", "minLength": 1, "maxLength": 200}, "field_mappings": {"type": "object", "additionalProperties": {"type": "string", "pattern": "^[A-Za-z0-9_:-]+(?:\\.[A-Za-z0-9_:-]+){0,7}$"}}, "default_values": {"type": "object"}, "conflict_policy": {"type": "string", "enum": ["reject", "source_wins", "newer_wins"], "default": "reject"}, "deprovision_policy": {"type": "string", "enum": ["block", "unlink"], "default": "block"}, "credential_ref": {"type": "string", "format": "uri", "maxLength": 500, "description": "External vault or key-manager reference only; never credential material"}}},
      "IdentitySyncJobRequest": {"type": "object", "required": ["mode", "expected_cursor_version"], "additionalProperties": false, "properties": {"mode": {"type": "string", "enum": ["full", "incremental"]}, "start_cursor": {"type": "string", "maxLength": 2000}, "next_cursor": {"type": "string", "maxLength": 2000}, "expected_cursor_version": {"type": "integer", "minimum": 0}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "IdentitySyncRecordRequest": {"type": "object", "required": ["source_record_id"], "additionalProperties": false, "properties": {"source_record_id": {"type": "string", "minLength": 1, "maxLength": 300}, "source_version": {"type": "string", "maxLength": 300}, "source_updated_at": {"type": "string", "format": "date-time"}, "operation": {"type": "string", "enum": ["upsert", "deactivate"], "default": "upsert"}, "data": {"type": "object"}}},
      "IdentitySyncBatchRequest": {"type": "object", "required": ["batch_key", "records"], "additionalProperties": false, "properties": {"batch_key": {"type": "string", "minLength": 1, "maxLength": 200}, "records": {"type": "array", "minItems": 1, "maxItems": 500, "items": {"$ref": "#/components/schemas/IdentitySyncRecordRequest"}}}},
      "SCIMUserRequest": {"type": "object", "required": ["userName"], "properties": {"schemas": {"type": "array", "items": {"type": "string"}}, "userName": {"type": "string", "minLength": 1, "maxLength": 300}, "externalId": {"type": "string", "maxLength": 300}, "active": {"type": "boolean"}, "locale": {"type": "string"}, "preferredLanguage": {"type": "string"}, "timezone": {"type": "string"}, "emails": {"type": "array", "items": {"type": "object"}}, "phoneNumbers": {"type": "array", "items": {"type": "object"}}}},
      "SCIMGroupRequest": {"type": "object", "required": ["displayName"], "properties": {"schemas": {"type": "array", "items": {"type": "string"}}, "displayName": {"type": "string", "minLength": 1, "maxLength": 300}, "externalId": {"type": "string", "maxLength": 300}, "members": {"type": "array", "maxItems": 10000, "items": {"type": "object", "required": ["value"], "properties": {"value": {"type": "string", "minLength": 1, "maxLength": 300}}}}}},
      "SCIMPatchRequest": {"type": "object", "required": ["Operations"], "properties": {"schemas": {"type": "array", "items": {"type": "string"}}, "Operations": {"type": "array", "minItems": 1, "maxItems": 100, "items": {"type": "object", "required": ["op"], "properties": {"op": {"type": "string", "enum": ["add", "replace", "remove"]}, "path": {"type": "string"}, "value": {}}}}}},
      "ConfirmedReason": {"type": "object", "required": ["confirm", "reason"], "additionalProperties": false, "properties": {"confirm": {"const": true}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}}},
      "WorkspaceTemplateCreateRequest": {"type": "object", "required": ["key", "name"], "additionalProperties": false, "properties": {"key": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,79}$"}, "name": {"type": "string", "minLength": 1, "maxLength": 160}, "description": {"type": "string", "maxLength": 2000}}},
      "WorkspaceTemplateApplication": {"type": "object", "required": ["name", "environment"], "additionalProperties": false, "properties": {"name": {"type": "string", "minLength": 1, "maxLength": 160}, "environment": {"type": "string", "enum": ["development", "preview", "staging", "production"]}, "origin_allowlist": {"type": "array", "maxItems": 100, "uniqueItems": true, "items": {"type": "string", "format": "uri"}}, "apns_topic": {"type": "string", "maxLength": 255}, "android_package": {"type": "string", "maxLength": 255}, "sandbox_mode": {"type": "boolean", "description": "Required true for every non-production environment; defaults true outside production."}, "test_user_allowlist": {"type": "array", "maxItems": 500, "uniqueItems": true, "items": {"type": "string", "minLength": 1, "maxLength": 200}}, "sdk_configuration": {"$ref": "#/components/schemas/SDKConfigurationRequest"}}},
      "WorkspaceTemplateSpecification": {"type": "object", "required": ["applications"], "additionalProperties": false, "properties": {"applications": {"type": "array", "minItems": 1, "maxItems": 20, "items": {"$ref": "#/components/schemas/WorkspaceTemplateApplication"}}}},
      "WorkspaceTemplateVersionRequest": {"type": "object", "required": ["specification", "change_note"], "additionalProperties": false, "properties": {"specification": {"$ref": "#/components/schemas/WorkspaceTemplateSpecification"}, "change_note": {"type": "string", "minLength": 3, "maxLength": 1000}}},
      "WorkspaceTemplatePublicationRequest": {"type": "object", "required": ["reason"], "additionalProperties": false, "properties": {"reason": {"type": "string", "minLength": 3, "maxLength": 1000}}},
      "WorkspaceTemplatePublicationDecision": {"type": "object", "required": ["confirm", "reason"], "additionalProperties": false, "properties": {"confirm": {"type": "boolean", "const": true}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}}},
      "WorkspaceTemplateInstantiationRequest": {"type": "object", "required": ["project_name"], "additionalProperties": false, "properties": {"project_name": {"type": "string", "minLength": 1, "maxLength": 160}, "project_slug": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,79}$"}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 160}}},
      "SDKNegotiationRequest": {"type": "object", "required": ["sdk", "sdk_version", "protocol_version"], "additionalProperties": false, "properties": {"sdk": {"type": "string", "pattern": "^[a-z][a-z0-9._-]{0,63}$"}, "sdk_version": {"type": "string", "pattern": "^v?[0-9]+(?:\\.[0-9]+){0,3}(?:[-+][0-9A-Za-z.-]+)?$"}, "protocol_version": {"type": "integer", "minimum": 1, "maximum": 255}, "adapters": {"type": "array", "maxItems": 20, "uniqueItems": true, "items": {"type": "string", "pattern": "^[a-z][a-z0-9._-]{0,63}$"}}, "capabilities": {"type": "object", "description": "Bounded secret-free capability declaration"}, "configuration_checksum": {"type": "string", "pattern": "^[0-9a-f]{64}$"}}},
      "TokenRotationRequest": {"type": "object", "required": ["push_provider"], "additionalProperties": false, "properties": {"push_provider": {"type": "string", "enum": ["apns", "fcm", "webpush"]}, "token": {"type": "string"}, "endpoint": {"type": "string", "format": "uri"}, "p256dh": {"type": "string"}, "auth": {"type": "string"}}, "description": "APNs/FCM require token. Web Push requires endpoint, p256dh and auth. Raw credential values are never written to lifecycle evidence."},
      "SDKHealthRequest": {"type": "object", "required": ["status", "protocol_version", "sdk_version"], "additionalProperties": false, "properties": {"status": {"type": "string", "enum": ["healthy", "degraded", "error"]}, "protocol_version": {"type": "integer", "minimum": 1, "maximum": 255}, "sdk_version": {"type": "string", "pattern": "^v?[0-9]+(?:\\.[0-9]+){0,3}(?:[-+][0-9A-Za-z.-]+)?$"}, "offline_queue_depth": {"type": "integer", "minimum": 0, "maximum": 10000, "default": 0}, "dropped_events": {"type": "integer", "minimum": 0, "maximum": 1000000000, "default": 0}, "last_success_at": {"type": "string", "format": "date-time"}, "last_token_refresh_at": {"type": "string", "format": "date-time"}, "configuration_checksum": {"type": "string", "pattern": "^[0-9a-f]{64}$"}, "capabilities_checksum": {"type": "string", "pattern": "^[0-9a-f]{64}$"}, "error_codes": {"type": "array", "maxItems": 20, "uniqueItems": true, "items": {"type": "string", "pattern": "^[a-z][a-z0-9._-]{0,79}$"}}, "evidence": {"type": "object", "description": "Bounded secret-free diagnostics; identifiers and credential-shaped keys are rejected"}}},
      "InstallationPreferenceRequest": {"type": "object", "required": ["opted_in"], "additionalProperties": false, "properties": {"opted_in": {"type": "boolean"}, "expected_state_version": {"type": "integer", "minimum": 0}, "legal_basis": {"type": "string", "maxLength": 120}, "purpose": {"type": "string", "maxLength": 500}, "policy_version": {"type": "string", "maxLength": 120}, "expires_at": {"type": "string", "format": "date-time"}}},
      "InstallationRequest": {"type": "object", "required": ["app_id", "device_id", "platform", "push_provider"], "properties": {"app_id": {"type": "string", "format": "uuid"}, "user_id": {"type": "string"}, "anonymous_id": {"type": "string"}, "device_id": {"type": "string"}, "platform": {"type": "string", "enum": ["ios", "ipados", "macos", "android", "web"]}, "push_provider": {"type": "string", "enum": ["apns", "fcm", "webpush", "sse", "none"]}, "environment": {"type": "string", "enum": ["development", "preview", "staging", "production"]}, "permission_state": {"type": "string", "enum": ["unknown", "granted", "denied", "provisional", "ephemeral"]}, "token": {"type": "string"}, "endpoint": {"type": "string", "format": "uri"}, "p256dh": {"type": "string"}, "auth": {"type": "string"}, "capabilities": {"type": "object"}, "identity_token": {"type": "string", "description": "From a client (browser, publishable key, native app): required with user_id when the app's identity verification is \"required\". A JWT (HS256) your backend signs with the app's identity key; see IdentityToken."}}},
      "InstallationUpdate": {"type": "object", "properties": {"user_id": {"type": "string", "description": "Empty string logs the installation out (no token needed)."}, "identity_token": {"type": "string", "description": "Required with a non-empty user_id when the app's identity verification is \"required\"."}, "anonymous_id": {"type": "string"}, "permission_state": {"type": "string"}, "capabilities": {"type": "object"}, "app_version": {"type": "string"}, "sdk_version": {"type": "string"}}},
      "IdentityToken": {"type": "string", "description": "Compact JWS, alg HS256, header {alg, typ: JWT, kid}. Claims: iss = app id, aud = \"bolrach:push:identity\", sub = the user id exactly as sent in user_id, inst = installation id (or did = device id at registration), iat, exp (exp - iat <= 900 s), jti (unique; each is accepted once). Signed with the app's identity key secret (UTF-8 bytes) from POST /apps/{id}/identity-keys:rotate. Mint it on your backend for the signed-in member only; never ship the secret in an app or a page."},
      "IdentityVerification": {"type": "object", "properties": {"mode": {"type": "string", "enum": ["report", "required"]}, "key_ids": {"type": "array", "items": {"type": "string"}}, "audience": {"type": "string"}, "max_lifetime_seconds": {"type": "integer"}}},
      "ChannelConnectorRequest": {"type": "object", "required": ["channel", "provider", "name", "config"], "properties": {"channel": {"$ref": "#/components/parameters/Channel/schema"}, "provider": {"type": "string", "enum": ["mailtaz", "twilio", "meta_whatsapp", "google_rcs", "http_json", "custom"]}, "name": {"type": "string"}, "endpoint_url": {"type": "string", "format": "uri", "pattern": "^https://"}, "priority": {"type": "integer", "minimum": 0, "maximum": 1000}, "timeout_ms": {"type": "integer", "minimum": 1000, "maximum": 60000}, "max_attempts": {"type": "integer", "minimum": 1, "maximum": 20}, "capabilities": {"type": "object"}, "config": {"type": "object", "description": "Provider credentials; encrypted at rest and never returned"}}},
      "ChannelMessageRequest": {"type": "object", "required": ["app_id", "channel", "content"], "properties": {"app_id": {"type": "string", "format": "uuid"}, "user_id": {"type": "string", "format": "uuid", "description": "Required for marketing so consent can be evaluated"}, "channel": {"type": "string", "enum": ["email", "sms", "whatsapp", "rcs", "slack", "teams", "discord", "custom"]}, "destination": {"type": "string", "description": "Optional when a verified user destination exists"}, "category": {"type": "string"}, "priority": {"type": "integer", "minimum": 0, "maximum": 4, "default": 3}, "content": {"type": "object"}, "idempotency_key": {"type": "string", "maxLength": 200}, "trace_id": {"type": "string"}, "scheduled_for": {"type": "string", "format": "date-time"}, "expires_in_seconds": {"type": "integer", "minimum": 1, "maximum": 2419200}}},
      "ChannelReceipt": {"type": "object", "required": ["provider_event_id", "state"], "properties": {"provider_event_id": {"type": "string"}, "state": {"type": "string", "enum": ["provider_accepted", "delivered", "read", "failed"]}, "occurred_at": {"type": "string", "format": "date-time"}, "payload": {"type": "object"}}},
      "MigrationSourceRequest": {"type": "object", "required": ["provider", "name", "configuration"], "properties": {"provider": {"type": "string", "enum": ["onesignal", "firebase", "knock", "novu", "courier", "braze", "airship", "csv", "api", "database"]}, "name": {"type": "string"}, "configuration": {"type": "object", "description": "Source credentials and connection details; envelope-encrypted and never returned"}, "mapping": {"type": "object", "additionalProperties": {"type": "string"}}}},
      "MigrationJobRequest": {"type": "object", "required": ["mode", "idempotency_key"], "properties": {"mode": {"type": "string", "enum": ["validate", "apply"]}, "idempotency_key": {"type": "string"}, "input_checksum": {"type": "string"}}},
      "MigrationBatchRequest": {"type": "object", "required": ["idempotency_key", "records"], "properties": {"idempotency_key": {"type": "string"}, "records": {"type": "array", "minItems": 1, "maxItems": 1000, "items": {"type": "object", "additionalProperties": true}}}},
      "ShadowEvaluationRequest": {"type": "object", "required": ["request", "baseline", "source_provider", "idempotency_key"], "properties": {"request": {"$ref": "#/components/schemas/SendRequest"}, "baseline": {"type": "object", "description": "Source-system audience, suppression, channel, and canonical render result"}, "source_provider": {"type": "string"}, "idempotency_key": {"type": "string"}}},
      "DualRunConfigRequest": {"type": "object", "required": ["source_provider", "allocation_bps", "status"], "properties": {"source_provider": {"type": "string", "enum": ["onesignal", "firebase", "knock", "novu", "courier", "braze", "airship", "api", "database"]}, "allocation_bps": {"type": "integer", "minimum": 0, "maximum": 10000}, "status": {"type": "string", "enum": ["active", "paused", "completed"]}}},
      "DualRunRouteRequest": {"type": "object", "required": ["request", "source_provider", "idempotency_key", "cohort_key"], "properties": {"request": {"$ref": "#/components/schemas/SendRequest"}, "source_provider": {"type": "string"}, "source_message_id": {"type": "string"}, "idempotency_key": {"type": "string"}, "cohort_key": {"type": "string", "description": "Stable user or account key; stored only as SHA-256"}}},
      "DualRunSourceResult": {"type": "object", "required": ["provider_event_id", "state", "occurred_at"], "properties": {"provider_event_id": {"type": "string"}, "source_message_id": {"type": "string"}, "state": {"type": "string", "enum": ["accepted", "delivered", "opened", "failed"]}, "occurred_at": {"type": "string", "format": "date-time"}, "latency_ms": {"type": "integer", "minimum": 0}, "cost_minor": {"type": "integer", "minimum": 0}, "currency": {"type": "string"}}},
      "ExperimentVariant": {"type": "object", "required": ["key", "weight_basis_points"], "additionalProperties": false, "properties": {"key": {"type": "string", "minLength": 1, "maxLength": 100}, "weight_basis_points": {"type": "integer", "minimum": 1, "maximum": 10000}, "control": {"type": "boolean", "default": false}, "specification": {"type": "object"}}},
      "ExperimentMetric": {"type": "object", "required": ["key", "event_name"], "additionalProperties": false, "properties": {"key": {"type": "string", "minLength": 1, "maxLength": 100}, "kind": {"type": "string", "enum": ["objective", "guardrail"], "default": "objective"}, "event_name": {"type": "string", "minLength": 1, "maxLength": 200}, "aggregation": {"type": "string", "enum": ["conversion_rate", "mean_value"], "default": "conversion_rate"}, "direction": {"type": "string", "enum": ["maximize", "minimize"], "default": "maximize"}, "minimum_effect": {"type": "number", "minimum": 0, "maximum": 1}, "maximum_regression": {"type": "number", "minimum": 0, "maximum": 1}, "currency": {"type": "string", "pattern": "^[A-Z]{3}$"}}},
      "ExperimentDefinition": {"type": "object", "required": ["app_id", "key", "name", "goal_event", "variants"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "key": {"type": "string", "minLength": 1, "maxLength": 100}, "name": {"type": "string", "minLength": 1, "maxLength": 200}, "goal_event": {"type": "string", "minLength": 1, "maxLength": 200}, "kind": {"type": "string", "enum": ["ab", "abn", "multivariate", "subject", "body", "image", "action", "send_time", "channel", "frequency", "workflow_path", "rollout"], "default": "abn"}, "assignment_unit": {"type": "string", "enum": ["user", "organization"], "default": "user"}, "mutex_group": {"type": "string", "maxLength": 100}, "holdout_basis_points": {"type": "integer", "minimum": 0, "maximum": 9000}, "minimum_sample_size": {"type": "integer", "minimum": 10, "maximum": 100000000, "default": 100}, "confidence_level": {"type": "number", "minimum": 0.8, "exclusiveMaximum": 1, "default": 0.95}, "minimum_detectable_effect": {"type": "number", "minimum": 0, "maximum": 1, "default": 0.01}, "sequential_max_looks": {"type": "integer", "minimum": 1, "maximum": 100, "default": 10}, "automatic_stop": {"type": "boolean", "default": false}, "stop_rules": {"type": "object", "additionalProperties": false, "properties": {"minimum_look_interval_seconds": {"type": "integer", "minimum": 300, "maximum": 86400}}}, "variants": {"type": "array", "minItems": 1, "items": {"$ref": "#/components/schemas/ExperimentVariant"}}, "metrics": {"type": "array", "minItems": 1, "items": {"$ref": "#/components/schemas/ExperimentMetric"}}}},
      "ExperimentTransition": {"type": "object", "additionalProperties": false, "properties": {"reason": {"type": "string", "maxLength": 1000}}},
      "ExperimentSubject": {"type": "object", "required": ["app_id", "subject_type", "subject_id"], "properties": {"app_id": {"type": "string", "format": "uuid"}, "subject_type": {"type": "string", "enum": ["user", "organization"]}, "subject_id": {"type": "string", "minLength": 1, "maxLength": 500}}},
      "ExperimentExposure": {"allOf": [{"$ref": "#/components/schemas/ExperimentSubject"}, {"type": "object", "required": ["source_type"], "properties": {"source_type": {"type": "string", "minLength": 1, "maxLength": 100}, "source_id": {"type": "string", "maxLength": 500}, "exposed_at": {"type": "string", "format": "date-time"}}}]},
      "ExperimentObservation": {"allOf": [{"$ref": "#/components/schemas/ExperimentSubject"}, {"type": "object", "required": ["metric"], "properties": {"metric": {"type": "string", "minLength": 1, "maxLength": 200}, "value": {"type": "number", "default": 1}, "currency": {"type": "string", "pattern": "^[A-Z]{3}$"}, "occurred_at": {"type": "string", "format": "date-time"}, "evidence": {"type": "object", "description": "Bounded non-personal supporting data; identifiers remain subject-hashed server-side"}}}]},
      "ExperimentWinnerDecision": {"type": "object", "required": ["variant_key", "reason"], "additionalProperties": false, "properties": {"variant_key": {"type": "string", "minLength": 1, "maxLength": 100}, "reason": {"type": "string", "minLength": 3, "maxLength": 1000}, "confirm": {"type": "boolean", "description": "Required true only for approval"}}},
      "AnalyticsPolicy": {"type": "object", "required": ["retention_days", "minimum_group_size", "user_level_analytics", "mask_ip", "deletion_propagation"], "additionalProperties": false, "properties": {"retention_days": {"type": "integer", "minimum": 1, "maximum": 3650}, "minimum_group_size": {"type": "integer", "minimum": 1, "maximum": 10000}, "user_level_analytics": {"type": "boolean", "default": false}, "mask_ip": {"type": "boolean", "default": true}, "deletion_propagation": {"type": "boolean", "default": true}}},
      "AttributionModelRequest": {"type": "object", "required": ["app_id", "key", "name", "model", "attribution_window_seconds", "idempotency_key"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "key": {"type": "string", "pattern": "^[a-z][a-z0-9_-]{0,99}$"}, "name": {"type": "string", "minLength": 1, "maxLength": 200}, "model": {"type": "string", "enum": ["first_touch", "last_touch", "linear", "time_decay", "position_based"]}, "attribution_window_seconds": {"type": "integer", "minimum": 60, "maximum": 7776000}, "direct_open_window_seconds": {"type": "integer", "minimum": 60, "maximum": 604800, "default": 3600}, "influenced_open_window_seconds": {"type": "integer", "minimum": 60, "maximum": 2592000, "default": 86400}, "touchpoints": {"type": "array", "minItems": 1, "maxItems": 10, "uniqueItems": true, "items": {"type": "string", "enum": ["ACTION_CLICKED", "OPENED", "DISPLAYED", "DEVICE_RECEIVED", "PROVIDER_ACCEPTED"]}}, "idempotency_key": {"type": "string", "minLength": 1, "maxLength": 200}}},
      "ApprovalDecision": {"type": "object", "required": ["idempotency_key"], "additionalProperties": false, "properties": {"idempotency_key": {"type": "string", "minLength": 1, "maxLength": 200}, "reason": {"type": "string", "maxLength": 1000}}},
      "ReportType": {"type": "string", "enum": ["delivery_funnel", "engagement_funnel", "breakdown", "campaign_comparison", "channel_comparison", "cohort", "retention", "journey", "fatigue", "revenue_cost", "experiment", "anomaly", "forecast"]},
      "ReportParameters": {"type": "object", "additionalProperties": false, "properties": {"dimension": {"type": "string", "enum": ["provider", "platform", "app_version", "country", "timezone", "channel", "priority", "status"]}, "currency": {"type": "string", "pattern": "^[A-Z]{3}$"}}},
      "ReportDefinitionRequest": {"type": "object", "required": ["app_id", "key", "name", "report_type"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "key": {"type": "string", "pattern": "^[a-z][a-z0-9_-]{0,99}$"}, "name": {"type": "string", "minLength": 1, "maxLength": 200}, "report_type": {"$ref": "#/components/schemas/ReportType"}, "parameters": {"$ref": "#/components/schemas/ReportParameters"}, "schedule_seconds": {"type": "integer", "minimum": 300, "maximum": 2678400}}},
      "ReportRunRequest": {"type": "object", "required": ["idempotency_key"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "report_definition_id": {"type": "string", "format": "uuid"}, "report_type": {"$ref": "#/components/schemas/ReportType"}, "parameters": {"$ref": "#/components/schemas/ReportParameters"}, "range_start": {"type": "string", "format": "date-time"}, "range_end": {"type": "string", "format": "date-time"}, "idempotency_key": {"type": "string", "minLength": 1, "maxLength": 200}}},
      "DataExportRequest": {"type": "object", "required": ["app_id", "report_run_id", "format", "idempotency_key"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "report_run_id": {"type": "string", "format": "uuid"}, "format": {"type": "string", "enum": ["csv", "jsonl"]}, "idempotency_key": {"type": "string", "minLength": 1, "maxLength": 200}}},
      "EventDestinationRequest": {"type": "object", "required": ["app_id", "key", "name", "kind", "configuration"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "key": {"type": "string", "pattern": "^[a-z][a-z0-9_-]{0,99}$"}, "name": {"type": "string", "minLength": 1, "maxLength": 200}, "kind": {"type": "string", "enum": ["signed_https", "amazon_kinesis", "google_pubsub", "azure_event_hubs", "kafka", "redpanda", "amazon_sqs", "google_bigquery", "snowflake", "databricks", "clickhouse", "postgresql", "cloudflare_r2", "amazon_s3", "segment", "analytics", "siem"]}, "event_types": {"type": "array", "minItems": 1, "maxItems": 200, "uniqueItems": true, "items": {"type": "string"}}, "field_selection": {"type": "array", "maxItems": 100, "uniqueItems": true, "items": {"type": "string"}}, "pii_mode": {"type": "string", "enum": ["remove", "mask", "hash"], "default": "remove"}, "configuration": {"type": "object", "description": "Envelope-encrypted and never returned. signed_https requires a public HTTPS url; optional secret is generated when omitted. Optional client_certificate_pem and client_private_key_pem enable mTLS and must be supplied together."}, "max_attempts": {"type": "integer", "minimum": 1, "maximum": 20, "default": 8}, "start_sequence": {"type": "integer", "minimum": 1, "description": "Optional bounded initial backfill; rejected above 10,000 matching events."}}},
      "EventReplayRequest": {"type": "object", "required": ["from_sequence", "to_sequence", "reason", "confirm", "idempotency_key"], "additionalProperties": false, "properties": {"from_sequence": {"type": "integer", "minimum": 1}, "to_sequence": {"type": "integer", "minimum": 1, "description": "Inclusive and at most 9,999 after from_sequence."}, "event_types": {"type": "array", "maxItems": 200, "uniqueItems": true, "items": {"type": "string"}}, "reason": {"type": "string", "minLength": 1, "maxLength": 1000}, "confirm": {"const": true}, "idempotency_key": {"type": "string", "minLength": 1, "maxLength": 200}}},
      "EventSchemaRequest": {"type": "object", "required": ["app_id", "event_type", "schema"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "event_type": {"type": "string", "pattern": "^[a-z][a-z0-9_.-]{0,127}$"}, "schema": {"type": "object", "description": "Bounded JSON Schema object subset: object properties, required, primitive types, and additionalProperties."}, "pii_fields": {"type": "array", "maxItems": 100, "uniqueItems": true, "items": {"type": "string", "description": "Dot path in the canonical event payload, for example properties.email."}}}},
      "LiveTokenRequest": {"type": "object", "required": ["token_kind", "token", "idempotency_key"], "additionalProperties": false, "properties": {"token_kind": {"type": "string", "enum": ["apple_activity", "apple_push_to_start"]}, "token": {"type": "string", "minLength": 16, "maxLength": 8192}, "external_id": {"type": "string", "maxLength": 200}, "attributes_type": {"type": "string", "maxLength": 200}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}, "description": "ActivityKit token registration. external_id is required for apple_activity; raw tokens are envelope-encrypted and never returned."},
      "LiveEventSubscriptionRequest": {"type": "object", "required": ["event_key", "enabled"], "additionalProperties": false, "properties": {"event_key": {"type": "string", "minLength": 1, "maxLength": 200}, "enabled": {"type": "boolean"}, "categories": {"type": "array", "maxItems": 50, "uniqueItems": true, "items": {"type": "string", "maxLength": 100}}, "starts_at": {"type": "string", "format": "date-time"}, "ends_at": {"type": "string", "format": "date-time"}}},
      "LiveLifecycleEventRequest": {"type": "object", "required": ["live_id", "event", "idempotency_key"], "additionalProperties": false, "properties": {"live_id": {"type": "string", "format": "uuid"}, "event": {"type": "string", "enum": ["rendered", "stale", "dismissed", "ended"]}, "rail": {"type": "string", "enum": ["apple_activity", "apple_push_to_start", "android_live", "web_persistent", "in_app", "ordinary_fallback"]}, "sequence": {"type": "integer", "minimum": 0}, "occurred_at": {"type": "string", "format": "date-time"}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}, "evidence": {"type": "object", "description": "Bounded secret-free client lifecycle evidence."}}},
      "LiveNotificationRequest": {"type": "object", "required": ["app_id", "user_id", "external_id", "kind", "content", "idempotency_key"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "user_id": {"type": "string", "minLength": 1, "maxLength": 500}, "external_id": {"type": "string", "minLength": 1, "maxLength": 200}, "kind": {"type": "string", "minLength": 1, "maxLength": 100}, "content": {"type": "object"}, "fallback": {"$ref": "#/components/schemas/MessageContent"}, "expires_at": {"type": "string", "format": "date-time"}, "stale_at": {"type": "string", "format": "date-time"}, "dismissal_at": {"type": "string", "format": "date-time"}, "auto_end_at": {"type": "string", "format": "date-time"}, "min_update_interval_seconds": {"type": "integer", "minimum": 5, "maximum": 3600, "default": 15}, "apple": {"type": "object", "description": "ActivityKit attributes_type and attributes for push-to-start."}, "android": {"type": "object", "description": "Android Live Update style and rendering fields."}, "web": {"type": "object", "description": "Persistent Web Notification rendering fields."}, "preference_category": {"type": "string", "maxLength": 100, "default": "live_updates"}, "event_key": {"type": "string", "maxLength": 200}, "alert": {"type": "object", "description": "Apple start/end alert dictionary."}, "relevance_score": {"type": "number", "minimum": 0, "maximum": 1}, "idempotency_key": {"type": "string", "minLength": 1, "maxLength": 200}}},
      "LiveMutationRequest": {"type": "object", "required": ["idempotency_key"], "additionalProperties": false, "properties": {"content": {"type": "object"}, "fallback": {"$ref": "#/components/schemas/MessageContent"}, "stale_at": {"type": "string", "format": "date-time"}, "dismissal_at": {"type": "string", "format": "date-time"}, "alert": {"type": "object"}, "relevance_score": {"type": "number", "minimum": 0, "maximum": 1}, "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 200}}},
      "LiveSimulationRequest": {"type": "object", "required": ["app_id", "kind", "content"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "external_id": {"type": "string", "maxLength": 200}, "kind": {"type": "string", "minLength": 1, "maxLength": 100}, "content": {"type": "object"}, "apple": {"type": "object"}, "android": {"type": "object"}, "web": {"type": "object"}, "alert": {"type": "object"}, "stale_at": {"type": "string", "format": "date-time"}, "dismissal_at": {"type": "string", "format": "date-time"}, "relevance_score": {"type": "number", "minimum": 0, "maximum": 1}}},
      "LiveTemplateRequest": {"type": "object", "required": ["app_id", "name", "kind", "content"], "additionalProperties": false, "properties": {"app_id": {"type": "string", "format": "uuid"}, "name": {"type": "string", "minLength": 1, "maxLength": 160}, "kind": {"type": "string", "pattern": "^[a-z][a-z0-9._-]{0,63}$"}, "content": {"type": "object"}, "variable_schema": {"type": "object"}, "apple": {"type": "object"}, "android": {"type": "object"}, "web": {"type": "object"}}},
      "DeliveryState": {"type": "string", "enum": ["QUEUED", "SCHEDULED", "DISPATCHING", "RETRYING", "PROVIDER_ACCEPTED", "PROVIDER_REJECTED", "DEVICE_RECEIVED", "DISPLAYED", "OPENED", "CLICKED", "ACTIONED", "CONVERTED", "EXPIRED", "CANCELED", "DEAD_LETTERED"]}
    }
  }
}
