{"components":{"headers":{"CorrelationId":{"description":"Request correlation ID for logs and support.","schema":{"type":"string"}}},"parameters":{"OrganizationSlug":{"in":"path","name":"organization_slug","required":true,"schema":{"type":"string"}},"WorkspaceSlug":{"in":"path","name":"workspace_slug","required":true,"schema":{"type":"string"}}},"schemas":{"ArchiveResponse":{"properties":{"archived":{"type":"boolean"}},"required":["archived"],"type":"object"},"AudienceCreateRequest":{"examples":[{"minimum_interval_seconds":604800,"name":"Weekly newsletter","purpose":"Weekly GFA community update","slug":"weekly-newsletter"}],"properties":{"minimum_interval_seconds":{"maximum":2147483647,"minimum":0,"type":"integer"},"name":{"type":"string"},"purpose":{"type":"string"},"slug":{"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","type":"string"}},"required":["name","slug","purpose"],"type":"object"},"AudienceCreateResponse":{"properties":{"audience":{"properties":{"id":{"type":"string"},"slug":{"type":"string"}},"required":["id","slug"],"type":"object"}},"required":["audience"],"type":"object"},"AudienceResponse":{"properties":{"audience":{"properties":{"active_member_count":{"type":"integer"},"id":{"type":"string"},"is_archived":{"type":"boolean"},"name":{"type":"string"},"purpose":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug","purpose","is_archived","active_member_count"],"type":"object"}},"required":["audience"],"type":"object"},"AudienceSubscribeRequest":{"examples":[{"contact_id":"contact-id","evidence":{"captured_at":"2026-07-25T00:00:00Z"},"source":"approved-form","wording_version":"newsletter-v1"}],"properties":{"contact_id":{"type":"string"},"evidence":{"additionalProperties":true,"type":"object"},"form_identifier":{"type":"string"},"source":{"type":"string"},"source_application":{"type":"string"},"wording_version":{"type":"string"}},"required":["contact_id","source","wording_version"],"type":"object"},"AudienceSubscribeResponse":{"properties":{"consent_event_id":{"type":"string"},"subscribed":{"type":"boolean"}},"required":["subscribed","consent_event_id"],"type":"object"},"AudienceUnsubscribeRequest":{"examples":[{"contact_id":"contact-id","source":"authorized_api"}],"properties":{"contact_id":{"type":"string"},"source":{"type":"string"}},"required":["contact_id"],"type":"object"},"AudienceUnsubscribeResponse":{"properties":{"scope":{"const":"audience","type":"string"},"unsubscribed":{"type":"boolean"}},"required":["unsubscribed","scope"],"type":"object"},"Automation":{"properties":{"activation_available":{"const":false,"type":"boolean"},"authoring_only":{"const":true,"type":"boolean"},"current_version":{"type":"integer"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"enrollment_available":{"const":false,"type":"boolean"},"execution_available":{"const":false,"type":"boolean"},"id":{"type":"string"},"name":{"type":"string"},"review_ready_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}]},"review_ready_by_gfavip_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"review_ready_version":{"anyOf":[{"type":"integer"},{"type":"null"}]},"selected_version":{"properties":{"change_notes":{"anyOf":[{"type":"string"},{"type":"null"}]},"created_at":{"format":"date-time","type":"string"},"created_by_gfavip_id":{"type":"string"},"definition":{"$ref":"#/components/schemas/AutomationDefinition"},"definition_checksum":{"type":"string"},"id":{"type":"string"},"preview":{"additionalProperties":true,"type":"object"},"trigger_type":{"type":"string"},"validation":{"$ref":"#/components/schemas/AutomationValidation"},"version":{"type":"integer"}},"required":["id","version","trigger_type","definition_checksum","validation","preview","definition","change_notes","created_by_gfavip_id","created_at"],"type":"object"},"slug":{"type":"string"},"status":{"enum":["draft","ready_for_review","archived"],"type":"string"},"versions":{"items":{"$ref":"#/components/schemas/AutomationVersionSummary"},"type":"array"},"workspace_id":{"type":"string"}},"required":["id","workspace_id","name","slug","description","status","current_version","review_ready_version","review_ready_by_gfavip_id","review_ready_at","authoring_only","execution_available","activation_available","enrollment_available","selected_version"],"type":"object"},"AutomationCreateRequest":{"examples":[{"change_notes":"Initial non-executable shell","definition":{"edges":[],"nodes":[{"config":{},"key":"finish","type":"end"}],"start_node":"finish","trigger":{"config":{},"type":"manual"}},"description":"Authoring-only synthetic workflow","name":"Lead magnet delivery","slug":"lead-magnet-delivery"}],"properties":{"change_notes":{"type":"string"},"definition":{"$ref":"#/components/schemas/AutomationDefinition"},"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug","definition"],"type":"object"},"AutomationDefinition":{"properties":{"edges":{"items":{"$ref":"#/components/schemas/AutomationEdgeDefinition"},"maxItems":200,"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/AutomationNodeDefinition"},"maxItems":100,"minItems":1,"type":"array"},"start_node":{"type":"string"},"trigger":{"$ref":"#/components/schemas/AutomationTrigger"}},"required":["trigger","start_node","nodes","edges"],"type":"object"},"AutomationEdgeDefinition":{"properties":{"branch":{"type":"string"},"condition":{"additionalProperties":true,"type":"object"},"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to","branch"],"type":"object"},"AutomationEnrollment":{"properties":{"automation_id":{"type":"string"},"automation_version_id":{"type":"string"},"completed_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}]},"current_node_key":{"anyOf":[{"type":"string"},{"type":"null"}]},"enrolled_at":{"format":"date-time","type":"string"},"events":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"provider_calls":{"const":0,"type":"integer"},"state":{"type":"string"},"steps":{"items":{"type":"object"},"type":"array"},"synthetic":{"const":true,"type":"boolean"},"webhook_calls":{"const":0,"type":"integer"},"workspace_id":{"type":"string"}},"required":["id","workspace_id","automation_id","automation_version_id","state","synthetic","enrolled_at","provider_calls","webhook_calls"],"type":"object"},"AutomationEnrollmentControlRequest":{"examples":[{"reason":"synthetic operator rehearsal","step_id":"failed-synthetic-step-id"}],"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}]},"step_id":{"anyOf":[{"type":"string"},{"type":"null"}]}},"type":"object"},"AutomationEnrollmentListResponse":{"properties":{"enrollments":{"items":{"$ref":"#/components/schemas/AutomationEnrollment"},"type":"array"},"production_enrollment_available":{"const":false,"type":"boolean"},"synthetic_only":{"const":true,"type":"boolean"}},"required":["enrollments","synthetic_only","production_enrollment_available"],"type":"object"},"AutomationEnrollmentResponse":{"properties":{"enrollment":{"$ref":"#/components/schemas/AutomationEnrollment"}},"required":["enrollment"],"type":"object"},"AutomationListResponse":{"properties":{"authoring_only":{"const":true,"type":"boolean"},"automations":{"items":{"$ref":"#/components/schemas/Automation"},"type":"array"},"execution_available":{"const":false,"type":"boolean"}},"required":["automations","authoring_only","execution_available"],"type":"object"},"AutomationNodeDefinition":{"properties":{"config":{"additionalProperties":true,"type":"object"},"key":{"type":"string"},"type":{"enum":["send_email","wait_duration","wait_until_date","add_tag","remove_tag","add_audience","remove_audience","update_contact_field","adjust_score","decision","end"],"type":"string"}},"required":["key","type","config"],"type":"object"},"AutomationResponse":{"properties":{"automation":{"$ref":"#/components/schemas/Automation"}},"required":["automation"],"type":"object"},"AutomationReviewReadyRequest":{"examples":[{"definition_checksum":"sha256-definition-checksum","version_id":"automation-version-id"}],"properties":{"definition_checksum":{"type":"string"},"version_id":{"type":"string"}},"required":["version_id","definition_checksum"],"type":"object"},"AutomationSyntheticEnrollmentRequest":{"examples":[{"contact_id":"synthetic-contact-id","synthetic_context_id":"synthetic-rehearsal-id"}],"properties":{"contact_id":{"type":"string"},"synthetic_context_id":{"type":"string"}},"required":["contact_id","synthetic_context_id"],"type":"object"},"AutomationTrigger":{"properties":{"config":{"additionalProperties":true,"type":"object"},"type":{"enum":["audience_subscribed","tag_added","tag_removed","contact_field_changed","contact_date","recurring_schedule","api_event","manual"],"type":"string"}},"required":["type","config"],"type":"object"},"AutomationValidation":{"properties":{"authoring_only":{"const":true,"type":"boolean"},"dependencies":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"dependency_counts":{"additionalProperties":true,"type":"object"},"execution_available":{"const":false,"type":"boolean"},"reconstruction_review":{"additionalProperties":true,"type":"object"},"source_provenance":{"$ref":"#/components/schemas/RecoveredSourceProvenance"},"structural_errors":{"items":{"type":"string"},"type":"array"},"valid":{"type":"boolean"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["valid","structural_errors","dependencies","dependency_counts","warnings","authoring_only","execution_available"],"type":"object"},"AutomationVersionRequest":{"examples":[{"change_notes":"Reviewed source definition","definition":{"edges":[],"nodes":[{"config":{},"key":"finish","type":"end"}],"start_node":"finish","trigger":{"config":{},"type":"manual"}}}],"properties":{"change_notes":{"type":"string"},"definition":{"$ref":"#/components/schemas/AutomationDefinition"}},"required":["definition"],"type":"object"},"AutomationVersionSummary":{"properties":{"change_notes":{"anyOf":[{"type":"string"},{"type":"null"}]},"created_at":{"format":"date-time","type":"string"},"created_by_gfavip_id":{"type":"string"},"definition_checksum":{"type":"string"},"id":{"type":"string"},"trigger_type":{"type":"string"},"version":{"type":"integer"}},"required":["id","version","trigger_type","definition_checksum","change_notes","created_by_gfavip_id","created_at"],"type":"object"},"Campaign":{"properties":{"current_version":{"type":"integer"},"draft":{"properties":{"audience_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"audience_ids":{"items":{"type":"string"},"type":"array"},"content_version_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"sender_identity_id":{"type":"string"},"version":{"type":"integer"}},"required":["id","version","name","audience_id","audience_ids","sender_identity_id","content_version_id"],"type":"object"},"id":{"type":"string"},"status":{"type":"string"}},"required":["id","status","current_version","draft"],"type":"object"},"CampaignDraftRequest":{"examples":[{"audience_id":"audience-id","content_version_id":"content-version-id","name":"Weekly GFA update","notes":"Draft only","sender_identity_id":"sender-id"}],"properties":{"audience_id":{"type":"string"},"content_version_id":{"type":"string"},"name":{"type":"string"},"notes":{"type":"string"},"sender_identity_id":{"type":"string"}},"required":["name","audience_id","sender_identity_id","content_version_id"],"type":"object"},"CampaignReportResponse":{"properties":{"campaign_run":{"$ref":"#/components/schemas/CampaignRun"},"report":{"additionalProperties":true,"type":"object"}},"required":["campaign_run","report"],"type":"object"},"CampaignResponse":{"properties":{"campaign":{"$ref":"#/components/schemas/Campaign"}},"required":["campaign"],"type":"object"},"CampaignRun":{"properties":{"campaign_id":{"type":"string"},"excluded_count":{"type":"integer"},"exclusion_counts":{"additionalProperties":true,"type":"object"},"failed_count":{"type":"integer"},"id":{"type":"string"},"included_count":{"type":"integer"},"scheduled_for":{"format":"date-time","type":"string"},"sent_count":{"type":"integer"},"snapshot_id":{"type":"string"},"state":{"type":"string"}},"required":["id","campaign_id","snapshot_id","state","scheduled_for","included_count","excluded_count","sent_count","failed_count","exclusion_counts"],"type":"object"},"CampaignRunResponse":{"properties":{"campaign_run":{"$ref":"#/components/schemas/CampaignRun"}},"required":["campaign_run"],"type":"object"},"Contact":{"properties":{"company":{"anyOf":[{"type":"string"},{"type":"null"}]},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}]},"custom_fields":{"additionalProperties":true,"type":"object"},"email":{"type":"string"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"id":{"type":"string"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"legacy_consent_classification":{"anyOf":[{"type":"string"},{"type":"null"}]},"normalized_email":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"}},"required":["id","email","normalized_email","first_name","last_name","company","country_code","legacy_consent_classification","tags","custom_fields"],"type":"object"},"ContactFieldDefinitionRequest":{"examples":[{"field_key":"industry","field_type":"single_choice","label":"Industry","options":["commerce","technology"]}],"properties":{"field_key":{"pattern":"^[a-z][a-z0-9_]{0,99}$","type":"string"},"field_type":{"enum":["text","long_text","integer","decimal","boolean","date","datetime","single_choice","multiple_choice","url"],"type":"string"},"label":{"type":"string"},"options":{"items":{"type":"string"},"type":"array"}},"required":["field_key","label","field_type"],"type":"object"},"ContactFieldDefinitionResponse":{"properties":{"field_definition":{"properties":{"field_key":{"type":"string"},"field_type":{"type":"string"},"id":{"type":"string"},"version":{"type":"integer"}},"required":["id","field_key","field_type","version"],"type":"object"}},"required":["field_definition"],"type":"object"},"ContactResponse":{"properties":{"contact":{"$ref":"#/components/schemas/Contact"}},"required":["contact"],"type":"object"},"ContactUpsertRequest":{"examples":[{"country_code":"US","email":"person@example.com","first_name":"Person","source":"approved-form","tags":["newsletter"]}],"properties":{"company":{"anyOf":[{"type":"string"},{"type":"null"}]},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}]},"custom_fields":{"additionalProperties":true,"type":"object"},"email":{"format":"email","type":"string"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"is_legacy":{"type":"boolean"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"legacy_consent_evidence":{"additionalProperties":true,"type":"object"},"locale":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"source":{"type":"string"},"source_identifier":{"type":"string"},"source_metadata":{"additionalProperties":true,"type":"object"},"source_workspace":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["email","source"],"type":"object"},"ContactUpsertResponse":{"properties":{"contact":{"$ref":"#/components/schemas/Contact"},"created":{"type":"boolean"}},"required":["contact","created"],"type":"object"},"ContentValidation":{"properties":{"images":{"type":"integer"},"links":{"type":"integer"},"missing_defaults":{"items":{"type":"string"},"type":"array"},"plain_text_generated":{"type":"boolean"},"review_warnings":{"items":{"type":"string"},"type":"array"},"source_provenance":{"$ref":"#/components/schemas/RecoveredSourceProvenance"},"stripped":{"$ref":"#/components/schemas/StrippedMarkup"},"tokens":{"items":{"type":"string"},"type":"array"},"unsubscribe_present":{"type":"boolean"},"valid":{"type":"boolean"}},"required":["valid","links","images","tokens","missing_defaults","plain_text_generated","unsubscribe_present"],"type":"object"},"ContentVersionRequest":{"examples":[{"html":"<p>Hello {{ first_name }}</p><p><a href=\"{{ unsubscribe_url }}\">Unsubscribe</a></p>","personalization_defaults":{"first_name":"there"},"plain_text":"Hello {{ first_name }}\n\nUnsubscribe: {{ unsubscribe_url }}","preheader":"This week's GFA update","subject":"Hello {{ first_name }}"}],"properties":{"html":{"type":"string"},"personalization_defaults":{"additionalProperties":{"type":"string"},"type":"object"},"plain_text":{"type":"string"},"preheader":{"type":"string"},"subject":{"maxLength":300,"type":"string"}},"required":["subject","html"],"type":"object"},"ContentVersionResponse":{"properties":{"content_version":{"properties":{"id":{"type":"string"},"template_id":{"type":"string"},"validation":{"$ref":"#/components/schemas/ContentValidation"},"version":{"type":"integer"}},"required":["id","template_id","version","validation"],"type":"object"}},"required":["content_version"],"type":"object"},"CsvImport":{"properties":{"approval_checksum":{"anyOf":[{"type":"string"},{"type":"null"}]},"approved_by_gfavip_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"attempt_count":{"type":"integer"},"completed_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}]},"consent_policy":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"error":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}]},"expires_at":{"format":"date-time","type":"string"},"file_sha256":{"type":"string"},"filename":{"type":"string"},"headers":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"mapping":{"additionalProperties":{"type":"string"},"type":"object"},"payload_retained":{"type":"boolean"},"payload_size":{"type":"integer"},"policy":{"additionalProperties":true,"type":"object"},"report":{"additionalProperties":true,"type":"object"},"report_checksum":{"anyOf":[{"type":"string"},{"type":"null"}]},"requested_by_gfavip_id":{"type":"string"},"source_label":{"type":"string"},"status":{"type":"string"}},"required":["id","status","filename","source_label","file_sha256","payload_size","payload_retained","headers","mapping","consent_policy","policy","report","report_checksum","approval_checksum","requested_by_gfavip_id","approved_by_gfavip_id","attempt_count","created_at","expires_at","completed_at","error"],"type":"object"},"CsvImportApprovalRequest":{"examples":[{"confirmation":"APPLY CSV IMPORT job-id TO gfa-community/gfa-community"}],"properties":{"confirmation":{"type":"string"}},"required":["confirmation"],"type":"object"},"CsvImportListResponse":{"properties":{"imports":{"items":{"$ref":"#/components/schemas/CsvImport"},"type":"array"}},"required":["imports"],"type":"object"},"CsvImportMappingProfileListResponse":{"properties":{"profiles":{"items":{"properties":{"id":{"type":"string"},"mapping":{"additionalProperties":true,"type":"object"},"mapping_checksum":{"type":"string"},"name":{"type":"string"},"policy":{"additionalProperties":true,"type":"object"}},"required":["id","name","mapping","policy","mapping_checksum"],"type":"object"},"type":"array"}},"required":["profiles"],"type":"object"},"CsvImportMappingRequest":{"examples":[{"consent_policy":"status_column","mapping":{"email":"Email","first_name":"First Name","status":"Status"},"policy":{"consent_basis":"Documented newsletter opt-in field.","consent_source":"documented-event-registration","default_status":"review_required","evidence_reference":"approved-registration-export","static_tags":["event"],"status_values":{"subscribed":"subscribed","unsubscribed":"audience_unsubscribe"},"wording_version":"event-form-v2"}}],"properties":{"consent_policy":{"enum":["review_required","explicit_opt_in","status_column"],"type":"string"},"mapping":{"additionalProperties":{"type":"string"},"type":"object"},"policy":{"additionalProperties":true,"type":"object"},"profile_id":{"type":"string"},"save_profile_name":{"type":"string"}},"required":["mapping","consent_policy","policy"],"type":"object"},"CsvImportResponse":{"properties":{"import":{"$ref":"#/components/schemas/CsvImport"}},"required":["import"],"type":"object"},"DomainProviderRequest":{"examples":[{"dkim_selector":"smtp","provider_connection_id":"provider-connection-id","provider_domain_reference":"mail.example.com"}],"properties":{"dkim_selector":{"type":"string"},"provider_connection_id":{"type":"string"},"provider_domain_reference":{"type":"string"}},"required":["provider_connection_id","dkim_selector"],"type":"object"},"DomainVerifyResponse":{"properties":{"check":{"properties":{"evidence":{"additionalProperties":true,"type":"object"},"id":{"type":"string"},"is_ready":{"type":"boolean"}},"required":["id","is_ready","evidence"],"type":"object"},"sending_domain":{"$ref":"#/components/schemas/SendingDomain"}},"required":["sending_domain","check"],"type":"object"},"EligibilityResponse":{"properties":{"eligibility":{"properties":{"audience_id":{"type":"string"},"contact_id":{"type":"string"},"eligible":{"type":"boolean"},"evaluated_at":{"format":"date-time","type":"string"},"reasons":{"items":{"type":"string"},"type":"array"},"workspace_id":{"type":"string"}},"required":["eligible","reasons","contact_id","audience_id","workspace_id","evaluated_at"],"type":"object"}},"required":["eligibility"],"type":"object"},"EmailTemplateArchiveRequest":{"examples":[{"archived":true}],"properties":{"archived":{"type":"boolean"}},"type":"object"},"EmailTemplateArchiveResponse":{"properties":{"email_template":{"properties":{"archived":{"type":"boolean"},"id":{"type":"string"}},"required":["id","archived"],"type":"object"}},"required":["email_template"],"type":"object"},"EmailTemplateRequest":{"examples":[{"description":"Versioned weekly newsletter","name":"Weekly update","slug":"weekly-update"}],"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"EmailTemplateResponse":{"properties":{"email_template":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"}},"required":["email_template"],"type":"object"},"HealthResponse":{"properties":{"production_sending_enabled":{"type":"boolean"},"role":{"type":"string"},"service":{"type":"string"},"status":{"type":"string"}},"required":["status","service","role","production_sending_enabled"],"type":"object"},"MailgunWebhookEnvelope":{"examples":[{"event-data":{"event":"delivered","id":"provider-event-id","timestamp":1784937600},"signature":{"signature":"provider-supplied-hmac","timestamp":"1784937600","token":"provider-supplied-token"}}],"properties":{"event-data":{"properties":{"event":{"enum":["accepted","delivered","failed","opened","clicked","unsubscribed","complained"],"type":"string"},"id":{"type":"string"},"timestamp":{"type":"number"}},"required":["id","event","timestamp"],"type":"object"},"signature":{"properties":{"signature":{"type":"string"},"timestamp":{"type":"string"},"token":{"type":"string"}},"required":["timestamp","token","signature"],"type":"object"}},"required":["signature","event-data"],"type":"object"},"MailgunWebhookResponse":{"properties":{"id":{"type":"string"},"status":{"enum":["processed","duplicate"],"type":"string"}},"required":["status","id"],"type":"object"},"MeResponse":{"examples":[{"auth_method":"bearer","csrf_token":null,"user":{"gfavip_user_id":"stable-wallet-user-id","identity_type":"agent","platform_role":null,"username":"pl-arthur-blaze"},"workspaces":[{"is_archived":false,"organization":"gfa-community","role":"editor","workspace":"gfa-community"}]}],"properties":{"auth_method":{"enum":["bearer","session"],"type":"string"},"csrf_token":{"anyOf":[{"type":"string"},{"type":"null"}]},"user":{"$ref":"#/components/schemas/User"},"workspaces":{"items":{"$ref":"#/components/schemas/Membership"},"type":"array"}},"required":["user","auth_method","csrf_token","workspaces"],"type":"object"},"Membership":{"properties":{"is_archived":{"type":"boolean"},"organization":{"type":"string"},"role":{"type":"string"},"workspace":{"type":"string"}},"required":["organization","workspace","role","is_archived"],"type":"object"},"PreferenceTokenRequest":{"examples":[{"audience_id":"audience-id","scope":"audience"}],"properties":{"audience_id":{"type":"string"},"scope":{"enum":["audience","workspace"],"type":"string"}},"required":["scope"],"type":"object"},"PreferenceTokenResponse":{"properties":{"one_click_url":{"format":"uri","type":"string"},"preference_url":{"format":"uri","type":"string"}},"required":["preference_url","one_click_url"],"type":"object"},"PreferenceUnsubscribeResponse":{"properties":{"scope":{"type":"string"},"unsubscribed":{"type":"boolean"}},"required":["unsubscribed","scope"],"type":"object"},"Preflight":{"properties":{"checks":{"items":{"$ref":"#/components/schemas/PreflightCheck"},"type":"array"},"completed_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"report_checksum":{"type":"string"},"requested_by_gfavip_id":{"type":"string"},"status":{"enum":["passed","blocked"],"type":"string"},"summary":{"properties":{"blocked":{"type":"integer"},"passed":{"type":"integer"},"warnings":{"type":"integer"}},"required":["passed","blocked","warnings"],"type":"object"},"workspace_id":{"type":"string"}},"required":["id","workspace_id","status","summary","checks","report_checksum","requested_by_gfavip_id","completed_at"],"type":"object"},"PreflightCheck":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"evidence":{"additionalProperties":true,"type":"object"},"label":{"type":"string"},"remediation":{"type":"string"},"status":{"enum":["pass","warn","block"],"type":"string"}},"required":["code","label","status","detail"],"type":"object"},"PreflightResponse":{"properties":{"preflight":{"anyOf":[{"$ref":"#/components/schemas/Preflight"},{"type":"null"}]}},"required":["preflight"],"type":"object"},"ProductionActivationRequest":{"examples":[{"confirmation":"ACTIVATE PRODUCTION SENDING"}],"properties":{"confirmation":{"const":"ACTIVATE PRODUCTION SENDING","type":"string"}},"required":["confirmation"],"type":"object"},"ProviderActivationRequest":{"examples":[{"confirmation":"ENABLE TEST CONNECTION"}],"properties":{"confirmation":{"const":"ENABLE TEST CONNECTION","type":"string"}},"required":["confirmation"],"type":"object"},"ProviderConnection":{"properties":{"connection_state":{"type":"string"},"credential_env_key":{"type":"string"},"credential_value_exposed":{"const":false,"type":"boolean"},"id":{"type":"string"},"is_active":{"type":"boolean"},"name":{"type":"string"},"provider":{"const":"mailgun","type":"string"},"region":{"type":"string"},"webhook_signing_env_key":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","provider","region","credential_env_key","webhook_signing_env_key","connection_state","is_active","credential_value_exposed"],"type":"object"},"ProviderConnectionRequest":{"examples":[{"credential_env_key":"MAILGUN_API_KEY_GFA","name":"Mailgun US","region":"us","webhook_signing_env_key":"MAILGUN_WEBHOOK_SIGNING_KEY_GFA"}],"properties":{"credential_env_key":{"type":"string"},"name":{"type":"string"},"region":{"enum":["us","eu"],"type":"string"},"webhook_signing_env_key":{"type":"string"}},"required":["name","credential_env_key"],"type":"object"},"ProviderConnectionResponse":{"properties":{"provider_connection":{"$ref":"#/components/schemas/ProviderConnection"}},"required":["provider_connection"],"type":"object"},"ProviderEventReplayResponse":{"properties":{"provider_event":{"properties":{"event_type":{"type":"string"},"id":{"type":"string"},"processing_state":{"type":"string"}},"required":["id","processing_state","event_type"],"type":"object"}},"required":["provider_event"],"type":"object"},"ReadinessResponse":{"properties":{"database":{"type":"string"},"status":{"type":"string"}},"required":["status","database"],"type":"object"},"RecoveredSourceProvenance":{"properties":{"checksum_manifest_sha256":{"type":"string"},"operator_review_required":{"const":true,"type":"boolean"},"protected_source_outside_git":{"const":true,"type":"boolean"},"source_checksum":{"type":"string"},"source_hashes":{"additionalProperties":true,"type":"object"},"source_id":{"type":"string"},"source_object_id":{"oneOf":[{"type":"string"},{"type":"integer"}]},"source_object_type":{"enum":["email","campaign"],"type":"string"},"source_repository_commit":{"type":"string"},"source_system":{"enum":["mautic"],"type":"string"},"transformation":{"additionalProperties":true,"type":"object"},"workflow_graph_sha256":{"type":"string"}},"required":["source_system","source_object_type","source_object_id","source_id","source_repository_commit","checksum_manifest_sha256","protected_source_outside_git","operator_review_required"],"type":"object"},"Rehearsal":{"properties":{"created_at":{"format":"date-time","type":"string"},"event_counts":{"additionalProperties":true,"type":"object"},"id":{"type":"string"},"reconciliation":{"additionalProperties":true,"type":"object"},"state":{"type":"string"},"test_send_request_id":{"type":"string"},"verified_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}]}},"required":["id","test_send_request_id","state","event_counts","reconciliation","created_at","verified_at"],"type":"object"},"RehearsalRequest":{"examples":[{"confirmation":"RUN CONTROLLED REHEARSAL","content_version_id":"content-version-id","recipient_email":"allowlisted@example.com","sender_identity_id":"sender-id"}],"properties":{"confirmation":{"const":"RUN CONTROLLED REHEARSAL","type":"string"},"content_version_id":{"type":"string"},"recipient_email":{"format":"email","type":"string"},"sender_identity_id":{"type":"string"}},"required":["sender_identity_id","content_version_id","recipient_email","confirmation"],"type":"object"},"RehearsalResponse":{"properties":{"rehearsal":{"$ref":"#/components/schemas/Rehearsal"}},"required":["rehearsal"],"type":"object"},"ResolveSuppressionRequest":{"examples":[{"resolution_reason":"Reviewed and cleared by an authorized operator"}],"properties":{"resolution_reason":{"type":"string"}},"required":["resolution_reason"],"type":"object"},"ResolvedResponse":{"properties":{"resolved":{"type":"boolean"}},"required":["resolved"],"type":"object"},"ScheduleRequest":{"examples":[{"scheduled_for":"2026-08-01T10:00:00+07:00"}],"properties":{"scheduled_for":{"format":"date-time","type":"string"}},"required":["scheduled_for"],"type":"object"},"SenderActivationResponse":{"properties":{"sender_identity":{"properties":{"id":{"type":"string"},"is_enabled":{"type":"boolean"}},"required":["id","is_enabled"],"type":"object"}},"required":["sender_identity"],"type":"object"},"SenderIdentity":{"properties":{"display_name":{"type":"string"},"from_address":{"type":"string"},"id":{"type":"string"},"is_enabled":{"type":"boolean"},"reply_to":{"type":"string"},"verification_state":{"type":"string"}},"required":["id","display_name","from_address","reply_to","verification_state","is_enabled"],"type":"object"},"SenderIdentityRequest":{"examples":[{"display_name":"GFA Community","from_address":"news@mail.example.com","reply_to":"support@example.com","sending_domain_id":"sending-domain-id"}],"properties":{"display_name":{"type":"string"},"from_address":{"format":"email","type":"string"},"reply_to":{"format":"email","type":"string"},"sending_domain_id":{"type":"string"}},"required":["sending_domain_id","display_name","from_address","reply_to"],"type":"object"},"SenderIdentityResponse":{"properties":{"sender_identity":{"$ref":"#/components/schemas/SenderIdentity"}},"required":["sender_identity"],"type":"object"},"SendingDomain":{"properties":{"alignment_state":{"type":"string"},"dkim_state":{"type":"string"},"dmarc_state":{"type":"string"},"domain_name":{"type":"string"},"id":{"type":"string"},"is_ready":{"type":"boolean"},"quota_state":{"type":"string"},"spf_state":{"type":"string"},"verification_state":{"type":"string"}},"required":["id","domain_name","verification_state","spf_state","dkim_state","dmarc_state","alignment_state","quota_state","is_ready"],"type":"object"},"SendingDomainReadinessRequest":{"examples":[{"alignment_state":"not_checked","dkim_state":"pending","dmarc_state":"pending","notes":"Pending live verification","quota_state":"not_checked","spf_state":"pending","verification_state":"pending"}],"properties":{"alignment_state":{"enum":["not_checked","aligned","misaligned"],"type":"string"},"dkim_state":{"enum":["not_checked","pending","verified","failed"],"type":"string"},"dmarc_state":{"enum":["not_checked","pending","verified","failed"],"type":"string"},"notes":{"type":"string"},"quota_state":{"enum":["not_checked","approved","insufficient"],"type":"string"},"spf_state":{"enum":["not_checked","pending","verified","failed"],"type":"string"},"verification_state":{"enum":["not_checked","pending","verified","failed"],"type":"string"}},"type":"object"},"SendingDomainRequest":{"examples":[{"domain_name":"mail.example.com","tracking_domain":"track.example.com"}],"properties":{"domain_name":{"type":"string"},"notes":{"type":"string"},"tracking_domain":{"type":"string"}},"required":["domain_name"],"type":"object"},"SendingDomainResponse":{"properties":{"sending_domain":{"$ref":"#/components/schemas/SendingDomain"}},"required":["sending_domain"],"type":"object"},"StrippedMarkup":{"description":"What the sanitizer removed from the submitted HTML. `valid` stays true when these lists are non-empty: the version is stored, but the stored `sanitized_html` no longer contains the listed markup, and that is what is sent. Treat any non-empty list as a defect in the submitted HTML and repost with allowlisted markup. See /skill.md, 'Email HTML that survives sanitizing'.","properties":{"attributes":{"items":{"type":"string"},"type":"array"},"css_properties":{"items":{"type":"string"},"type":"array"},"protocols":{"items":{"type":"string"},"type":"array"},"tags":{"items":{"type":"string"},"type":"array"}},"required":["tags","attributes","css_properties","protocols"],"type":"object"},"SubscriptionSourceAudiencesResponse":{"properties":{"audiences":{"items":{"properties":{"id":{"format":"uuid","type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"type":"array"},"schema_version":{"const":"connect.subscription-source-audiences.v1","type":"string"},"source_id":{"format":"uuid","type":"string"}},"required":["schema_version","source_id","audiences"],"type":"object"},"SubscriptionSourceEventRequest":{"additionalProperties":false,"examples":[{"captured_at":"2026-07-29T00:00:00Z","consent":{"privacy_policy_url":"https://lifeisshortdoitnow.com/privacy","privacy_policy_version":"2026-07-29","wording_id":"newsletter-v1","wording_sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"consent_granted":true,"contact":{"email":"synthetic-phase5@example.test","first_name":"Synthetic"},"destination_audience_id":"22222222-2222-4222-8222-222222222222","schema_version":"connect.subscription-source-event.v1","source":{"evidence_schema_version":"memoupdate.newsletter-consent-capture.v1","form_id":"synthetic-form","form_version":"1","page_origin":"https://my.lifeisshortdoitnow.com"},"source_event_id":"11111111-1111-4111-8111-111111111111"}],"properties":{"captured_at":{"format":"date-time","type":"string"},"consent":{"properties":{"privacy_policy_url":{"format":"uri","type":"string"},"privacy_policy_version":{"maxLength":160,"type":"string"},"wording_id":{"maxLength":160,"type":"string"},"wording_sha256":{"pattern":"^[a-f0-9]{64}$","type":"string"}},"required":["wording_id","wording_sha256","privacy_policy_url","privacy_policy_version"],"type":"object"},"consent_granted":{"const":true,"type":"boolean"},"contact":{"properties":{"email":{"format":"email","type":"string"},"first_name":{"maxLength":160,"type":"string"},"last_name":{"maxLength":160,"type":"string"},"locale":{"maxLength":40,"type":"string"}},"required":["email"],"type":"object"},"destination_audience_id":{"format":"uuid","type":"string"},"schema_version":{"const":"connect.subscription-source-event.v1","type":"string"},"source":{"properties":{"evidence_schema_version":{"const":"memoupdate.newsletter-consent-capture.v1","type":"string"},"form_id":{"maxLength":160,"type":"string"},"form_version":{"maxLength":160,"type":"string"},"page_origin":{"format":"uri","type":"string"},"popup_campaign_id":{"anyOf":[{"format":"uuid","type":"string"},{"type":"null"}]},"popup_version":{"anyOf":[{"minimum":1,"type":"integer"},{"type":"null"}]}},"required":["form_id","form_version","page_origin","evidence_schema_version"],"type":"object"},"source_event_id":{"format":"uuid","type":"string"}},"required":["schema_version","source_event_id","destination_audience_id","contact","consent_granted","captured_at","consent","source"],"type":"object"},"SubscriptionSourceEventResponse":{"properties":{"audience_membership_active":{"type":"boolean"},"consent_event_id":{"format":"uuid","type":"string"},"correlation_id":{"type":"string"},"original_status":{"anyOf":[{"type":"string"},{"type":"null"}]},"reason_class":{"anyOf":[{"type":"string"},{"type":"null"}]},"receipt_id":{"format":"uuid","type":"string"},"schema_version":{"const":"connect.subscription-source-result.v1","type":"string"},"source_event_id":{"format":"uuid","type":"string"},"status":{"enum":["accepted","duplicate","review_required","suppressed"],"type":"string"}},"required":["schema_version","source_event_id","status","receipt_id","consent_event_id","audience_membership_active","reason_class","correlation_id"],"type":"object"},"SuppressRequest":{"examples":[{"reason":"manual","scope":"workspace","source":"authorized_api"}],"properties":{"audience_id":{"type":"string"},"evidence":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"scope":{"enum":["audience","workspace","platform"],"type":"string"},"source":{"type":"string"}},"required":["scope","reason"],"type":"object"},"SuppressResponse":{"properties":{"suppressed":{"type":"boolean"},"suppression_id":{"type":"string"}},"required":["suppressed","suppression_id"],"type":"object"},"SyntheticRehearsal":{"properties":{"claimed_count":{"anyOf":[{"type":"integer"},{"type":"null"}]},"cleanup_verified":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"completed_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}]},"created_at":{"format":"date-time","type":"string"},"duplicate_claim_count":{"anyOf":[{"type":"integer"},{"type":"null"}]},"elapsed_milliseconds":{"anyOf":[{"type":"integer"},{"type":"null"}]},"eligible_count":{"anyOf":[{"type":"integer"},{"type":"null"}]},"excluded_count":{"anyOf":[{"type":"integer"},{"type":"null"}]},"id":{"type":"string"},"provider_call_count":{"type":"integer"},"recipient_count":{"type":"integer"},"recovered_count":{"anyOf":[{"type":"integer"},{"type":"null"}]},"report":{"additionalProperties":true,"type":"object"},"report_checksum":{"anyOf":[{"type":"string"},{"type":"null"}]},"requested_by_gfavip_id":{"type":"string"},"state":{"type":"string"},"target_seconds":{"type":"integer"},"workspace_id":{"type":"string"}},"required":["id","workspace_id","state","recipient_count","target_seconds","elapsed_milliseconds","eligible_count","excluded_count","claimed_count","recovered_count","duplicate_claim_count","provider_call_count","cleanup_verified","report","report_checksum","requested_by_gfavip_id","created_at","completed_at"],"type":"object"},"SyntheticRehearsalDetailResponse":{"properties":{"run":{"$ref":"#/components/schemas/SyntheticRehearsal"}},"required":["run"],"type":"object"},"SyntheticRehearsalRequest":{"examples":[{"confirmation":"RUN 10000 SYNTHETIC REHEARSAL","idempotency_key":"synthetic-capacity-10000-0001","recipient_count":10000}],"properties":{"confirmation":{"type":"string"},"idempotency_key":{"maxLength":200,"minLength":12,"type":"string"},"recipient_count":{"maximum":10000,"minimum":100,"type":"integer"}},"required":["idempotency_key","confirmation"],"type":"object"},"SyntheticRehearsalResponse":{"properties":{"created":{"type":"boolean"},"run":{"$ref":"#/components/schemas/SyntheticRehearsal"}},"required":["created","run"],"type":"object"},"TestSend":{"properties":{"attempt_count":{"type":"integer"},"content_version_id":{"type":"string"},"id":{"type":"string"},"provider_message_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"recipient_email":{"type":"string"},"sender_identity_id":{"type":"string"},"state":{"type":"string"}},"required":["id","state","sender_identity_id","content_version_id","recipient_email","attempt_count","provider_message_id"],"type":"object"},"TestSendRequest":{"examples":[{"confirmation":"SEND TEST EMAIL","content_version_id":"content-version-id","recipient_email":"allowlisted@example.com","sender_identity_id":"sender-id"}],"properties":{"confirmation":{"const":"SEND TEST EMAIL","type":"string"},"content_version_id":{"type":"string"},"recipient_email":{"format":"email","type":"string"},"sender_identity_id":{"type":"string"}},"required":["sender_identity_id","content_version_id","recipient_email","confirmation"],"type":"object"},"TestSendResponse":{"properties":{"test_send":{"$ref":"#/components/schemas/TestSend"}},"required":["test_send"],"type":"object"},"User":{"properties":{"gfavip_user_id":{"type":"string"},"identity_type":{"enum":["human","agent"],"type":"string"},"platform_role":{"anyOf":[{"type":"string"},{"type":"null"}]},"username":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["gfavip_user_id","username","identity_type","platform_role"],"type":"object"},"WorkspaceActivationResponse":{"properties":{"workspace":{"properties":{"id":{"type":"string"},"production_sending_enabled":{"type":"boolean"}},"required":["id","production_sending_enabled"],"type":"object"}},"required":["workspace"],"type":"object"},"WorkspaceListItem":{"properties":{"is_archived":{"type":"boolean"},"name":{"type":"string"},"organization":{"type":"string"},"production_sending_enabled":{"type":"boolean"},"role":{"type":"string"},"workspace":{"type":"string"}},"required":["organization","workspace","name","role","is_archived","production_sending_enabled"],"type":"object"},"WorkspaceResponse":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array"},"is_archived":{"type":"boolean"},"name":{"type":"string"},"organization":{"type":"string"},"production_sending_enabled":{"type":"boolean"},"role":{"type":"string"},"workspace":{"type":"string"}},"required":["organization","workspace","name","role","capabilities","is_archived","production_sending_enabled"],"type":"object"},"WorkspacesResponse":{"properties":{"workspaces":{"items":{"$ref":"#/components/schemas/WorkspaceListItem"},"type":"array"}},"required":["workspaces"],"type":"object"}},"securitySchemes":{"bearerAuth":{"description":"Wallet-issued `gfavip-session-*` token. Never send a PowerLobster API key to Connect.","scheme":"bearer","type":"http"},"sessionCookie":{"description":"Human browser session. Mutating API requests also require `X-CSRF-Token`.","in":"cookie","name":"session","type":"apiKey"},"sourceCredential":{"description":"Hashed, revocable credential for one registered subscription source. It is not a Wallet token and grants no read or send access.","scheme":"bearer","type":"http"}}},"info":{"description":"Implemented production API for governed contacts, consent, authoring, protected CSV imports, versioned automation authoring, a synthetic-only durable automation runtime foundation, sender readiness, delivery controls, and operational rehearsals. Production automation enrollment, execution, and external actions remain unavailable.","title":"HeliumRises Connect API","version":"2026-07-28"},"openapi":"3.1.0","paths":{"/api/v1/me":{"get":{"description":"The live response contains `user`, `auth_method`, `csrf_token`, and `workspaces`. There is no top-level `memberships` field.","operationId":"getMe","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Get validated identity and local memberships","tags":["Identity"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"authenticated","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}":{"get":{"description":"","operationId":"getWorkspace","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Get workspace role, capabilities, and send state","tags":["Identity"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/activate-sending":{"post":{"description":"Requires `ACTIVATE PRODUCTION SENDING`, a ready sender, and all global activation gates.","operationId":"activateWorkspaceSending","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductionActivationRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceActivationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Activate workspace production sending","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":true,"x-required-capability":"manage_senders","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/audiences":{"post":{"description":"","operationId":"createAudience","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceCreateRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceCreateResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"409":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Uniqueness or source-identity conflict. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create an audience","tags":["Audiences"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/audiences/{audience_id}":{"get":{"description":"","operationId":"getAudience","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable audience id.","in":"path","name":"audience_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect an audience","tags":["Audiences"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/audiences/{audience_id}/archive":{"post":{"description":"","operationId":"archiveAudience","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable audience id.","in":"path","name":"audience_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArchiveResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Archive an audience","tags":["Audiences"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/audiences/{audience_id}/subscribe":{"post":{"description":"Refuses with 422 when an unresolved Suppression blocks the contact -- platform-wide, scoped to this workspace, or scoped to this audience -- naming the blocking scope and reason in the error. There is no parameter to override this. Resolve the suppression first via POST /suppressions/{suppression_id}/resolve (resolve_suppressions capability), then call subscribe again.","operationId":"subscribeContact","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable audience id.","in":"path","name":"audience_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceSubscribeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceSubscribeResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Record consent and activate audience membership","tags":["Consent and safety"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/audiences/{audience_id}/unsubscribe":{"post":{"description":"","operationId":"unsubscribeContact","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable audience id.","in":"path","name":"audience_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceUnsubscribeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceUnsubscribeResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Unsubscribe a contact from an audience","tags":["Consent and safety"],"x-idempotency":"Safe to repeat; the resulting audience permission remains unsubscribed.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automation-enrollments/{enrollment_id}":{"get":{"description":"","operationId":"getAutomationEnrollment","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable enrollment id.","in":"path","name":"enrollment_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationEnrollmentResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect a synthetic enrollment timeline","tags":["Automations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"read-only-runtime-observability"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automation-enrollments/{enrollment_id}/{action}":{"post":{"description":"Hard-blocked while the Phase 5D runtime gate is closed.","operationId":"controlSyntheticAutomationEnrollment","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable enrollment id.","in":"path","name":"enrollment_id","required":true,"schema":{"type":"string"}},{"description":"Stable action.","in":"path","name":"action","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationEnrollmentControlRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationEnrollmentResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"409":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Uniqueness or source-identity conflict. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Pause, resume, cancel, or replay synthetic runtime state","tags":["Automations"],"x-idempotency":"State-machine constrained; invalid repeats return 409.","x-platform-and-workspace-owner-required":false,"x-required-capability":"pause_delivery","x-safety-class":"synthetic-only-runtime-control"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations":{"get":{"description":"Returns workspace-local immutable authoring state. Phase 5B has no enrollment, execution, activation, provider, or webhook path.","operationId":"listAutomations","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationListResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"List non-executable automation definitions","tags":["Automations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"read-only-authoring"},"post":{"description":"Validates graph structure and workspace dependencies. Makes zero provider or webhook calls and creates no enrollment.","operationId":"createAutomation","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationCreateRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create a validated automation draft and immutable version","tags":["Automations"],"x-idempotency":"Not idempotent. Automation slug uniqueness prevents duplicate workspace definitions.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_automations","x-safety-class":"database-only-authoring"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations/{automation_id}":{"get":{"description":"","operationId":"getAutomation","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable automation id.","in":"path","name":"automation_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect an automation and immutable version history","tags":["Automations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"read-only-authoring"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations/{automation_id}/archive":{"post":{"description":"","operationId":"archiveAutomation","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable automation id.","in":"path","name":"automation_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Archive an automation authoring definition","tags":["Automations"],"x-idempotency":"Safe to repeat; the authoring definition remains archived.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_automations","x-safety-class":"database-only-authoring"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations/{automation_id}/enrollments":{"get":{"description":"Production currently returns an empty collection.","operationId":"listAutomationEnrollments","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable automation id.","in":"path","name":"automation_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationEnrollmentListResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"List synthetic-only durable automation enrollments","tags":["Automations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"read-only-runtime-observability"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations/{automation_id}/ready-for-review":{"post":{"description":"Records an authoring milestone only. It cannot enroll contacts, schedule steps, send email, call a webhook, or open a gate.","operationId":"markAutomationReadyForReview","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable automation id.","in":"path","name":"automation_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationReviewReadyRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Mark the current checksum-bound version ready for review","tags":["Automations"],"x-idempotency":"Safe to repeat for the same current version and checksum. This is not activation or approval to execute.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_automations","x-safety-class":"database-only-review-state"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations/{automation_id}/restore":{"post":{"description":"Restores authoring only and cannot activate execution.","operationId":"restoreAutomation","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable automation id.","in":"path","name":"automation_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Restore an archived definition as a draft","tags":["Automations"],"x-idempotency":"Accepted only while archived; a repeated request after restore returns 422.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_automations","x-safety-class":"database-only-authoring"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations/{automation_id}/versions":{"post":{"description":"Resets review-ready state to draft. Does not change or migrate historical versions.","operationId":"createAutomationVersion","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable automation id.","in":"path","name":"automation_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationVersionRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Append a validated immutable automation version","tags":["Automations"],"x-idempotency":"Not idempotent. Each accepted request appends a new immutable version.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_automations","x-safety-class":"database-only-authoring"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations/{automation_id}/versions/{version_id}":{"get":{"description":"","operationId":"getAutomationVersion","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable automation id.","in":"path","name":"automation_id","required":true,"schema":{"type":"string"}},{"description":"Stable version id.","in":"path","name":"version_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect one immutable automation version","tags":["Automations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"read-only-authoring"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/automations/{automation_id}/versions/{version_id}/synthetic-enrollments":{"post":{"description":"Hard-blocked in production. Accepts only archived synthetic workspaces and `.invalid` contacts bound to a rehearsal ID.","operationId":"createSyntheticAutomationEnrollment","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable automation id.","in":"path","name":"automation_id","required":true,"schema":{"type":"string"}},{"description":"Stable version id.","in":"path","name":"version_id","required":true,"schema":{"type":"string"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"maxLength":200,"minLength":12,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationSyntheticEnrollmentRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationEnrollmentResponse"}}},"description":"Successful idempotent replay or update","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationEnrollmentResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"409":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Uniqueness or source-identity conflict. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create an idempotent non-production synthetic enrollment","tags":["Automations"],"x-idempotency":"Required Idempotency-Key; replay returns the original row.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_automations","x-safety-class":"synthetic-only-runtime"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/campaign-drafts":{"post":{"description":"Database-only draft creation. It schedules and sends nothing.","operationId":"createCampaignDraft","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDraftRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create a campaign draft","tags":["Campaigns"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_content","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/campaign-drafts/{campaign_id}/schedule":{"post":{"description":"Fails closed unless every global, workspace, provider, domain, sender, content, and production-sending gate is open.","operationId":"scheduleCampaign","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable campaign id.","in":"path","name":"campaign_id","required":true,"schema":{"type":"string"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"maxLength":200,"minLength":12,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRunResponse"}}},"description":"Successful idempotent replay or update","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRunResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create an immutable scheduled campaign run","tags":["Campaigns"],"x-idempotency":"Required `Idempotency-Key`; a replay for the same campaign returns the original run with 200.","x-platform-and-workspace-owner-required":false,"x-required-capability":"schedule_campaign","x-safety-class":"production-delivery-path"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/campaign-drafts/{campaign_id}/versions":{"post":{"description":"","operationId":"createCampaignDraftVersion","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable campaign id.","in":"path","name":"campaign_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDraftRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Append an immutable campaign draft version","tags":["Campaigns"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_content","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/campaign-runs/{run_id}":{"get":{"description":"","operationId":"getCampaignRun","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable run id.","in":"path","name":"run_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRunResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect a campaign run","tags":["Campaigns"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/campaign-runs/{run_id}/report":{"get":{"description":"","operationId":"getCampaignReport","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable run id.","in":"path","name":"run_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignReportResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect per-recipient delivery outcomes and reconciled reporting","tags":["Campaigns"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/campaign-runs/{run_id}/unschedule":{"post":{"description":"","operationId":"unscheduleCampaign","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable run id.","in":"path","name":"run_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRunResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Cancel a still-pending schedule","tags":["Campaigns"],"x-idempotency":"Not replay-safe after the run leaves `scheduled`; later calls return 422.","x-platform-and-workspace-owner-required":false,"x-required-capability":"schedule_campaign","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/campaign-runs/{run_id}/{action}":{"post":{"description":"","operationId":"controlCampaignRun","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable run id.","in":"path","name":"run_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"action","required":true,"schema":{"enum":["pause","resume","cancel"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRunResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Pause, resume, or cancel a campaign run","tags":["Campaigns"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"pause_delivery","x-safety-class":"delivery-control"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/contact-field-definitions":{"post":{"description":"","operationId":"createContactFieldDefinition","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactFieldDefinitionRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactFieldDefinitionResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create the next typed custom-field definition","tags":["Contacts"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/contacts/lookup":{"get":{"description":"","operationId":"lookupContact","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"in":"query","name":"email","required":true,"schema":{"format":"email","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Look up a contact by normalized email","tags":["Contacts"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/contacts/upsert":{"post":{"description":"","operationId":"upsertContact","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactUpsertRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactUpsertResponse"}}},"description":"Successful idempotent replay or update","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactUpsertResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"409":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Uniqueness or source-identity conflict. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create or update a contact","tags":["Contacts"],"x-idempotency":"Idempotent by normalized email; source identity conflicts return 409.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/contacts/{contact_id}/eligibility/{audience_id}":{"get":{"description":"Read-only evaluation. It never contacts Mailgun or a recipient.","operationId":"checkEligibility","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable contact id.","in":"path","name":"contact_id","required":true,"schema":{"type":"string"}},{"description":"Stable audience id.","in":"path","name":"audience_id","required":true,"schema":{"type":"string"}},{"in":"query","name":"message_idempotency_key","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EligibilityResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Evaluate centralized send eligibility","tags":["Consent and safety"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/contacts/{contact_id}/preference-token":{"post":{"description":"","operationId":"issuePreferenceToken","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable contact id.","in":"path","name":"contact_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferenceTokenRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferenceTokenResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Issue scoped preference and one-click URLs","tags":["Consent and safety"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/contacts/{contact_id}/suppress":{"post":{"description":"","operationId":"suppressContact","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable contact id.","in":"path","name":"contact_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create a safety suppression","tags":["Consent and safety"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"resolve_suppressions","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/email-templates":{"post":{"description":"","operationId":"createEmailTemplate","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailTemplateRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailTemplateResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create an email-template container","tags":["Content"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_content","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/email-templates/{template_id}/archive":{"post":{"description":"Shelves the template container. Send `{\"archived\": false}` to restore it; an empty body archives. Content versions are untouched, and a campaign already referencing one keeps working. The slug stays reserved either way, since slugs are unique per workspace whether or not the template is archived.","operationId":"archiveEmailTemplate","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable template id.","in":"path","name":"template_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailTemplateArchiveRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailTemplateArchiveResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Archive or restore an email template","tags":["Content"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_content","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/email-templates/{template_id}/versions":{"post":{"description":"Database-only authoring. It sends no email. The submitted HTML is sanitized against an allowlist before it is stored, and only the sanitized copy is ever sent. Check `validation.stripped` on the response: it lists tags, attributes, and CSS properties the sanitizer removed. Non-empty lists mean the stored email no longer looks like what was submitted. /skill.md documents the allowlist and the house email structure.","operationId":"createContentVersion","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable template id.","in":"path","name":"template_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentVersionRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentVersionResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create an immutable sanitized content version","tags":["Content"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"edit_content","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/imports/csv":{"get":{"description":"","operationId":"listCsvImports","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportListResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"List protected CSV imports","tags":["Imports"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"read-only"},"post":{"description":"","operationId":"uploadCsvImport","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"audience_id":{"type":"string"},"file":{"description":"UTF-8 CSV protected immediately after upload.","format":"binary","type":"string"},"source_label":{"maxLength":160,"type":"string"}},"required":["file","audience_id","source_label"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Upload a protected CSV","tags":["Imports"],"x-idempotency":"Not idempotent. The response job ID and file checksum identify the durable upload; do not retry after receiving 201.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"encrypted-upload-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/imports/csv-mapping-profiles":{"get":{"description":"","operationId":"listCsvImportMappingProfiles","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportMappingProfileListResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"List reusable CSV mapping profiles","tags":["Imports"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"read-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/imports/csv/{job_id}":{"get":{"description":"","operationId":"getCsvImport","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable job id.","in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect a protected CSV import","tags":["Imports"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"read-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/imports/csv/{job_id}/approve":{"post":{"description":"","operationId":"approveCsvImport","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable job id.","in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportApprovalRequest"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Approve a checksum-bound import apply","tags":["Imports"],"x-idempotency":"Approval is checksum-bound and accepted once. Apply uses a per-row idempotency ledger.","x-platform-and-workspace-owner-required":false,"x-required-capability":"approve_imports","x-safety-class":"database-import-queue"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/imports/csv/{job_id}/cancel":{"post":{"description":"","operationId":"cancelCsvImport","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable job id.","in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Cancel an import and destroy its payload","tags":["Imports"],"x-idempotency":"Terminal cleanup operation. A cancelled or purged payload cannot be restored.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"destructive-payload-cleanup"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/imports/csv/{job_id}/mapping":{"patch":{"description":"","operationId":"configureCsvImport","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable job id.","in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportMappingRequest"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Configure mapping and queue a zero-write dry run","tags":["Imports"],"x-idempotency":"Repeatable before approval. Reconfiguration invalidates any prior report and approval.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"zero-write-analysis-queue"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/imports/csv/{job_id}/retry":{"post":{"description":"","operationId":"retryCsvImport","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable job id.","in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Retry a failed import safely","tags":["Imports"],"x-idempotency":"Only failed jobs are accepted. A still-valid checksum-bound approval retries apply; otherwise the job returns to dry run.","x-platform-and-workspace-owner-required":false,"x-required-capability":"upsert_contacts","x-safety-class":"idempotent-recovery-queue"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/operations/preflight":{"get":{"description":"","operationId":"getLatestPreflight","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreflightResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Get the latest launch preflight","tags":["Operations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"},"post":{"description":"May perform readiness inspection but sends no email and opens no gates.","operationId":"runPreflight","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreflightResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Run the fail-closed launch preflight","tags":["Operations"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"read-only-checks-with-retained-report"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/operations/synthetic-rehearsals":{"post":{"description":"Uses no subscriber data, makes zero provider calls, sends no email, and rolls back synthetic operational rows.","operationId":"startSyntheticRehearsal","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticRehearsalRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticRehearsalResponse"}}},"description":"Successful idempotent replay or update","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticRehearsalResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Queue an isolated synthetic capacity rehearsal","tags":["Operations"],"x-idempotency":"Required body `idempotency_key`; a replay returns the original run with 200.","x-platform-and-workspace-owner-required":true,"x-required-capability":"manage_senders","x-safety-class":"synthetic-database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/operations/synthetic-rehearsals/{run_id}":{"get":{"description":"","operationId":"getSyntheticRehearsal","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable run id.","in":"path","name":"run_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticRehearsalDetailResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect a synthetic capacity rehearsal","tags":["Operations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/provider-connections":{"post":{"description":"","operationId":"createProviderConnection","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create a secret-reference-only Mailgun connection","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/provider-connections/{connection_id}/activate":{"post":{"description":"Requires the exact confirmation `ENABLE TEST CONNECTION`. This does not enable production sending.","operationId":"activateProviderConnection","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable connection id.","in":"path","name":"connection_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderActivationRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Enable a verified connection for test activity","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/provider-connections/{connection_id}/check":{"post":{"description":"Contacts Mailgun for an account-level check but sends no email.","operationId":"checkProviderConnection","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable connection id.","in":"path","name":"connection_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Test the Mailgun connection","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"external-read-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/provider-events/{event_id}/replay":{"post":{"description":"","operationId":"replayProviderEvent","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable event id.","in":"path","name":"event_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderEventReplayResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Replay a stored verified provider event","tags":["Operations"],"x-idempotency":"Provider-event processing is deduplicated by the stored provider event.","x-platform-and-workspace-owner-required":false,"x-required-capability":"pause_delivery","x-safety-class":"database-only-event-reprocessing"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/rehearsals":{"post":{"description":"Queues one gated test email and observes signed Mailgun events. It is not a marketing send.","operationId":"startControlledRehearsal","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"maxLength":200,"minLength":12,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RehearsalRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RehearsalResponse"}}},"description":"Successful idempotent replay or update","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RehearsalResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Start a controlled provider-event rehearsal","tags":["Delivery safety"],"x-idempotency":"Required `Idempotency-Key`; a replay returns the original rehearsal with 200.","x-platform-and-workspace-owner-required":false,"x-required-capability":"send_test","x-safety-class":"may-contact-mailgun-and-one-allowlisted-recipient"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/rehearsals/{rehearsal_id}":{"get":{"description":"","operationId":"getControlledRehearsal","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable rehearsal id.","in":"path","name":"rehearsal_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RehearsalResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Inspect controlled rehearsal reconciliation","tags":["Delivery safety"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"view","x-safe":true,"x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/sender-identities":{"post":{"description":"","operationId":"createSenderIdentity","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderIdentityRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderIdentityResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create a disabled sender identity","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/sender-identities/{sender_id}/activate":{"post":{"description":"Requires `ACTIVATE PRODUCTION SENDING` and closed-by-default global activation gates.","operationId":"activateSenderIdentity","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable sender id.","in":"path","name":"sender_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductionActivationRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderActivationResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Activate a sender behind production gates","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":true,"x-required-capability":"manage_senders","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/sending-domains":{"post":{"description":"","operationId":"createSendingDomain","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomainRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomainResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create a sender-domain readiness record","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/sending-domains/{domain_id}/provider":{"post":{"description":"","operationId":"configureDomainProvider","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable domain id.","in":"path","name":"domain_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainProviderRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomainResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Associate a Mailgun connection and DKIM selector","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/sending-domains/{domain_id}/readiness":{"post":{"description":"","operationId":"updateDomainReadiness","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable domain id.","in":"path","name":"domain_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomainReadinessRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomainResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Update manually recorded domain readiness","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/sending-domains/{domain_id}/verify":{"post":{"description":"Performs DNS lookups and Mailgun status reads. It sends no email.","operationId":"verifySendingDomain","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable domain id.","in":"path","name":"domain_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainVerifyResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Run live DNS and Mailgun domain verification","tags":["Sender readiness"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"manage_senders","x-safety-class":"external-read-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/subscription-sources/{source_slug}/audiences":{"get":{"description":"Read-only companion to the ingest route, for a caller building an audience picker. Returns exactly the source's allowlisted audiences minus archived ones, so a rendered picker cannot offer a choice ingestion would refuse. Reveals nothing the credential's own allowlist does not already grant.","operationId":"listSubscriptionSourceAudiences","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Registered subscription source slug.","in":"path","name":"source_slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionSourceAudiencesResponse"}}},"description":"Allowed, unarchived audiences for this source","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Invalid or expired source credential. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Source revoked, suspended, or route mismatch. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"429":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Rate limit exceeded for this subscription source. Counted per source over a fixed one-minute window and applied before the credential is checked, so an invalid credential is counted too.. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"sourceCredential":[]}],"summary":"List the audiences this source may write to","tags":["Subscription sources"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-required-capability":"active scoped subscription-source credential","x-safe":true,"x-safety-class":"read-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/subscription-sources/{source_slug}/events":{"post":{"description":"Source-only ingestion for MemoUpdate. The credential is fixed to one workspace, source, exact audience allowlist, and origin allowlist. This operation cannot schedule or send.","operationId":"ingestSubscriptionSourceEvent","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Registered subscription source slug.","in":"path","name":"source_slug","required":true,"schema":{"type":"string"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"maxLength":200,"minLength":12,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionSourceEventRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionSourceEventResponse"}}},"description":"Exact idempotent replay","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionSourceEventResponse"}}},"description":"Consent accepted and audience membership active","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionSourceEventResponse"}}},"description":"Consent recorded but suppression or review prevents membership","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Invalid or expired source credential. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Source revoked, suspended, or route mismatch. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"409":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Idempotency key payload conflict. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Invalid evidence, audience, origin, or consent. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"429":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Rate limit exceeded for this subscription source. The limit is counted per source over a fixed one-minute window and applies before the credential is checked, so an invalid credential is counted too. `Retry-After` carries the window length in seconds.. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Transient ingestion failure. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"sourceCredential":[]}],"summary":"Record explicit consent from an approved source","tags":["Subscription sources"],"x-idempotency":"Required Idempotency-Key. Exact replay returns the original receipt as duplicate; a changed payload returns 409.","x-required-capability":"active scoped subscription-source credential","x-safety-class":"consent-ingestion-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/suppressions/{suppression_id}/resolve":{"post":{"description":"Platform-scope safety suppressions also require a platform owner or administrator.","operationId":"resolveSuppression","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"description":"Stable suppression id.","in":"path","name":"suppression_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveSuppressionRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolvedResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Resolve an eligible suppression","tags":["Consent and safety"],"x-idempotency":"Not guaranteed idempotent; check operation-specific retry behavior.","x-platform-and-workspace-owner-required":false,"x-required-capability":"resolve_suppressions","x-safety-class":"database-only"}},"/api/v1/organizations/{organization_slug}/workspaces/{workspace_slug}/test-sends":{"post":{"description":"Requires `SEND TEST EMAIL`, an allowlisted recipient, verified domain, active provider, and test-send configuration gate.","operationId":"requestTestSend","parameters":[{"$ref":"#/components/parameters/OrganizationSlug"},{"$ref":"#/components/parameters/WorkspaceSlug"},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"maxLength":200,"minLength":12,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSendRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSendResponse"}}},"description":"Successful idempotent replay or update","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSendResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"403":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authenticated but not authorized. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Resource or unauthorized workspace not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"422":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Request failed validation or a safety gate. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Queue a tightly gated allowlisted test email","tags":["Delivery safety"],"x-idempotency":"Required `Idempotency-Key`; a replay returns the original request with 200.","x-platform-and-workspace-owner-required":false,"x-required-capability":"send_test","x-safety-class":"may-contact-mailgun-and-one-allowlisted-recipient"}},"/api/v1/workspaces":{"get":{"description":"","operationId":"listWorkspaces","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspacesResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Authentication required or Wallet token invalid. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Wallet identity validation unavailable. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"List locally assigned workspaces","tags":["Identity"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-platform-and-workspace-owner-required":false,"x-required-capability":"authenticated","x-safe":true,"x-safety-class":"database-only"}},"/healthz":{"get":{"operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[],"summary":"Process health","tags":["Operations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-safe":true}},"/preferences/one-click/{token}":{"post":{"description":"A validly signed token is honoured however old it is, so a mail client's own unsubscribe button keeps working on an old message. Aged use is recorded on the audit event as `link_expired`. Forged, tampered, and foreign-key tokens are still refused with 400.","operationId":"oneClickUnsubscribe","parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"properties":{"List-Unsubscribe":{"const":"One-Click","type":"string"}},"required":["List-Unsubscribe"],"type":"object"}}},"required":true},"responses":{"204":{"description":"Unsubscribed; no response body","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"400":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Invalid RFC 8058 body, preference token, or purpose. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Contact or audience not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[],"summary":"Apply an RFC 8058 one-click unsubscribe","tags":["Consent and safety"],"x-idempotency":"Safe to repeat; unsubscribe state remains restrictive.","x-required-capability":"valid signed preference token","x-safety-class":"suppression-increasing-public-action"}},"/preferences/{token}":{"post":{"description":"A validly signed token is honoured however old it is. `PREFERENCE_TOKEN_MAX_AGE_SECONDS` decides when the hosted page tells the reader the link came from an older email, not when the link stops working: refusing an aged unsubscribe leaves the reader with no way out but a spam report. Aged use is recorded on the audit event as `link_expired`. Forged, tampered, and foreign-key tokens are still refused with 400.","operationId":"submitPreference","parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferenceUnsubscribeResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"400":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Invalid preference token or purpose. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Contact or audience not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[],"summary":"Apply a signed preference unsubscribe","tags":["Consent and safety"],"x-idempotency":"Safe to repeat; unsubscribe state remains restrictive.","x-required-capability":"valid signed preference token","x-safety-class":"suppression-increasing-public-action"}},"/readyz":{"get":{"operationId":"readiness","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessResponse"}}},"description":"Database unavailable","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[],"summary":"Database readiness","tags":["Operations"],"x-idempotency":"Safe and idempotent read-only operation; repeating it does not change server state.","x-idempotent":true,"x-safe":true}},"/webhooks/mailgun/{connection_id}":{"post":{"description":"Provider callback. Accepts JSON or Mailgun form fields whose `event-data` and `signature` values are JSON strings.","operationId":"receiveMailgunWebhook","parameters":[{"in":"path","name":"connection_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MailgunWebhookEnvelope"}},"application/x-www-form-urlencoded":{"schema":{"properties":{"event-data":{"description":"JSON-encoded event data.","type":"string"},"signature":{"description":"JSON-encoded signature data.","type":"string"}},"required":["event-data","signature"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MailgunWebhookResponse"}}},"description":"Successful response","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"400":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Invalid envelope, event, or unsupported event type. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"401":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Invalid or unavailable signing key. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"404":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Provider connection not found. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}},"429":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Rate limit exceeded for this provider connection. Counted per connection over a fixed one-minute window, ahead of signature verification, so one connection's burst cannot refuse another's. `Retry-After` carries the window length in seconds.. The current API returns Flask's standard `text/html` error body; use the HTTP status and `X-Correlation-ID` for handling.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}}}},"security":[],"summary":"Receive and deduplicate a signed Mailgun event","tags":["Operations"],"x-idempotency":"Deduplicated by provider connection and Mailgun event ID.","x-required-capability":"valid Mailgun webhook signature","x-safety-class":"signed-provider-event-processing"}}},"servers":[{"url":"https://connect.heliumrises.com"}],"tags":[{"name":"Identity"},{"name":"Contacts"},{"name":"Audiences"},{"name":"Imports"},{"name":"Consent and safety"},{"name":"Sender readiness"},{"name":"Content"},{"name":"Campaigns"},{"name":"Automations"},{"name":"Delivery safety"},{"name":"Operations"},{"name":"Subscription sources"}]}
