{"openapi":"3.1.0","info":{"title":"Galassify Broadcast — Public integration","description":"Actual implemented operations. Accepted public requests do not prove activation or inbox delivery. Public signup uses no admin cookie or API key. Capability endpoints have their own authority.","version":"0.20.0rc1"},"paths":{"/assets/{storage_key}":{"get":{"summary":"Public Image","operationId":"public_image_assets__storage_key__get","parameters":[{"name":"storage_key","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Storage Key"}}],"responses":{"200":{"description":"Public image or unsubscribe confirmation.","content":{"image/*":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"text/html":{"schema":{"type":"string"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"text/html":{"schema":{"type":"string"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"text/html":{"schema":{"type":"string"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"text/html":{"schema":{"type":"string"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"text/html":{"schema":{"type":"string"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Assets"],"x-required-role":"public/capability","security":[],"description":"Uses the shared domain service and current authorization checks. See the integration/operator walkthrough for the surrounding workflow."}},"/api/v1/public/organisations/{slug}":{"get":{"summary":"Organisation","operationId":"organisation_api_v1_public_organisations__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResultPublicOrganisation"}},"required":["data"]}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Signup"],"x-required-role":"public/capability","security":[],"description":"Exact configured organisation CORS origins only; credentials omitted. Omitted subject_ids selects all; explicit [] is rejected when subjects exist. Generic success depends only on public opt-in mode, not address state."}},"/api/v1/public/organisations/{slug}/subjects":{"get":{"summary":"Subjects","operationId":"subjects_api_v1_public_organisations__slug__subjects_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResultSubjects"}},"required":["data"]}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Signup"],"x-required-role":"public/capability","security":[],"description":"Exact configured organisation CORS origins only; credentials omitted. Omitted subject_ids selects all; explicit [] is rejected when subjects exist. Generic success depends only on public opt-in mode, not address state."}},"/api/v1/public/organisations/{slug}/subscriptions":{"post":{"summary":"Subscribe","operationId":"subscribe_api_v1_public_organisations__slug__subscriptions_post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"},"example":{"email":"reader@example.com","first_name":"Sam"}}}},"responses":{"202":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultGeneric"}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Signup"],"x-required-role":"public/capability","security":[],"description":"Exact configured organisation CORS origins only; credentials omitted. Omitted subject_ids selects all; explicit [] is rejected when subjects exist. Generic success depends only on public opt-in mode, not address state."}},"/api/v1/public/organisations/{slug}/confirmation-requests":{"post":{"summary":"Replacement","operationId":"replacement_api_v1_public_organisations__slug__confirmation_requests_post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRequest"}}}},"responses":{"202":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultGeneric"}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Signup"],"x-required-role":"public/capability","security":[],"description":"Exact configured organisation CORS origins only; credentials omitted. Omitted subject_ids selects all; explicit [] is rejected when subjects exist. Generic success depends only on public opt-in mode, not address state."}},"/api/v1/public/confirmations":{"post":{"summary":"Confirm","operationId":"confirm_api_v1_public_confirmations_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"required":true},"responses":{"200":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResultActivation"}},"required":["data"]}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Signup"],"x-required-role":"public/capability","parameters":[{"name":"Origin","in":"header","required":false,"schema":{"type":"string"},"description":"Required with capability cookie or a browser request."},{"name":"X-CSRF-Token","in":"header","required":false,"schema":{"type":"string"},"description":"Required for browser/cookie activation."}],"security":[],"description":"Token in JSON for server clients, or exchanged broadcast_activation cookie. Browser requests require canonical Origin and broadcast_activation_csrf via X-CSRF-Token. GET links never activate. Disabled organisations cannot activate."}},"/api/v1/public/resubscriptions":{"post":{"summary":"Resubscribe","operationId":"resubscribe_api_v1_public_resubscriptions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resubscription"}}},"required":true},"responses":{"200":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResultActivation"}},"required":["data"]}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Signup"],"x-required-role":"public/capability","parameters":[{"name":"Origin","in":"header","required":false,"schema":{"type":"string"},"description":"Required with capability cookie or a browser request."},{"name":"X-CSRF-Token","in":"header","required":false,"schema":{"type":"string"},"description":"Required for browser/cookie activation."}],"security":[],"description":"Token in JSON for server clients, or exchanged broadcast_activation cookie. Browser requests require canonical Origin and broadcast_activation_csrf via X-CSRF-Token. GET links never activate. Disabled organisations cannot activate."}},"/api/v1/public/preferences-requests":{"post":{"summary":"Request Link","operationId":"request_link_api_v1_public_preferences_requests_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRequest"},"example":{"email":"reader@example.com"}}},"required":true},"responses":{"202":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultGeneric"}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Preferences"],"x-required-role":"public/capability","parameters":[{"name":"Origin","in":"header","required":true,"schema":{"type":"string"},"description":"Exact configured application origin; this endpoint is same-origin, not organisation CORS."}],"security":[],"description":"Same generic 202 for zero/one/multiple associations, cooldown and missing/unhealthy SMTP. One organisation uses its sender; multiple use neutral central mail. Disabled associations remain eligible for preferences only. No source fallback."}},"/api/v1/public/preferences":{"get":{"summary":"Preferences","operationId":"preferences_api_v1_public_preferences_get","responses":{"200":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResultPreferences"}},"required":["data"]}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Preferences"],"x-required-role":"public/capability","parameters":[],"security":[{"PreferencesCapability":[]},{"PreferencesCookie":[]}],"description":"Only existing capability grants. Server clients may use X-Preferences-Token without Origin. Browser/cookie mutations require canonical Origin and scoped X-CSRF-Token; no admin session."}},"/api/v1/public/preferences/{org_id}":{"patch":{"summary":"Update","operationId":"update_api_v1_public_preferences__org_id__patch","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"Origin","in":"header","required":false,"schema":{"type":"string"},"description":"Required for cookie/browser requests."},{"name":"X-CSRF-Token","in":"header","required":false,"schema":{"type":"string"},"description":"Scoped CSRF from the hosted preferences page, required for cookie/browser requests."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Choices"}}}},"responses":{"200":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResultPreferenceChange"}},"required":["data"]}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Preferences"],"x-required-role":"public/capability","security":[{"PreferencesCapability":[]},{"PreferencesCookie":[]}],"description":"Only existing capability grants. Server clients may use X-Preferences-Token without Origin. Browser/cookie mutations require canonical Origin and scoped X-CSRF-Token; no admin session."}},"/api/v1/public/preferences/{org_id}/unsubscribe":{"post":{"summary":"Unsubscribe","operationId":"unsubscribe_api_v1_public_preferences__org_id__unsubscribe_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"Origin","in":"header","required":false,"schema":{"type":"string"},"description":"Required for cookie/browser requests."},{"name":"X-CSRF-Token","in":"header","required":false,"schema":{"type":"string"},"description":"Scoped CSRF from the hosted preferences page, required for cookie/browser requests."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Withdrawal"}}}},"responses":{"200":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResultPreferenceChange"}},"required":["data"]}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Preferences"],"x-required-role":"public/capability","security":[{"PreferencesCapability":[]},{"PreferencesCookie":[]}],"description":"Only existing capability grants. Server clients may use X-Preferences-Token without Origin. Browser/cookie mutations require canonical Origin and scoped X-CSRF-Token; no admin session."}},"/u/{raw}":{"get":{"summary":"Direct Page","operationId":"direct_page_u__raw__get","parameters":[{"name":"raw","in":"path","required":true,"schema":{"type":"string","title":"Raw"}}],"responses":{"200":{"description":"Public image or unsubscribe confirmation.","content":{"text/html":{"schema":{"type":"string"}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"text/html":{"schema":{"type":"string"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"text/html":{"schema":{"type":"string"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"text/html":{"schema":{"type":"string"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"text/html":{"schema":{"type":"string"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"text/html":{"schema":{"type":"string"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Preferences"],"x-required-role":"public/capability","security":[],"description":"Uses the shared domain service and current authorization checks. See the integration/operator walkthrough for the surrounding workflow."},"post":{"summary":"Direct Unsubscribe","operationId":"direct_unsubscribe_u__raw__post","parameters":[{"name":"raw","in":"path","required":true,"schema":{"type":"string","title":"Raw"}}],"responses":{"200":{"description":"Successful result. 202 means durable processing, not delivery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultUnsubscribe"}},"text/html":{"schema":{"type":"string"}}}},"403":{"description":"Role, origin or CSRF denied.","content":{"text/html":{"schema":{"type":"string"}}}},"404":{"description":"Missing or inaccessible resource; tenant existence is not disclosed.","content":{"text/html":{"schema":{"type":"string"}}}},"409":{"description":"Conflict, stale revision/confirmation, disabled organisation or invalid transition.","content":{"text/html":{"schema":{"type":"string"}}}},"410":{"description":"Expired operation or invalid/expired capability.","content":{"text/html":{"schema":{"type":"string"}}}},"413":{"description":"Request or upload exceeds its limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"415":{"description":"Unsupported content type.","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation failed; unknown mutation fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}},"429":{"description":"Rate limited; obey Retry-After.","content":{"text/html":{"schema":{"type":"string"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until retry."}}},"503":{"description":"Request could not be durably processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultError"}}}}},"tags":["Preferences"],"x-required-role":"public/capability","security":[],"description":"Uses the shared domain service and current authorization checks. See the integration/operator walkthrough for the surrounding workflow.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"List-Unsubscribe":{"const":"One-Click"}},"required":["List-Unsubscribe"]}}}}}},"/health/live":{"get":{"summary":"Live","operationId":"live_health_live_get","responses":{"200":{"description":"Healthy probe.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultProbe"}}}}},"tags":["Main"],"x-required-role":"public/capability","parameters":[],"security":[],"description":"Uses the shared domain service and current authorization checks. See the integration/operator walkthrough for the surrounding workflow."}},"/health/ready":{"get":{"summary":"Readiness","operationId":"readiness_health_ready_get","responses":{"200":{"description":"Healthy probe.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultProbe"}}}},"503":{"description":"Not ready or degraded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultProbe"}}}}},"tags":["Main"],"x-required-role":"public/capability","parameters":[],"security":[],"description":"Uses the shared domain service and current authorization checks. See the integration/operator walkthrough for the surrounding workflow."}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Healthy probe.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultProbe"}}}},"503":{"description":"Not ready or degraded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultProbe"}}}}},"tags":["Main"],"x-required-role":"public/capability","parameters":[],"security":[],"description":"Uses the shared domain service and current authorization checks. See the integration/operator walkthrough for the surrounding workflow."}}},"components":{"schemas":{"Choices":{"properties":{"subject_ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":1000,"title":"Subject Ids"}},"additionalProperties":false,"type":"object","required":["subject_ids"],"title":"Choices"},"Confirmation":{"properties":{"token":{"anyOf":[{"type":"string","maxLength":43,"minLength":43},{"type":"null"}],"title":"Token"},"subject_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":1000},{"type":"null"}],"title":"Subject Ids"}},"additionalProperties":false,"type":"object","title":"Confirmation"},"EmailRequest":{"properties":{"email":{"type":"string","maxLength":254,"title":"Email"}},"additionalProperties":false,"type":"object","required":["email"],"title":"EmailRequest"},"Resubscription":{"properties":{"token":{"anyOf":[{"type":"string","maxLength":43,"minLength":43},{"type":"null"}],"title":"Token"},"subject_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":1000},{"type":"null"}],"title":"Subject Ids"},"confirmed":{"type":"boolean","title":"Confirmed"}},"additionalProperties":false,"type":"object","required":["confirmed"],"title":"Resubscription"},"Subscription":{"properties":{"email":{"type":"string","maxLength":254,"title":"Email"},"first_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Last Name"},"subject_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":1000},{"type":"null"}],"title":"Subject Ids"}},"additionalProperties":false,"type":"object","required":["email"],"title":"Subscription"},"Withdrawal":{"properties":{},"additionalProperties":false,"type":"object","title":"Withdrawal"},"ResultError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"string"}},"request_id":{"type":"string"}},"required":["code","message","fields","request_id"]}},"required":["error"]},"ResultGeneric":{"type":"object","properties":{"success":{"const":true},"status":{"type":"string"},"message":{"type":"string"}},"required":["success","status","message"]},"ResultUnsubscribe":{"type":"object","properties":{"success":{"const":true},"message":{"type":"string"}},"required":["success","message"]},"ResultPublicOrganisation":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"brand_colour":{"type":"string"},"background_mode":{"type":"string"},"signup_intro":{"type":"string"},"confirmation_intro":{"type":"string"},"double_opt_in":{"type":"boolean"},"signup_available":{"type":"boolean"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}]},"subjects":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"id":{"type":"string","format":"uuid"}},"required":["id","name","description"]}}},"required":["name","slug","subjects","double_opt_in","signup_available"]},"ResultSubjects":{"type":"object","properties":{"subjects":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"id":{"type":"string","format":"uuid"}},"required":["id","name","description"]}}},"required":["subjects"]},"ResultActivation":{"type":"object","properties":{"confirmed":{"const":true}},"required":["confirmed"]},"ResultPreferences":{"type":"object","properties":{"central":{"type":"boolean"},"organisations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"brand_colour":{"type":"string"},"background_mode":{"type":"string"},"signup_intro":{"type":"string"},"confirmation_intro":{"type":"string"},"double_opt_in":{"type":"boolean"},"signup_available":{"type":"boolean"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}]},"subjects":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"id":{"type":"string","format":"uuid"}},"required":["id","name","description"]}},"preferences_intro":{"type":"string"},"state":{"type":"string"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"org_id":{"type":"string","format":"uuid"},"subject_ids":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":[]}}},"required":["central","organisations"]},"ResultPreferenceChange":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"brand_colour":{"type":"string"},"background_mode":{"type":"string"},"signup_intro":{"type":"string"},"confirmation_intro":{"type":"string"},"double_opt_in":{"type":"boolean"},"signup_available":{"type":"boolean"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}]},"subjects":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"id":{"type":"string","format":"uuid"}},"required":["id","name","description"]}},"preferences_intro":{"type":"string"},"state":{"type":"string"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"org_id":{"type":"string","format":"uuid"},"subject_ids":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":[]},"ResultProbe":{"type":"object","properties":{"status":{"type":"string"},"version":{"type":"string"}},"required":["status","version"]}},"securitySchemes":{"PreferencesCapability":{"type":"apiKey","in":"header","name":"X-Preferences-Token"},"PreferencesCookie":{"type":"apiKey","in":"cookie","name":"broadcast_preferences"}}}}