{"openapi":"3.1.0","info":{"title":"rasket API","version":"1.0.0","description":"The rasket transactional email API. Authenticate with `Authorization: Bearer rk_…` and send a User-Agent on every request. Every operation carries `x-rasket-permission` — the least credential that reaches it: `sending_access` or `full_access` for an API key, `session` for the dashboard cookie, `none` for an unauthenticated route, or `null` when no key or session reaches it (`/mcp` takes only an OAuth access token) — and `x-rasket-scope`, the OAuth scope a token needs, or `null` when no scope reaches it."},"servers":[{"url":"https://api.rasket.com","description":"production"},{"url":"https://www.rasket.com/api/v1","description":"this deployment"}],"tags":[{"name":"operations","description":"Liveness and readiness. Unauthenticated, outside the customer contract."},{"name":"auth","description":"The dashboard's own session: signup, login, logout, verification, password reset and MFA. Cookie-authenticated; not callable with an API key."},{"name":"teams","description":"The teams a signed-in user belongs to, switching between them, members and invitations. Session only."},{"name":"billing","description":"The team's plan, Checkout, the billing portal, invoices, pay-as-you-go and add-ons. A `full_access` API key or a session; an OAuth token may read with `billing:read` and never write."},{"name":"domains","description":"Sending domains: add one, publish its DNS records, verify, claim, rotate DKIM and auto-configure."},{"name":"api-keys","description":"Create, list, rename and revoke API keys."},{"name":"suppressions","description":"Addresses the team will not send to, and why — added by a bounce, a complaint or by hand."},{"name":"webhooks","description":"Webhook endpoints, their signing secrets, the events delivered to them, attempts and replay."},{"name":"logs","description":"Every request made with the team's credentials."},{"name":"templates","description":"Versioned email content with typed variables, addressed by id or alias."},{"name":"emails","description":"Send, batch, retrieve, list, reschedule and cancel emails; attachments, metrics and share links."},{"name":"receiving","description":"Mail sent to the team's receiving domains: the message, its attachments and its raw source."},{"name":"contact-properties","description":"The typed custom fields every contact in the team can carry."},{"name":"contacts","description":"The audience: contacts, CSV imports, their segment memberships and topic choices."},{"name":"segments","description":"Audiences defined by a filter, by hand, or both."},{"name":"topics","description":"What contacts subscribe to, and the list the preference page shows."},{"name":"broadcasts","description":"One message to a segment: the draft, the send gate, the send and the report."},{"name":"oauth","description":"The OAuth 2.1 authorization server: authorize, token, dynamic client registration, revocation and grants."},{"name":"automations","description":"Workflows that run per contact: the step graph, its versions, and every run."},{"name":"events","description":"Custom events: the names a product fires, and sending one to start an automation."},{"name":"mcp","description":"The remote Model Context Protocol server. Takes an OAuth access token and nothing else."},{"name":"team","description":"The team a credential belongs to: its profile, plan, sender identity, AI assist and single sign-on summary, and its members."},{"name":"ai","description":"AI assist: subject-line suggestions, drafting a body from a brief, and explaining what happened to an email. Needs AI assist turned on for the team; each accepted request spends one of the month's AI credits. A `full_access` API key, or an OAuth token with `ai:use`."}],"security":[{"bearerAuth":[]}],"components":{"schemas":{"CreateContactImportOptions":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"CSV file to import. Maximum size is 50MB."},"column_map":{"type":"string","description":"JSON-encoded object mapping contact fields and custom property keys to CSV column names. Supports `email`, `first_name`, `last_name`, `unsubscribed`, and `properties`. Custom property mappings can include `type` as `string`, `number`, or `boolean`; defaults to `string`.","example":"{\"email\":\"Email\",\"first_name\":\"First Name\",\"last_name\":\"Last Name\",\"unsubscribed\":\"Unsubscribed\",\"properties\":{\"plan\":{\"column\":\"Plan\",\"type\":\"string\"}}}"},"on_conflict":{"type":"string","enum":["upsert","skip"],"default":"skip","description":"Strategy to use when an imported contact already exists.","example":"skip"},"segments":{"type":"string","description":"JSON-encoded array of segments to add imported contacts to.","example":"[{\"id\":\"78261eea-8f8b-4381-83c6-79fa7120f1cf\"}]"},"topics":{"type":"string","description":"JSON-encoded array of topic subscriptions to apply to imported contacts. Each `subscription` must be `opt_in` or `opt_out`.","example":"[{\"id\":\"b6d24b8e-af0b-4c3c-be0c-359bbd97381e\",\"subscription\":\"opt_in\"}]"}},"required":["file"]},"Health":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]},"version":{"type":"string"},"env":{"type":"string"}},"required":["status","version","env"],"additionalProperties":false},"Ready":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"]},"version":{"type":"string"},"env":{"type":"string"},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"ok":{"type":"boolean"},"durationMs":{"type":"number"},"error":{"type":"string"}},"required":["name","ok","durationMs"],"additionalProperties":false}},"failed":{"type":"array","items":{"type":"string"}}},"required":["status","version","env","checks","failed"],"additionalProperties":false},"Error":{"type":"object","properties":{"statusCode":{"type":"integer"},"name":{"type":"string","enum":["invalid_idempotency_key","validation_error","missing_api_key","restricted_api_key","email_above_quota","invalid_permission","suspended_api_key","not_found","method_not_allowed","concurrent_idempotent_requests","invalid_idempotent_request","resource_locked","invalid_attachment","invalid_parameter","missing_required_field","missing_required_parameter","daily_quota_exceeded","monthly_quota_exceeded","rate_limit_exceeded","application_error","not_implemented","service_unavailable"]},"message":{"type":"string"},"code":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"additionalProperties":false}},"claimable":{"type":"boolean"}},"required":["statusCode","name","message"],"additionalProperties":false},"Session":{"type":"object","properties":{"object":{"type":"string","enum":["session"]},"user":{"$ref":"#/components/schemas/User"},"current_team":{"$ref":"#/components/schemas/Team"}},"required":["object","user","current_team"],"additionalProperties":false},"User":{"type":"object","properties":{"object":{"type":"string","enum":["user"]},"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"name":{"type":["string","null"]},"email_verified_at":{"type":["string","null"]},"created_at":{"type":"string"}},"required":["object","id","email","name","email_verified_at","created_at"],"additionalProperties":false},"Team":{"type":["object","null"],"properties":{"object":{"type":"string","enum":["team"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"risk_state":{"type":"string"},"created_at":{"type":"string"}},"required":["object","id","name","slug","risk_state","created_at"],"additionalProperties":false},"SignupRequest":{"type":"object","properties":{"email":{"type":"string","minLength":3,"maxLength":320},"password":{"type":"string","minLength":6,"maxLength":4096},"name":{"type":"string","maxLength":200}},"required":["email","password"]},"MfaChallenge":{"type":"object","properties":{"object":{"type":"string","enum":["mfa_challenge"]},"challenge_token":{"type":"string"},"expires_at":{"type":"string"}},"required":["object","challenge_token","expires_at"],"additionalProperties":false},"LoginRequest":{"type":"object","properties":{"email":{"type":"string","minLength":3,"maxLength":320},"password":{"type":"string","minLength":1,"maxLength":4096}},"required":["email","password"]},"LogoutResult":{"type":"object","properties":{"object":{"type":"string","enum":["session"]},"revoked":{"type":"boolean","enum":[true]}},"required":["object","revoked"],"additionalProperties":false},"LogoutRequest":{"type":"object","properties":{"all":{"type":"boolean"}}},"VerifyEmailResult":{"type":"object","properties":{"object":{"type":"string","enum":["user"]},"id":{"type":"string","format":"uuid"},"email_verified_at":{"type":["string","null"]}},"required":["object","id","email_verified_at"],"additionalProperties":false},"TokenRequest":{"type":"object","properties":{"token":{"type":"string","minLength":1,"maxLength":512}},"required":["token"]},"PasswordResetRequested":{"type":"object","properties":{"object":{"type":"string","enum":["password_reset"]},"requested":{"type":"boolean","enum":[true]}},"required":["object","requested"],"additionalProperties":false},"EmailRequest":{"type":"object","properties":{"email":{"type":"string","minLength":3,"maxLength":320}},"required":["email"]},"PasswordResetResult":{"type":"object","properties":{"object":{"type":"string","enum":["user"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"ResetPasswordRequest":{"type":"object","properties":{"token":{"type":"string","minLength":1,"maxLength":512},"password":{"type":"string","minLength":6,"maxLength":4096}},"required":["token","password"]},"MfaStatus":{"type":"object","properties":{"object":{"type":"string","enum":["mfa"]},"enabled":{"type":"boolean"},"enabled_at":{"type":["string","null"]},"enrolling":{"type":"boolean"},"recovery_codes_remaining":{"type":"integer"},"has_password":{"type":"boolean"}},"required":["object","enabled","enabled_at","enrolling","recovery_codes_remaining","has_password"],"additionalProperties":false},"MfaEnrolment":{"type":"object","properties":{"object":{"type":"string","enum":["mfa_enrolment"]},"otpauth_url":{"type":"string"},"secret":{"type":"string"}},"required":["object","otpauth_url","secret"],"additionalProperties":false},"MfaActivated":{"type":"object","properties":{"object":{"type":"string","enum":["mfa"]},"enabled":{"type":"boolean","enum":[true]},"enabled_at":{"type":"string"},"recovery_codes":{"type":"array","items":{"type":"string"}}},"required":["object","enabled","enabled_at","recovery_codes"],"additionalProperties":false},"MfaConfirmRequest":{"type":"object","properties":{"code":{"type":"string","minLength":1,"maxLength":64},"password":{"type":"string","maxLength":4096}},"required":["code"]},"MfaDisabled":{"type":"object","properties":{"object":{"type":"string","enum":["mfa"]},"enabled":{"type":"boolean","enum":[false]},"enabled_at":{"type":"null"}},"required":["object","enabled","enabled_at"],"additionalProperties":false},"MfaRecoveryCodes":{"type":"object","properties":{"object":{"type":"string","enum":["mfa_recovery_codes"]},"recovery_codes":{"type":"array","items":{"type":"string"}}},"required":["object","recovery_codes"],"additionalProperties":false},"MfaCodeRequest":{"type":"object","properties":{"code":{"type":"string","minLength":1,"maxLength":64}},"required":["code"]},"MfaVerifyRequest":{"type":"object","properties":{"challenge_token":{"type":"string","minLength":1,"maxLength":512},"code":{"type":"string","minLength":1,"maxLength":64}},"required":["challenge_token","code"]},"MfaRecoveryRequest":{"type":"object","properties":{"challenge_token":{"type":"string","minLength":1,"maxLength":512},"recovery_code":{"type":"string","minLength":1,"maxLength":64}},"required":["challenge_token","recovery_code"]},"Me":{"type":"object","properties":{"object":{"type":"string","enum":["user"]},"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"name":{"type":["string","null"]},"email_verified_at":{"type":["string","null"]},"current_team_id":{"type":["string","null"],"format":"uuid"},"teams":{"type":"array","items":{"$ref":"#/components/schemas/Team"}}},"required":["object","id","email","name","email_verified_at","current_team_id","teams"],"additionalProperties":false},"CreateTeamRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200}},"required":["name"]},"TeamList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Team"}}},"required":["object","has_more","data"],"additionalProperties":false},"TeamMemberList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TeamMember"}}},"required":["object","has_more","data"],"additionalProperties":false},"TeamMember":{"type":"object","properties":{"object":{"type":"string","enum":["team_member"]},"id":{"type":"string","format":"uuid"},"user_id":{"type":"string","format":"uuid"},"email":{"type":"string"},"name":{"type":["string","null"]},"role":{"type":"string"},"mfa_enabled":{"type":"boolean"},"sso_exempt":{"type":"boolean"},"created_at":{"type":"string"}},"required":["object","id","user_id","email","name","role","mfa_enabled","sso_exempt","created_at"],"additionalProperties":false},"Billing":{"type":"object","properties":{"object":{"type":"string","enum":["billing"]},"plan":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"monthly_price_cents":{"type":"integer"},"included_emails":{"type":"integer"},"overage_per_1000_cents":{"type":["integer","null"]}},"required":["code","name","monthly_price_cents","included_emails","overage_per_1000_cents"],"additionalProperties":false},"effective_plan_code":{"type":"string"},"subscription":{"type":["object","null"],"properties":{"status":{"type":"string"},"current_period_start":{"type":"string"},"current_period_end":{"type":"string"},"invoicing":{"type":"string"},"latest_invoice_status":{"type":["string","null"]}},"required":["status","current_period_start","current_period_end","invoicing","latest_invoice_status"],"additionalProperties":false},"usage":{"type":"object","properties":{"period_start":{"type":"string"},"period_end":{"type":"string"},"emails":{"type":"integer"},"included_emails":{"type":"integer"}},"required":["period_start","period_end","emails","included_emails"],"additionalProperties":false},"pay_as_you_go":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"],"additionalProperties":false},"payment_method":{"type":"object","properties":{"present":{"type":"boolean"},"brand":{"type":["string","null"]},"last4":{"type":["string","null"]}},"required":["present","brand","last4"],"additionalProperties":false},"addons":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"quantity":{"type":"integer"},"status":{"type":"string"}},"required":["code","quantity","status"],"additionalProperties":false}},"pending_change":{"type":["object","null"],"properties":{"plan_code":{"type":"string"},"plan_name":{"type":"string"},"effective_at":{"type":"string"}},"required":["plan_code","plan_name","effective_at"],"additionalProperties":false},"checkout_available":{"type":"boolean"}},"required":["object","plan","effective_plan_code","subscription","usage","pay_as_you_go","payment_method","addons","pending_change","checkout_available"],"additionalProperties":false},"CheckoutSession":{"type":"object","properties":{"object":{"type":"string","enum":["checkout_session"]},"url":{"type":"string","format":"uri"},"expires_at":{"type":"string"}},"required":["object","url","expires_at"],"additionalProperties":false},"PortalSession":{"type":"object","properties":{"object":{"type":"string","enum":["portal_session"]},"url":{"type":"string","format":"uri"}},"required":["object","url"],"additionalProperties":false},"BillingInvoiceList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/BillingInvoice"}}},"required":["object","has_more","data"],"additionalProperties":false},"BillingInvoice":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":["string","null"]},"status":{"type":"string"},"total_cents":{"type":"integer"},"currency":{"type":"string"},"created_at":{"type":"string"},"hosted_invoice_url":{"type":["string","null"]},"invoice_pdf":{"type":["string","null"]}},"required":["id","number","status","total_cents","currency","created_at","hosted_invoice_url","invoice_pdf"],"additionalProperties":false},"CreateDomainResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"type":"string"},"status":{"type":"string","enum":["pending","verified","failed","not_started","partially_verified","partially_failed"]},"capabilities":{"$ref":"#/components/schemas/DomainCapabilities"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DomainRecord"}},"region":{"type":"string","enum":["us-east-1","eu-west-1","sa-east-1","ap-northeast-1"]},"open_tracking":{"type":"boolean"},"click_tracking":{"type":"boolean"},"tracking_subdomain":{"type":"string"}},"required":["id","name","created_at","status","capabilities","records","region","open_tracking","click_tracking","tracking_subdomain"],"additionalProperties":false},"DomainCapabilities":{"type":"object","properties":{"sending":{"type":"string","enum":["enabled","disabled"]},"receiving":{"type":"string","enum":["enabled","disabled"]}},"required":["sending","receiving"],"additionalProperties":false},"DomainRecord":{"type":"object","properties":{"record":{"type":"string","enum":["SPF","DKIM","Receiving","Tracking","TrackingCAA"]},"name":{"type":"string"},"type":{"type":"string","enum":["MX","TXT","CNAME","CAA"]},"ttl":{"type":"string"},"status":{"type":"string","enum":["pending","verified","failed","temporary_failure","not_started"]},"value":{"type":"string"},"priority":{"type":"integer"}},"required":["record","name","type","ttl","status","value"],"additionalProperties":false},"DomainList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListDomainsItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ListDomainsItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["pending","verified","failed","not_started","partially_verified","partially_failed"]},"created_at":{"type":"string"},"region":{"type":"string","enum":["us-east-1","eu-west-1","sa-east-1","ap-northeast-1"]},"open_tracking":{"type":"boolean"},"click_tracking":{"type":"boolean"},"capabilities":{"$ref":"#/components/schemas/DomainCapabilities"}},"required":["id","name","status","created_at","region","open_tracking","click_tracking","capabilities"],"additionalProperties":false},"DomainClaim":{"type":"object","properties":{"object":{"type":"string","enum":["domain_claim"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["pending","verified","completed","blocked","expired","superseded","canceled","failed"]},"domain_id":{"type":["string","null"],"format":"uuid"},"region":{"type":["string","null"],"enum":["us-east-1","eu-west-1","sa-east-1","ap-northeast-1",null]},"record":{"$ref":"#/components/schemas/DomainClaimRecord"},"blocked_reason":{"type":["string","null"],"enum":["grace_period","recent_owner_activity","pending_scheduled_emails",null]},"failure_reason":{"type":["string","null"]},"created_at":{"type":"string"},"expires_at":{"type":"string"}},"required":["object","id","name","status","domain_id","region","record","blocked_reason","failure_reason","created_at","expires_at"],"additionalProperties":false},"DomainClaimRecord":{"type":"object","properties":{"record":{"type":"string","enum":["Claim"]},"name":{"type":"string"},"type":{"type":"string","enum":["TXT"]},"ttl":{"type":"string"},"status":{"type":"string","enum":["pending","verified","failed","temporary_failure","not_started"]},"value":{"type":"string"}},"required":["record","name","type","ttl","status","value"],"additionalProperties":false},"Domain":{"type":"object","properties":{"object":{"type":"string","enum":["domain"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["pending","verified","failed","not_started","partially_verified","partially_failed"]},"created_at":{"type":"string"},"region":{"type":"string","enum":["us-east-1","eu-west-1","sa-east-1","ap-northeast-1"]},"open_tracking":{"type":"boolean"},"click_tracking":{"type":"boolean"},"tracking_subdomain":{"type":"string"},"capabilities":{"$ref":"#/components/schemas/DomainCapabilities"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DomainRecord"}}},"required":["object","id","name","status","created_at","region","open_tracking","click_tracking","tracking_subdomain","capabilities","records"],"additionalProperties":false},"DomainRef":{"type":"object","properties":{"object":{"type":"string","enum":["domain"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"DeleteDomainResponse":{"type":"object","properties":{"object":{"type":"string","enum":["domain"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"AutoconfigureResponse":{"type":"object","properties":{"object":{"type":"string","enum":["domain"]},"id":{"type":"string","format":"uuid"},"created":{"type":"array","items":{"type":"string"}},"updated":{"type":"array","items":{"type":"string"}},"conflicts":{"type":"array","items":{"type":"string"}},"credential_kept":{"type":"boolean"}},"required":["object","id","created","updated","conflicts","credential_kept"],"additionalProperties":false},"DeleteCredentialResponse":{"type":"object","properties":{"object":{"type":"string","enum":["domain"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"CreateApiKeyResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"token":{"type":"string"}},"required":["id","token"],"additionalProperties":false},"ApiKeyList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["object","has_more","data"],"additionalProperties":false},"ApiKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"permission":{"type":"string","enum":["full_access","sending_access"]},"domain_id":{"type":["string","null"],"format":"uuid"},"key_prefix":{"type":"string"},"status":{"type":"string","enum":["active","revoked","suspended"]},"last_used_request_log_id":{"type":["string","null"],"format":"uuid"}},"required":["id","name","created_at","last_used_at","permission","domain_id","key_prefix","status","last_used_request_log_id"],"additionalProperties":false},"UpdateApiKeyResponse":{"type":"object","properties":{"object":{"type":"string","enum":["api_key"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"DeleteApiKeyResponse":{"type":"object","properties":{"object":{"type":"string","enum":["api_key"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"CreatedSuppressionList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CreatedSuppression"}}},"required":["data"],"additionalProperties":false},"CreatedSuppression":{"type":"object","properties":{"object":{"type":"string","enum":["suppression"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"BatchAddSuppressionsRequest":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":100,"example":["steve.wozniak@gmail.com"]}},"required":["emails"]},"RemovedSuppressionList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RemovedSuppression"}}},"required":["data"],"additionalProperties":false},"RemovedSuppression":{"type":"object","properties":{"object":{"type":"string","enum":["suppression"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean"}},"required":["object","deleted"],"additionalProperties":false},"BatchRemoveSuppressionsRequest":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":100},"ids":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":100,"example":["e169aa45-1ecf-4183-9955-b1499d5701d3"]}}},"CreateSuppressionRequest":{"type":"object","properties":{"email":{"type":"string","minLength":3,"maxLength":320,"example":"steve.wozniak@gmail.com"}},"required":["email"]},"SuppressionList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SuppressionListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"SuppressionListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"origin":{"type":"string","enum":["bounce","complaint","manual","unsubscribe"]},"source_id":{"type":["string","null"],"format":"uuid"},"created_at":{"type":"string"}},"required":["id","email","origin","source_id","created_at"],"additionalProperties":false},"Suppression":{"type":"object","properties":{"object":{"type":"string","enum":["suppression"]},"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"origin":{"type":"string","enum":["bounce","complaint","manual","unsubscribe"]},"source_id":{"type":["string","null"],"format":"uuid"},"created_at":{"type":"string"}},"required":["object","id","email","origin","source_id","created_at"],"additionalProperties":false},"WebhookSecret":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string","format":"uuid"},"signing_secret":{"type":"string","example":"whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"}},"required":["object","id","signing_secret"],"additionalProperties":false},"WebhookList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"WebhookListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpoint":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["email.sent","email.scheduled","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.failed","email.suppressed","email.canceled","domain.created","domain.updated","domain.deleted","suppression.added","suppression.removed","contact.created","contact.updated","contact.deleted","email.received","automation.run.started","automation.run.completed","automation.run.failed"]}},"status":{"type":"string","enum":["enabled","disabled"]},"created_at":{"type":"string"}},"required":["id","endpoint","events","status","created_at"],"additionalProperties":false},"WebhookEventRef":{"type":"object","properties":{"object":{"type":"string","enum":["webhook_event"]},"id":{"type":"string"}},"required":["object","id"],"additionalProperties":false},"WebhookAttemptList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookAttempt"}}},"required":["object","has_more","data"],"additionalProperties":false},"WebhookAttempt":{"type":"object","properties":{"id":{"type":"string","example":"atmpt_0198f4c1000070008000000000000000"},"attempt_number":{"type":"integer"},"http_status_code":{"type":["integer","null"]},"response":{"type":["string","null"]},"duration_ms":{"type":"integer"},"error":{"type":["string","null"]},"sent_at":{"type":"string"}},"required":["id","attempt_number","http_status_code","response","duration_ms","error","sent_at"],"additionalProperties":false},"WebhookEvent":{"type":"object","properties":{"object":{"type":"string","enum":["webhook_event"]},"id":{"type":"string","example":"msg_0198f4c1000070008000000000000000"},"type":{"type":"string","enum":["email.sent","email.scheduled","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.failed","email.suppressed","email.canceled","domain.created","domain.updated","domain.deleted","suppression.added","suppression.removed","contact.created","contact.updated","contact.deleted","email.received","automation.run.started","automation.run.completed","automation.run.failed"]},"created_at":{"type":"string"},"status":{"type":"string","enum":["pending","attempting","success","failed"]},"attempt_count":{"type":"integer"},"next_attempt_at":{"type":["string","null"]},"last_http_status":{"type":["integer","null"]},"payload":{}},"required":["object","id","type","created_at","status","attempt_count","next_attempt_at","last_http_status"],"additionalProperties":false},"WebhookEventList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"WebhookEventListItem":{"type":"object","properties":{"id":{"type":"string","example":"msg_0198f4c1000070008000000000000000"},"type":{"type":"string","enum":["email.sent","email.scheduled","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.failed","email.suppressed","email.canceled","domain.created","domain.updated","domain.deleted","suppression.added","suppression.removed","contact.created","contact.updated","contact.deleted","email.received","automation.run.started","automation.run.completed","automation.run.failed"]},"created_at":{"type":"string"},"status":{"type":"string","enum":["pending","attempting","success","failed"]}},"required":["id","type","created_at","status"],"additionalProperties":false},"ParkedDelivery":{"type":"object","properties":{"object":{"type":"string","enum":["parked_delivery"]},"delivered":{"type":"integer"},"remaining":{"type":"integer","description":"Events still parked on the endpoint once this call returned."},"stopped_reason":{"type":["string","null"],"enum":["rate_limit_exceeded",null]}},"required":["object","delivered","remaining","stopped_reason"],"additionalProperties":false},"ParkedWebhookEventList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ParkedWebhookEvent"}}},"required":["object","has_more","data"],"additionalProperties":false},"ParkedWebhookEvent":{"type":"object","properties":{"id":{"type":"string","example":"msg_0198f4c1000070008000000000000000"},"type":{"type":"string","enum":["email.sent","email.scheduled","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.failed","email.suppressed","email.canceled","domain.created","domain.updated","domain.deleted","suppression.added","suppression.removed","contact.created","contact.updated","contact.deleted","email.received","automation.run.started","automation.run.completed","automation.run.failed"]},"created_at":{"type":"string"},"status":{"type":"string","enum":["pending","attempting","success","failed"]},"attempt_count":{"type":"integer"},"last_http_status":{"type":["integer","null"]}},"required":["id","type","created_at","status","attempt_count","last_http_status"],"additionalProperties":false},"WebhookDetail":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string","format":"uuid"},"endpoint":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["email.sent","email.scheduled","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.failed","email.suppressed","email.canceled","domain.created","domain.updated","domain.deleted","suppression.added","suppression.removed","contact.created","contact.updated","contact.deleted","email.received","automation.run.started","automation.run.completed","automation.run.failed"]}},"status":{"type":"string","enum":["enabled","disabled"]},"created_at":{"type":"string"},"signing_secret":{"type":"string","example":"whsec_••••••••LaSw"}},"required":["object","id","endpoint","events","status","created_at","signing_secret"],"additionalProperties":false},"WebhookRef":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"DeleteWebhookResponse":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"LogList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/LogSummary"}}},"required":["object","has_more","data"],"additionalProperties":false},"LogSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"},"endpoint":{"type":"string"},"method":{"type":"string"},"response_status":{"type":"integer"},"user_agent":{"type":["string","null"]},"source":{"type":"string"},"request_id":{"type":"string"},"latency_ms":{"type":"integer"},"api_key_id":{"type":["string","null"],"format":"uuid"}},"required":["id","created_at","endpoint","method","response_status","user_agent","source","request_id","latency_ms","api_key_id"],"additionalProperties":false},"Log":{"type":"object","properties":{"object":{"type":"string","enum":["log"]},"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"},"endpoint":{"type":"string"},"method":{"type":"string"},"response_status":{"type":"integer"},"user_agent":{"type":["string","null"]},"source":{"type":"string"},"request_id":{"type":"string"},"latency_ms":{"type":"integer"},"api_key_id":{"type":["string","null"],"format":"uuid"},"request_body":{},"response_body":{},"email_id":{"type":["string","null"],"format":"uuid"}},"required":["object","id","created_at","endpoint","method","response_status","user_agent","source","request_id","latency_ms","api_key_id","email_id"],"additionalProperties":false},"CreateTemplateResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"object":{"type":"string","enum":["template"]}},"required":["id","object"],"additionalProperties":false},"CreateTemplateRequest":{"type":"object","properties":{"name":{"type":"string","example":"Welcome","description":"The name of the template."},"alias":{"type":"string","example":"welcome","description":"A short name to address the template by instead of its ID: `^[a-z0-9][a-z0-9-_]{0,62}$`, lower-cased, never a UUID."},"from":{"type":"string","example":"Acme <hello@acme.com>","description":"Sender email address. To include a friendly name, use the format \"Your Name <sender@domain.com>\"."},"subject":{"type":"string","example":"Welcome, {{name}}","description":"Email subject. May carry `{{key}}` placeholders."},"reply_to":{"type":"array","items":{"type":"string"},"description":"Reply-to email addresses."},"html":{"type":"string","example":"<p>Hello {{name}}</p>","description":"The HTML version of the template. May carry `{{key}}` placeholders."},"text":{"type":"string","example":"Hello {{name}}","description":"The plain text version of the template. May carry `{{key}}` placeholders."},"variables":{"type":"array","items":{"$ref":"#/components/schemas/TemplateVariableInput"},"description":"The variables the bodies use. Every `{{key}}` must be declared here, and every declared key must be used."}},"required":["name","html"]},"TemplateVariableInput":{"type":"object","properties":{"key":{"type":"string","example":"name","description":"The key of the variable, matching `^[A-Za-z0-9_]+$`; unique within the template."},"type":{"type":"string","enum":["string","number","boolean","object","list"],"description":"The type of the variable."},"fallback_value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"The fallback value of the variable. Must match `type`."}},"required":["key","type"]},"ListTemplatesResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TemplateListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"TemplateListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"name":{"type":"string"},"status":{"type":"string","enum":["draft","published"]},"published_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"alias":{"type":"string","example":"welcome"}},"required":["id","name","status","published_at","created_at","updated_at"],"additionalProperties":false},"Template":{"type":"object","properties":{"object":{"type":"string","enum":["template"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"current_version_id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d18"},"name":{"type":"string"},"alias":{"type":"string","example":"welcome"},"from":{"type":"string","example":"Acme <hello@acme.com>"},"subject":{"type":"string","example":"Welcome, {{name}}"},"reply_to":{"type":["array","null"],"items":{"type":"string"}},"html":{"type":"string"},"text":{"type":"string"},"variables":{"type":"array","items":{"$ref":"#/components/schemas/TemplateVariable"}},"created_at":{"type":"string"},"updated_at":{"type":"string"},"status":{"type":"string","enum":["draft","published"]},"published_at":{"type":["string","null"]},"has_unpublished_versions":{"type":"boolean"}},"required":["object","id","current_version_id","name","reply_to","html","variables","created_at","updated_at","status","published_at","has_unpublished_versions"],"additionalProperties":false},"TemplateVariable":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d19"},"key":{"type":"string","example":"name"},"type":{"type":"string","enum":["string","number","boolean","object","list"]},"fallback_value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"The fallback value of the variable. Must match `type`."},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","key","type","created_at","updated_at"],"additionalProperties":false},"UpdateTemplateResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"object":{"type":"string","enum":["template"]}},"required":["id","object"],"additionalProperties":false},"UpdateTemplateOptions":{"type":"object","properties":{"name":{"type":"string","description":"The name of the template."},"alias":{"type":["string","null"],"example":"welcome","description":"The alias of the template. `null` removes it."},"from":{"type":["string","null"],"example":"Acme <hello@acme.com>","description":"Sender email address. `null` clears it."},"subject":{"type":["string","null"],"example":"Welcome, {{name}}","description":"Email subject. `null` clears it."},"reply_to":{"type":"array","items":{"type":"string"},"description":"Reply-to email addresses."},"html":{"type":"string","example":"<p>Hello {{name}}</p>","description":"The HTML version of the template. May carry `{{key}}` placeholders."},"text":{"type":"string","example":"Hello {{name}}","description":"The plain text version of the template. May carry `{{key}}` placeholders."},"variables":{"type":"array","items":{"$ref":"#/components/schemas/TemplateVariableInput"},"description":"The variables the bodies use. Every `{{key}}` must be declared here, and every declared key must be used."}}},"RemoveTemplateResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["template"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"PublishTemplateResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"object":{"type":"string","enum":["template"]}},"required":["id","object"],"additionalProperties":false},"DuplicateTemplateResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"object":{"type":"string","enum":["template"]}},"required":["id","object"],"additionalProperties":false},"TemplatePreview":{"type":"object","properties":{"object":{"type":"string","enum":["template_preview"]},"template_id":{"type":"string","format":"uuid"},"version_number":{"type":"integer"},"subject":{"type":["string","null"]},"html":{"type":"string","description":"The rendered HTML after the dashboard preview's sanitizer, with remote images withheld. Safe to place in a sandboxed iframe's `srcdoc`, and nowhere else: `style` and `class` survive."},"text":{"type":["string","null"]},"missing_variables":{"type":"array","items":{"type":"string"},"description":"Declared variables with neither a value nor a fallback. Their placeholders are left in the output; a send would refuse them."}},"required":["object","template_id","version_number","subject","html","text","missing_variables"],"additionalProperties":false},"TemplatePreviewRequest":{"type":"object","properties":{"variables":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"}]},"description":"Values by key, as a send takes them. Undeclared keys are refused."},"version":{"type":"integer","exclusiveMinimum":0,"description":"A `version_number` of this template. The current version when absent."}}},"GetEmailsMetricsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["metrics"]},"start_date":{"type":"string"},"end_date":{"type":"string"},"metrics":{"type":"array","items":{"type":"string"}},"dimensions":{"type":"array","items":{"type":"string"}},"granularity":{"type":"string","enum":["hourly","daily","weekly","monthly"]},"totals":{"type":"object","additionalProperties":{"type":"number"}},"data_as_of":{"type":"string"},"data":{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"number"},{"type":"string"}]}}}},"required":["object","start_date","end_date","metrics","dimensions","granularity","totals","data_as_of"],"additionalProperties":false},"ListReceivedEmailsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ReceivedEmailListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ReceivedEmailListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"to":{"type":"array","items":{"type":"string"}},"from":{"type":"string"},"subject":{"type":["string","null"]},"message_id":{"type":"string"},"bcc":{"type":["array","null"],"items":{"type":"string"}},"cc":{"type":["array","null"],"items":{"type":"string"}},"reply_to":{"type":["array","null"],"items":{"type":"string"}},"dropped_reason":{"type":["string","null"],"enum":["storage_quota","daily_cap","virus","parse_failed",null],"description":"Why the message was recorded without its content. `null` for a message we stored. A dropped message has `html: null`, `text: null` and no attachments."},"created_at":{"type":"string","example":"2026-09-09T10:16:44.902Z"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/ReceivedEmailAttachment"}}},"required":["id","to","from","subject","message_id","bcc","cc","reply_to","dropped_reason","created_at","attachments"],"additionalProperties":false},"ReceivedEmailAttachment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"660e8400-e29b-41d4-a716-446655440000"},"filename":{"type":["string","null"]},"content_type":{"type":"string","example":"application/pdf"},"content_id":{"type":"string"},"content_disposition":{"type":"string","enum":["inline","attachment"]},"size":{"type":"integer","example":2048}},"required":["id","filename","content_type","content_disposition","size"],"additionalProperties":false},"GetReceivedEmailResponse":{"type":"object","properties":{"object":{"type":"string","enum":["email"]},"id":{"type":"string","format":"uuid","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"to":{"type":"array","items":{"type":"string"}},"from":{"type":"string","example":"Ronald Williams <ronald.williams@example.com>"},"subject":{"type":"string"},"message_id":{"type":"string","example":"<CAF1042.damaged@mail.example.com>"},"bcc":{"type":["array","null"],"items":{"type":"string"}},"cc":{"type":["array","null"],"items":{"type":"string"}},"reply_to":{"type":["array","null"],"items":{"type":"string"}},"received_for":{"type":"array","items":{"type":"string"},"description":"The addresses of yours this message was accepted for. Route on this rather than on `to`, which is whatever the sender wrote."},"html":{"type":["string","null"]},"text":{"type":["string","null"]},"headers":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"dropped_reason":{"type":["string","null"],"enum":["storage_quota","daily_cap","virus","parse_failed",null],"description":"Why the message was recorded without its content. `null` for a message we stored. A dropped message has `html: null`, `text: null` and no attachments."},"created_at":{"type":"string","example":"2026-09-09T10:16:44.902Z"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/ReceivedEmailAttachment"}}},"required":["object","id","to","from","subject","message_id","bcc","cc","reply_to","received_for","html","text","headers","dropped_reason","created_at","attachments"],"additionalProperties":false},"ListAttachmentsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ReceivedAttachmentListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ReceivedAttachmentListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"660e8400-e29b-41d4-a716-446655440000"},"filename":{"type":["string","null"]},"content_type":{"type":"string","example":"application/pdf"},"content_id":{"type":"string"},"content_disposition":{"type":"string","enum":["inline","attachment"]},"size":{"type":"integer","example":2048},"download_url":{"type":"string","description":"A signed URL for the bytes, valid for 15 minutes. Absent — together with `expires_at` — when the part was not stored."},"expires_at":{"type":"string","example":"2026-09-09T10:31:44.902Z"}},"required":["id","filename","content_type","content_disposition","size"],"additionalProperties":false},"ReceivedAttachment":{"type":"object","properties":{"object":{"type":"string","enum":["attachment"]},"id":{"type":"string","format":"uuid","example":"660e8400-e29b-41d4-a716-446655440000"},"filename":{"type":["string","null"]},"content_type":{"type":"string","example":"application/pdf"},"content_id":{"type":"string"},"content_disposition":{"type":"string","enum":["inline","attachment"]},"size":{"type":"integer","example":2048},"download_url":{"type":"string","description":"A signed URL for the bytes, valid for 15 minutes. Absent — together with `expires_at` — when the part was not stored."},"expires_at":{"type":"string","example":"2026-09-09T10:31:44.902Z"}},"required":["object","id","filename","content_type","content_disposition","size"],"additionalProperties":false},"DeleteReceivedEmailResponse":{"type":"object","properties":{"object":{"type":"string","enum":["email"]},"id":{"type":"string","format":"uuid","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"ShareEmailResponse":{"type":"object","properties":{"object":{"type":"string","enum":["email"]},"id":{"type":"string","format":"uuid","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"url":{"type":"string","example":"https://share.example.com/9xKq2..."},"expires_at":{"type":"string","example":"2026-09-11T12:00:00.000Z"}},"required":["object","id","url","expires_at"],"additionalProperties":false},"ShareEmailOptions":{"type":"object","properties":{"expires_in":{"type":"string","example":"24h","description":"A duration such as `10m`, `2 hours` or `1 day`."}}},"DeleteEmailShareResponse":{"type":"object","properties":{"object":{"type":"string","enum":["email_share"]},"id":{"type":"string","format":"uuid"},"revoked_at":{"type":"string","example":"2026-09-10T09:00:00.000Z"}},"required":["object","id","revoked_at"],"additionalProperties":false},"EmailShareList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/EmailShare"}}},"required":["object","has_more","data"],"additionalProperties":false},"EmailShare":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0198f4c1-0000-7000-8000-000000000000"},"email_id":{"type":"string","format":"uuid","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"status":{"type":"string","enum":["active","expired","revoked"],"description":"`active` while the link still opens the page, `expired` once `expires_at` has passed, `revoked` once it was withdrawn. A withdrawn link that has also expired reads `revoked`."},"created_at":{"type":"string","example":"2026-09-09T12:00:00.000Z"},"expires_at":{"type":"string","example":"2026-09-11T12:00:00.000Z"},"revoked_at":{"type":["string","null"]},"created_by_user_id":{"type":["string","null"],"format":"uuid"},"created_by_api_key_id":{"type":["string","null"],"format":"uuid"}},"required":["id","email_id","status","created_at","expires_at","revoked_at","created_by_user_id","created_by_api_key_id"],"additionalProperties":false},"RetrievedAttachment":{"type":"object","properties":{"object":{"type":"string","enum":["attachment"]},"id":{"type":"string","format":"uuid"},"filename":{"type":["string","null"]},"content_type":{"type":"string"},"content_id":{"type":"string"},"content_disposition":{"type":"string","enum":["inline","attachment"]},"download_url":{"type":"string"},"expires_at":{"type":"string"},"size":{"type":"integer"}},"required":["object","id","filename","content_type","content_disposition","download_url","expires_at","size"],"additionalProperties":false},"AttachmentList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"AttachmentListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"filename":{"type":["string","null"]},"content_type":{"type":"string"},"content_id":{"type":"string"},"content_disposition":{"type":"string","enum":["inline","attachment"]},"download_url":{"type":"string"},"expires_at":{"type":"string"},"size":{"type":"integer"}},"required":["id","filename","content_type","content_disposition","download_url","expires_at","size"],"additionalProperties":false},"CreateBatchEmailsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"SendBatchEmailsRequest":{"type":"array","items":{"$ref":"#/components/schemas/SendEmailRequest"},"minItems":1,"maxItems":100},"SendEmailRequest":{"type":"object","properties":{"from":{"type":"string","example":"Acme <onboarding@resend.dev>"},"to":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"maxItems":50,"example":["delivered@resend.dev"]},"subject":{"type":"string","example":"Hello World"},"bcc":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"cc":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"reply_to":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"html":{"type":"string"},"text":{"type":"string"},"template":{"$ref":"#/components/schemas/EmailTemplateInput"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"scheduled_at":{"type":"string","example":"2026-09-10T12:00:00.000Z"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}},"tags":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}},"topic_id":{"type":"string"}},"required":["from","to","subject"]},"EmailTemplateInput":{"type":"object","properties":{"id":{"type":"string"},"variables":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"}]}}},"required":["id"]},"Attachment":{"type":"object","properties":{"content":{"type":"string"},"filename":{"type":"string"},"path":{"type":"string"},"content_type":{"type":"string"},"content_id":{"type":"string"}}},"Tag":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"SendEmailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"}},"required":["id"],"additionalProperties":false},"EmailList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Email"}}},"required":["object","has_more","data"],"additionalProperties":false},"Email":{"type":"object","properties":{"object":{"type":"string","enum":["email"]},"id":{"type":"string","format":"uuid","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"message_id":{"type":["string","null"]},"to":{"type":"array","items":{"type":"string"}},"from":{"type":"string"},"created_at":{"type":"string","example":"2026-09-09T12:00:00.000Z"},"subject":{"type":"string"},"html":{"type":["string","null"]},"text":{"type":["string","null"]},"bcc":{"type":"array","items":{"type":"string"}},"cc":{"type":"array","items":{"type":"string"}},"reply_to":{"type":"array","items":{"type":"string"}},"last_event":{"type":"string","enum":["queued","scheduled","sent","delivered","delivery_delayed","bounced","complained","opened","clicked","failed","suppressed","canceled"]}},"required":["object","id","message_id","to","from","created_at","subject","html","text","bcc","cc","reply_to","last_event"],"additionalProperties":false},"EmailRef":{"type":"object","properties":{"object":{"type":"string","enum":["email"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"UpdateEmailOptions":{"type":"object","properties":{"scheduled_at":{"type":"string","example":"2026-09-10T12:00:00.000Z"}},"required":["scheduled_at"]},"CreateContactPropertyResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact_property"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"CreateContactPropertyOptions":{"type":"object","properties":{"key":{"type":"string","example":"company_name","description":"The property key. Max length is 50 characters. Only alphanumeric characters and underscores are allowed."},"type":{"type":"string","enum":["string","number"]},"fallback_value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"null"}],"description":"The default value to use when the property is not set for a contact. Must match `type`."}},"required":["key","type"]},"ListContactPropertiesResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListContactPropertiesItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ListContactPropertiesItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"key":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean"]},"fallback_value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]},"created_at":{"type":"string"}},"required":["id","key","type","created_at"],"additionalProperties":false},"GetContactPropertyResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact_property"]},"id":{"type":"string","format":"uuid"},"key":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean"]},"fallback_value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]},"created_at":{"type":"string"}},"required":["object","id","key","type","created_at"],"additionalProperties":false},"UpdateContactPropertyResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact_property"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"UpdateContactPropertyOptions":{"type":"object","properties":{"fallback_value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"null"}]}}},"RemoveContactPropertyResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact_property"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"CreateContactImportResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact_import"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"ListContactImportsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ContactImport"}}},"required":["object","has_more","data"],"additionalProperties":false},"ContactImport":{"type":"object","properties":{"object":{"type":"string","enum":["contact_import"]},"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","in_progress","completed","failed"]},"created_at":{"type":"string"},"completed_at":{"type":["string","null"]},"counts":{"$ref":"#/components/schemas/ContactImportCounts"}},"required":["object","id","status","created_at","completed_at","counts"],"additionalProperties":false},"ContactImportCounts":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of rows processed by the import."},"created":{"type":"integer","description":"Number of contacts created by the import."},"updated":{"type":"integer","description":"Number of contacts updated by the import."},"skipped":{"type":"integer","description":"Number of rows skipped by the import."},"failed":{"type":"integer","description":"Number of rows that failed during the import."}},"required":["total","created","updated","skipped","failed"],"additionalProperties":false},"CreateContactResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"CreateContactOptions":{"type":"object","properties":{"email":{"type":"string","minLength":3,"maxLength":320,"example":"steve.wozniak@gmail.com"},"first_name":{"type":"string","example":"Steve"},"last_name":{"type":"string","example":"Wozniak"},"unsubscribed":{"type":"boolean"},"properties":{"type":"object","additionalProperties":{},"description":"A map of custom property keys and values. Every key must be a declared contact property; `null` removes a key."},"segments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]}},"topics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"subscription":{"type":"string","enum":["opt_in","opt_out"]}},"required":["id","subscription"]}}},"required":["email"]},"ListContactsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListContactsItem"}}},"required":["object","data"],"additionalProperties":false},"ListContactsItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"created_at":{"type":"string"},"unsubscribed":{"type":"boolean"}},"required":["id","email","first_name","last_name","created_at","unsubscribed"],"additionalProperties":false},"GetContactResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact"]},"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"created_at":{"type":"string"},"unsubscribed":{"type":"boolean"},"properties":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]},"description":"A map of custom property keys and values."}},"required":["object","id","email","first_name","last_name","created_at","unsubscribed","properties"],"additionalProperties":false},"UpdateContactResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"],"additionalProperties":false},"UpdateContactOptions":{"type":"object","properties":{"email":{"type":"string","minLength":3,"maxLength":320,"example":"steve.wozniak@gmail.com"},"first_name":{"type":"string"},"last_name":{"type":"string"},"unsubscribed":{"type":"boolean"},"properties":{"type":"object","additionalProperties":{},"description":"A map of custom property keys and values. Every key must be a declared contact property; `null` removes a key."}}},"RemoveContactResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"CreateSegmentResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["segment"]}},"required":["id","object"],"additionalProperties":false},"CreateSegmentOptions":{"type":"object","properties":{"name":{"type":"string","example":"Active Users","description":"The name of the segment."},"filter":{"type":["object","null"],"additionalProperties":{},"description":"Filter conditions for the segment: `{ all | any | not: [ … ] }` over `{ field, op, value }` and `{ topic, subscription }`. Fields: `email`, `first_name`, `last_name`, `unsubscribed`, `created_at`, `properties.<key>`. Ops: `eq`, `neq`, `contains`, `exists`, `gt`, `gte`, `lt`, `lte`, `in`. Nesting to depth 3, at most 20 conditions. `null` means explicit membership only.","example":{"all":[{"field":"properties.plan","op":"eq","value":"pro"},{"field":"unsubscribed","op":"eq","value":false},{"any":[{"field":"first_name","op":"exists"},{"field":"properties.score","op":"gt","value":10}]}]}}},"required":["name"]},"ListSegmentsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListSegmentsItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ListSegmentsItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"type":"string"}},"required":["id","name","created_at"],"additionalProperties":false},"SegmentPreview":{"type":"object","properties":{"object":{"type":"string","enum":["segment_preview"]},"contacts":{"type":"integer","description":"How many contacts the filter matches right now."}},"required":["object","contacts"],"additionalProperties":false},"SegmentPreviewRequest":{"type":"object","properties":{"filter":{"type":"object","additionalProperties":{},"description":"A segment filter, exactly as `POST /segments` takes it."}},"required":["filter"]},"SegmentContactList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListContactsItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"SegmentMetrics":{"type":"object","properties":{"object":{"type":"string","enum":["segment_metrics"]},"segment_id":{"type":"string","format":"uuid"},"contacts":{"type":"integer"},"subscribed":{"type":"integer"},"unsubscribed":{"type":"integer"}},"required":["object","segment_id","contacts","subscribed","unsubscribed"],"additionalProperties":false},"GetSegmentResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["segment"]},"name":{"type":"string"},"filter":{"type":["object","null"],"additionalProperties":{},"description":"Filter conditions for the segment: `{ all | any | not: [ … ] }` over `{ field, op, value }` and `{ topic, subscription }`. Fields: `email`, `first_name`, `last_name`, `unsubscribed`, `created_at`, `properties.<key>`. Ops: `eq`, `neq`, `contains`, `exists`, `gt`, `gte`, `lt`, `lte`, `in`. Nesting to depth 3, at most 20 conditions. `null` means explicit membership only.","example":{"all":[{"field":"properties.plan","op":"eq","value":"pro"},{"field":"unsubscribed","op":"eq","value":false},{"any":[{"field":"first_name","op":"exists"},{"field":"properties.score","op":"gt","value":10}]}]}},"created_at":{"type":"string"}},"required":["id","object","name","filter","created_at"],"additionalProperties":false},"UpdateSegmentResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["segment"]}},"required":["id","object"],"additionalProperties":false},"UpdateSegmentOptions":{"type":"object","properties":{"name":{"type":"string","example":"Active Users","description":"The name of the segment."}},"required":["name"]},"RemoveSegmentResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["segment"]},"deleted":{"type":"boolean","enum":[true]}},"required":["id","object","deleted"],"additionalProperties":false},"ListContactSegmentsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListContactSegmentsItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ListContactSegmentsItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"type":"string","description":"When the contact was added to the segment; for a contact matched by the segment's filter, the later of the segment's and the contact's creation."}},"required":["id","name","created_at"],"additionalProperties":false},"AddContactToSegmentResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact_segment"]},"contact_id":{"type":"string","format":"uuid"},"segment_id":{"type":"string","format":"uuid"}},"required":["object","contact_id","segment_id"],"additionalProperties":false},"RemoveContactFromSegmentResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact_segment"]},"contact_id":{"type":"string","format":"uuid"},"segment_id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","contact_id","segment_id","deleted"],"additionalProperties":false},"BillingPaygResponse":{"type":"object","properties":{"object":{"type":"string","enum":["billing_payg"]},"enabled":{"type":"boolean"},"overage_ceiling_emails":{"type":["integer","null"]}},"required":["object","enabled","overage_ceiling_emails"],"additionalProperties":false},"BillingPaygRequest":{"type":"object","properties":{"enabled":{"type":"boolean","description":"The \"Continue using the service beyond your quota.\" toggle."}},"required":["enabled"]},"TeamAddon":{"type":"object","properties":{"object":{"type":"string","enum":["team_addon"]},"addon_code":{"type":"string"},"name":{"type":"string"},"monthly_price_cents":{"type":"integer"},"quantity":{"type":"integer"},"status":{"type":"string"},"requested_at":{"type":"string"},"provisioned_at":{"type":["string","null"]}},"required":["object","addon_code","name","monthly_price_cents","quantity","status","requested_at","provisioned_at"],"additionalProperties":false},"PurchaseAddonRequest":{"type":"object","properties":{"addon_code":{"type":"string","enum":["extra_domains_100","dedicated_ip","sso"],"description":"`extra_domains_100`, `dedicated_ip`, or `sso`."},"quantity":{"type":"integer","minimum":1,"maximum":100,"description":"Units held after the call (a set, not an increment). Default 1."},"region":{"type":"string","enum":["us-east-1","eu-west-1","sa-east-1","ap-northeast-1"],"description":"`dedicated_ip` only: the region the pool should live in. The operator confirms it while provisioning."},"expected_daily_volume":{"type":"integer","minimum":1,"maximum":100000000,"description":"`dedicated_ip` only: roughly how many emails a day the team expects to send through the pool."}},"required":["addon_code"]},"GetContactTopicsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/GetContactTopicsItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"GetContactTopicsItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"subscription":{"type":"string","enum":["opt_in","opt_out"]}},"required":["id","name","description","subscription"],"additionalProperties":false},"UpdateContactTopicsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["contact_topics"]},"contact_id":{"type":"string","format":"uuid"},"topics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"subscription":{"type":"string","enum":["opt_in","opt_out"]}},"required":["id","subscription"],"additionalProperties":false}}},"required":["object","contact_id","topics"],"additionalProperties":false},"UpdateContactTopicsOptions":{"type":"object","properties":{"topics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"subscription":{"type":"string","enum":["opt_in","opt_out"]}},"required":["id","subscription"]}}},"required":["topics"]},"CreateTopicResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["topic"]}},"required":["id","object"],"additionalProperties":false},"CreateTopicOptions":{"type":"object","properties":{"name":{"type":"string","example":"Newsletter","description":"The name of the topic. Max 50 characters."},"default_subscription":{"type":"string","enum":["opt_in","opt_out"],"description":"The default subscription status for the topic. Cannot be changed after creation."},"description":{"type":"string","description":"A description of the topic. Max 200 characters."},"visibility":{"type":"string","enum":["public","private"],"description":"The visibility of the topic; `private` when omitted. Public topics are visible to all contacts on the unsubscribe page. Private topics are only visible to opted-in contacts."}},"required":["name","default_subscription"]},"ListTopicsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListTopicsItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ListTopicsItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"default_subscription":{"type":"string","enum":["opt_in","opt_out"]},"visibility":{"type":"string","enum":["public","private"]},"created_at":{"type":"string"}},"required":["id","name","description","default_subscription","visibility","created_at"],"additionalProperties":false},"GetTopicResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["topic"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"default_subscription":{"type":"string","enum":["opt_in","opt_out"]},"visibility":{"type":"string","enum":["public","private"]},"created_at":{"type":"string"}},"required":["object","id","name","description","default_subscription","visibility","created_at"],"additionalProperties":false},"UpdateTopicResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["topic"]}},"required":["id","object"],"additionalProperties":false},"UpdateTopicOptions":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":["string","null"]},"visibility":{"type":"string","enum":["public","private"]}}},"RemoveTopicResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["topic"]},"deleted":{"type":"boolean","enum":[true]}},"required":["id","object","deleted"],"additionalProperties":false},"CreateBroadcastResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["broadcast"]}},"required":["id","object"],"additionalProperties":false},"CreateBroadcastOptions":{"type":"object","properties":{"name":{"type":"string","description":"Name of the broadcast.","example":"November announcements"},"segment_id":{"type":"string","description":"Unique identifier of the segment this broadcast will be sent to.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"audience_id":{"type":"string","deprecated":true,"description":"Use `segment_id` instead. Unique identifier of the segment this broadcast will be sent to."},"from":{"type":"string","description":"The email address of the sender.","example":"Acme <onboarding@resend.dev>"},"subject":{"type":"string","description":"The subject line of the email.","example":"Hello World"},"reply_to":{"type":"array","items":{"type":"string"},"description":"The email addresses to which replies should be sent."},"preview_text":{"type":"string","description":"The preview text of the email.","example":"Here are our announcements"},"html":{"type":"string","description":"The HTML version of the message.","example":"<p>Hello {{{FIRST_NAME|there}}}!</p>"},"text":{"type":"string","description":"The plain text version of the message.","example":"Hello {{{FIRST_NAME|there}}}!"},"topic_id":{"type":"string","description":"The topic ID that the broadcast will be scoped to.","example":"b6d24b8e-af0b-4c3c-be0c-359bbd97381e"},"template":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"],"description":"Create the broadcast from a published template: its `html` and `text` (and `reply_to`, when this request sends none) are copied into the broadcast once. Mutually exclusive with `html` and `text`. Later template edits do not change the broadcast."},"send":{"type":"boolean","description":"Whether to send the broadcast immediately or keep it as a draft.\n"},"scheduled_at":{"type":"string","description":"Schedule time to send the broadcast. Can only be used if `send` is true.\n","example":"2026-09-11T12:00:00.000Z"}},"required":["from","subject"]},"ListBroadcastsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListBroadcastsItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ListBroadcastsItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"name":{"type":"string","example":"November announcements"},"audience_id":{"type":"string","format":"uuid","deprecated":true,"description":"Deprecated. Use segment_id instead."},"segment_id":{"type":"string","format":"uuid","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"status":{"type":"string","enum":["draft","scheduled","queued","sending","sent","canceled","failed"],"example":"draft"},"created_at":{"type":"string","example":"2026-09-11T12:00:00.000Z"},"scheduled_at":{"type":"string","example":"2026-09-11T12:00:00.000Z"},"sent_at":{"type":"string","example":"2026-09-11T12:00:00.000Z"},"topic_id":{"type":"string","format":"uuid","example":"b6d24b8e-af0b-4c3c-be0c-359bbd97381e"}},"required":["id","audience_id","segment_id","status","created_at"],"additionalProperties":false},"SendBroadcastResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":false},"SendBroadcastOptions":{"type":"object","properties":{"scheduled_at":{"type":"string","description":"Schedule email to be sent later. The date should be in ISO 8601 format.","example":"2026-09-11T12:00:00.000Z"}}},"CancelBroadcastResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["broadcast"]}},"required":["id","object"],"additionalProperties":false},"ListBroadcastRecipientsResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListBroadcastRecipientsItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ListBroadcastRecipientsItem":{"type":"object","properties":{"id":{"type":"string","description":"Opaque cursor identifying this row, used for pagination.","example":"MjAyNi0wOS0xMVQxMjowMDowMC4wMDBafGUxNjlhYTQ1LTFlY2YtNDE4My05OTU1LWIxNDk5ZDU3MDFkMw"},"contact_id":{"type":["string","null"],"format":"uuid","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"email":{"type":"string","example":"steve.wozniak@gmail.com"},"count":{"type":"integer","description":"The number of times this recipient triggered the event. Only present when `type` is `opened` or `clicked`.","example":3},"bounce_type":{"type":"string","enum":["permanent","transient","undetermined"],"description":"The type of bounce. Only present when `type` is `bounced`."},"clicked_links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","example":"https://resend.com/pricing"},"clicks":{"type":"integer","example":2}},"required":["url","clicks"],"additionalProperties":false},"description":"The links this recipient clicked. Only present when `type` is `clicked`."}},"required":["id","contact_id","email"],"additionalProperties":false},"ListBroadcastClickedLinksResponseSuccess":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ListBroadcastClickedLinksItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"ListBroadcastClickedLinksItem":{"type":"object","properties":{"id":{"type":"string","description":"An opaque cursor for this row, used only for pagination. It does not identify any entity."},"url":{"type":"string","example":"https://resend.com/pricing"},"clicks":{"type":"integer","example":42},"unique_clicks":{"type":"integer","example":30}},"required":["id","url","clicks","unique_clicks"],"additionalProperties":false},"BroadcastCompliance":{"type":"object","properties":{"object":{"type":"string","enum":["broadcast_compliance"]},"broadcast_id":{"type":"string","format":"uuid","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"sendable":{"type":"boolean","description":"Every condition passed: a send would be accepted now."},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/BroadcastComplianceCondition"}}},"required":["object","broadcast_id","sendable","conditions"],"additionalProperties":false},"BroadcastComplianceCondition":{"type":"object","properties":{"condition":{"type":"string","enum":["sending_domain","postal_address","segment","marketing_enabled","team_can_send","body"]},"passed":{"type":"boolean"},"name":{"type":"string","enum":["invalid_idempotency_key","validation_error","missing_api_key","restricted_api_key","email_above_quota","invalid_permission","suspended_api_key","not_found","method_not_allowed","concurrent_idempotent_requests","invalid_idempotent_request","resource_locked","invalid_attachment","invalid_parameter","missing_required_field","missing_required_parameter","daily_quota_exceeded","monthly_quota_exceeded","rate_limit_exceeded","application_error","not_implemented","service_unavailable"],"description":"The error a send would answer with, when it failed."},"message":{"type":"string","description":"The sentence a send would answer with, when it failed."}},"required":["condition","passed"],"additionalProperties":false},"GetBroadcastResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"name":{"type":"string","example":"November announcements"},"audience_id":{"type":["string","null"],"format":"uuid","deprecated":true,"description":"Deprecated: use `segment_id` instead."},"segment_id":{"type":["string","null"],"format":"uuid","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"from":{"type":"string","example":"Acme <onboarding@resend.dev>"},"subject":{"type":"string","example":"Hello World"},"reply_to":{"type":"array","items":{"type":"string"}},"preview_text":{"type":"string","example":"Here are our announcements"},"status":{"type":"string","enum":["draft","scheduled","queued","sending","sent","canceled","failed"],"example":"draft"},"created_at":{"type":"string","example":"2026-09-11T12:00:00.000Z"},"scheduled_at":{"type":"string","example":"2026-09-11T12:00:00.000Z"},"sent_at":{"type":"string","example":"2026-09-11T12:00:00.000Z"},"text":{"type":["string","null"],"example":"Hello {{{FIRST_NAME|there}}}!"},"html":{"type":["string","null"],"example":"<p>Hello {{{FIRST_NAME|there}}}!</p>"},"topic_id":{"type":["string","null"],"format":"uuid","example":"b6d24b8e-af0b-4c3c-be0c-359bbd97381e"}},"required":["id","audience_id","segment_id","from","subject","reply_to","status","created_at","text","html","topic_id"],"additionalProperties":false},"UpdateBroadcastResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["broadcast"]}},"required":["id","object"],"additionalProperties":false},"UpdateBroadcastOptions":{"type":"object","properties":{"name":{"type":"string","description":"Name of the broadcast.","example":"November announcements"},"segment_id":{"type":"string","description":"Unique identifier of the segment this broadcast will be sent to.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"audience_id":{"type":"string","deprecated":true,"description":"Use `segment_id` instead. Unique identifier of the segment this broadcast will be sent to."},"from":{"type":"string","description":"The email address of the sender.","example":"Acme <onboarding@resend.dev>"},"subject":{"type":"string","description":"The subject line of the email.","example":"Hello World"},"reply_to":{"type":"array","items":{"type":"string"},"description":"The email addresses to which replies should be sent."},"preview_text":{"type":"string","description":"The preview text of the email.","example":"Here are our announcements"},"html":{"type":"string","description":"The HTML version of the message.","example":"<p>Hello {{{FIRST_NAME|there}}}!</p>"},"text":{"type":"string","description":"The plain text version of the message.","example":"Hello {{{FIRST_NAME|there}}}!"},"topic_id":{"type":"string","description":"The topic ID that the broadcast will be scoped to.","example":"b6d24b8e-af0b-4c3c-be0c-359bbd97381e"}}},"RemoveBroadcastResponseSuccess":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["broadcast"]},"deleted":{"type":"boolean","enum":[true]}},"required":["id","object","deleted"],"additionalProperties":false},"OAuthTokenResponse":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"integer"},"refresh_token":{"type":"string"},"scope":{"type":"string"}},"required":["access_token","token_type","expires_in","refresh_token","scope"],"additionalProperties":false},"OAuthError":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","invalid_client","invalid_grant","unauthorized_client","unsupported_grant_type","invalid_scope"]},"error_description":{"type":"string"}},"required":["error"],"additionalProperties":false},"CreateAutomationResponse":{"type":"object","properties":{"object":{"type":"string","enum":["automation"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"}},"required":["object","id"],"additionalProperties":false},"CreateAutomationRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"example":"Trial nudge","description":"The name of the automation."},"status":{"type":"string","enum":["enabled","disabled"],"description":"The initial status of the automation. Defaults to `disabled`."},"steps":{"type":"array","items":{"$ref":"#/components/schemas/AutomationStep"},"minItems":1,"maxItems":150,"description":"The steps that compose the automation workflow, at most 150. Exactly one must be a `trigger`."},"connections":{"type":"array","items":{"$ref":"#/components/schemas/AutomationConnection"},"description":"The connections between steps in the automation graph."}},"required":["name","steps","connections"]},"AutomationStep":{"type":"object","properties":{"key":{"type":"string","example":"start","description":"A unique key for this step within the automation graph."},"type":{"type":"string","enum":["trigger","send_email","delay","wait_for_event","contact_delete","condition","contact_update","add_to_segment","topic_update"],"description":"The type of automation step."},"config":{"type":"object","additionalProperties":{},"description":"Configuration for the step. The shape depends on `type`: `trigger` takes `{ event_name }`, `send_email` a `{ template: { id, variables? }, subject?, from?, reply_to? }`, `delay` a `{ duration }` or `{ until }`, `condition` a rule tree, `contact_update` literal field values, `add_to_segment` a `{ segment_id }` and `topic_update` a `{ topic_id, subscription }`."}},"required":["key","type","config"]},"AutomationConnection":{"type":"object","properties":{"from":{"type":"string","example":"start","description":"The `key` of the source step."},"to":{"type":"string","example":"welcome","description":"The `key` of the target step."},"type":{"type":"string","enum":["default","condition_met","condition_not_met","timeout","event_received"],"default":"default","description":"The type of connection. Defaults to `default`."}},"required":["from","to"],"additionalProperties":false},"ListAutomationsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AutomationListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"AutomationListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"name":{"type":"string","example":"Trial nudge"},"status":{"type":"string","enum":["enabled","disabled"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","status","created_at","updated_at"],"additionalProperties":false},"Automation":{"type":"object","properties":{"object":{"type":"string","enum":["automation"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"name":{"type":"string","example":"Trial nudge"},"status":{"type":"string","enum":["enabled","disabled"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/AutomationStepResponse"}},"connections":{"type":"array","items":{"$ref":"#/components/schemas/AutomationConnection"}}},"required":["object","id","name","status","created_at","updated_at","steps","connections"],"additionalProperties":false},"AutomationStepResponse":{"type":"object","properties":{"key":{"type":"string","example":"start"},"type":{"type":"string","enum":["trigger","send_email","delay","condition","contact_update","add_to_segment","topic_update"],"description":"The type of automation step."},"config":{"type":"object","additionalProperties":{},"description":"The step's configuration, as it was published."}},"required":["key","type","config"],"additionalProperties":false},"PatchAutomationResponse":{"type":"object","properties":{"object":{"type":"string","enum":["automation"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"}},"required":["object","id"],"additionalProperties":false},"PatchAutomationRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"The name of the automation."},"status":{"type":"string","enum":["enabled","disabled"],"description":"The status of the automation. `disabled` stops new enrolments and leaves runs already in flight alone."},"steps":{"type":"array","items":{"$ref":"#/components/schemas/AutomationStep"},"minItems":1,"maxItems":150,"description":"The steps that compose the automation workflow, at most 150. Exactly one must be a `trigger`."},"connections":{"type":"array","items":{"$ref":"#/components/schemas/AutomationConnection"},"description":"The connections between steps in the automation graph."}}},"DeleteAutomationResponse":{"type":"object","properties":{"object":{"type":"string","enum":["automation"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"DuplicateAutomationResponse":{"type":"object","properties":{"object":{"type":"string","enum":["automation"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"}},"required":["object","id"],"additionalProperties":false},"StopAutomationResponse":{"type":"object","properties":{"object":{"type":"string","enum":["automation"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"status":{"type":"string","enum":["disabled"],"description":"The status after stopping."}},"required":["object","id","status"],"additionalProperties":false},"AutomationVersionList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AutomationVersion"}}},"required":["object","has_more","data"],"additionalProperties":false},"AutomationVersion":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"version_number":{"type":"integer"},"active":{"type":"boolean","description":"Whether new enrolments run this version."},"trigger_event_name":{"type":"string"},"trigger_segment_id":{"type":["string","null"],"format":"uuid"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/AutomationStepResponse"}},"connections":{"type":"array","items":{"$ref":"#/components/schemas/AutomationConnection"}},"created_by":{"type":["object","null"],"properties":{"type":{"type":"string","enum":["user","api_key"]},"id":{"type":"string","format":"uuid"}},"required":["type","id"],"additionalProperties":false,"description":"Whoever wrote the version, or null once neither exists."},"created_at":{"type":"string"}},"required":["id","version_number","active","trigger_event_name","trigger_segment_id","steps","connections","created_by","created_at"],"additionalProperties":false},"ListAutomationRunsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AutomationRunListItem"}}},"required":["object","has_more","data"],"additionalProperties":false},"AutomationRunListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e02"},"status":{"type":"string","enum":["running","completed","failed","cancelled"]},"started_at":{"type":["string","null"]},"completed_at":{"type":["string","null"]},"created_at":{"type":"string"}},"required":["id","status","started_at","completed_at","created_at"],"additionalProperties":false},"AutomationRun":{"type":"object","properties":{"object":{"type":"string","enum":["automation_run"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e02"},"status":{"type":"string","enum":["running","completed","failed","cancelled"]},"started_at":{"type":["string","null"]},"completed_at":{"type":["string","null"]},"created_at":{"type":"string"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/AutomationRunStep"}}},"required":["object","id","status","started_at","completed_at","created_at","steps"],"additionalProperties":false},"AutomationRunStep":{"type":"object","properties":{"key":{"type":"string","example":"welcome"},"type":{"type":"string","enum":["trigger","send_email","delay","condition","contact_update","add_to_segment","topic_update"]},"status":{"type":"string","example":"completed"},"started_at":{"type":["string","null"]},"completed_at":{"type":["string","null"]},"output":{"type":["object","null"],"additionalProperties":{},"description":"The output produced by the step, if any."},"error":{"type":["object","null"],"additionalProperties":{},"description":"The error produced by the step, if any."},"created_at":{"type":"string"}},"required":["key","type","status","started_at","completed_at","output","error","created_at"],"additionalProperties":false},"CreateEventResponse":{"type":"object","properties":{"object":{"type":"string","enum":["event"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01"}},"required":["object","id"],"additionalProperties":false},"CreateEventRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"example":"trial.started","description":"The name of the event: lower-case letters, digits, `.`, `_` and `-`, starting with a letter. The reserved `rasket:` prefix belongs to the platform's own triggers and is refused."},"schema":{"type":["object","null"],"additionalProperties":{},"example":{"plan":"string","seats":"number"},"description":"A flat key/type map defining the event payload schema. Supported types are `string`, `number`, `boolean`, `date`."}},"required":["name"]},"ListEventsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/EventSummary"}}},"required":["object","has_more","data"],"additionalProperties":false},"EventSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01"},"name":{"type":"string","example":"trial.started"},"schema":{"type":["object","null"],"additionalProperties":{"type":"string","enum":["string","number","boolean","date"]},"example":{"plan":"string","seats":"number"},"description":"A flat key/type map defining the event payload schema. Supported types are `string`, `number`, `boolean`, `date`."},"created_at":{"type":"string"},"updated_at":{"type":["string","null"]}},"required":["id","name","schema","created_at","updated_at"],"additionalProperties":false},"SendEventResponse":{"type":"object","properties":{"object":{"type":"string","enum":["event"]},"event":{"type":"string","example":"trial.started","description":"The name of the event that was sent."}},"required":["object","event"],"additionalProperties":false},"SendEventRequest":{"type":"object","properties":{"event":{"type":"string","example":"trial.started","description":"The name of the event to send."},"contact_id":{"type":"string","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f02","description":"The contact to associate with this event. Exactly one of `contact_id` or `email` must be provided."},"email":{"type":"string","example":"hello@example.com","description":"The email address to associate with this event. Exactly one of `contact_id` or `email` must be provided."},"payload":{"type":"object","additionalProperties":{},"description":"Key/value pairs to carry with the event. At most 16 KB of JSON."}},"required":["event"]},"Event":{"type":"object","properties":{"object":{"type":"string","enum":["event"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01"},"name":{"type":"string","example":"trial.started"},"schema":{"type":["object","null"],"additionalProperties":{"type":"string","enum":["string","number","boolean","date"]},"example":{"plan":"string","seats":"number"},"description":"A flat key/type map defining the event payload schema. Supported types are `string`, `number`, `boolean`, `date`."},"created_at":{"type":"string"},"updated_at":{"type":["string","null"]}},"required":["object","id","name","schema","created_at","updated_at"],"additionalProperties":false},"UpdateEventResponse":{"type":"object","properties":{"object":{"type":"string","enum":["event"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01"}},"required":["object","id"],"additionalProperties":false},"UpdateEventRequest":{"type":"object","properties":{"schema":{"type":["object","null"],"additionalProperties":{},"example":{"plan":"string","seats":"number"},"description":"A flat key/type map defining the event payload schema. Supported types are `string`, `number`, `boolean`, `date`. Set to `null` to clear it."}},"required":["schema"]},"RemoveEventResponse":{"type":"object","properties":{"object":{"type":"string","enum":["event"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"],"additionalProperties":false},"RegisteredClient":{"type":"object","properties":{"client_id":{"type":"string","example":"rkoc_7Fq2Lm9pXw3Kd8Vn1Zt5Rb4C"},"client_id_issued_at":{"type":"integer","description":"Seconds since the epoch."},"registration_client_uri":{"type":"string"},"client_name":{"type":"string"},"redirect_uris":{"type":"array","items":{"type":"string"}},"grant_types":{"type":"array","items":{"type":"string"}},"response_types":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_method":{"type":"string","enum":["none"]},"scope":{"type":"string"},"client_uri":{"type":"string"},"logo_uri":{"type":"string"},"software_id":{"type":"string"},"software_version":{"type":"string"},"registration_access_token":{"type":"string","description":"Shown exactly once. Required by the RFC 7592 management routes."}},"required":["client_id","client_id_issued_at","registration_client_uri","client_name","redirect_uris","grant_types","response_types","token_endpoint_auth_method","registration_access_token"],"additionalProperties":false},"OAuthRegistrationError":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_client_metadata","invalid_redirect_uri","invalid_token"]},"error_description":{"type":"string"}},"required":["error","error_description"],"additionalProperties":false},"OAuthClientInformation":{"type":"object","properties":{"client_id":{"type":"string","example":"rkoc_7Fq2Lm9pXw3Kd8Vn1Zt5Rb4C"},"client_id_issued_at":{"type":"integer","description":"Seconds since the epoch."},"registration_client_uri":{"type":"string"},"client_name":{"type":"string"},"redirect_uris":{"type":"array","items":{"type":"string"}},"grant_types":{"type":"array","items":{"type":"string"}},"response_types":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_method":{"type":"string","enum":["none"]},"scope":{"type":"string"},"client_uri":{"type":"string"},"logo_uri":{"type":"string"},"software_id":{"type":"string"},"software_version":{"type":"string"}},"required":["client_id","client_id_issued_at","registration_client_uri","client_name","redirect_uris","grant_types","response_types","token_endpoint_auth_method"],"additionalProperties":false},"ListOAuthGrantsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/OAuthGrant"}}},"required":["object","has_more","data"],"additionalProperties":false},"OAuthGrant":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"client_id":{"type":"string","example":"rkoc_7Fq2Lm9pXw3Kd8Vn1Zt5Rb4C"},"scopes":{"type":"array","items":{"type":"string"},"example":["emails:send","logs:read"]},"created_at":{"type":"string"},"revoked_at":{"type":["string","null"]},"revoked_reason":{"type":["string","null"]},"client":{"type":"object","properties":{"name":{"type":"string","example":"Acme CRM"},"logo_uri":{"type":["string","null"]}},"required":["name","logo_uri"],"additionalProperties":false}},"required":["id","client_id","scopes","created_at","revoked_at","revoked_reason","client"],"additionalProperties":false},"RevokeOAuthGrantResponse":{"type":"object","properties":{"object":{"type":"string","enum":["oauth_grant"]},"id":{"type":"string","format":"uuid","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"revoked_at":{"type":"string"},"revoked_reason":{"type":"string","example":"user"}},"required":["object","id","revoked_at","revoked_reason"],"additionalProperties":false},"TeamProfile":{"type":"object","properties":{"object":{"type":"string","enum":["team"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"created_at":{"type":"string"},"risk_state":{"type":"string"},"plan":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"limits":{"type":"object","properties":{"included_emails":{"type":"integer"},"daily_cap":{"type":["integer","null"]},"domain_limit":{"type":"integer"},"webhook_endpoint_limit":{"type":"integer"},"retention_days":{"type":"integer"}},"required":["included_emails","daily_cap","domain_limit","webhook_endpoint_limit","retention_days"],"additionalProperties":false}},"required":["code","name","limits"],"additionalProperties":false},"sender_identity":{"type":"object","properties":{"sender_name":{"type":["string","null"]},"postal_address":{"$ref":"#/components/schemas/PostalAddress"}},"required":["sender_name","postal_address"],"additionalProperties":false},"ai_assist_enabled":{"type":"boolean"},"sso":{"type":["object","null"],"properties":{"status":{"type":"string"},"issuer":{"type":"string"},"client_id":{"type":"string"},"enforced":{"type":"boolean"},"domains":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["verified","pending"]}},"required":["domain","status"],"additionalProperties":false}}},"required":["status","issuer","client_id","enforced","domains"],"additionalProperties":false,"description":"The single sign-on summary, or null before a connection exists. Never the client secret."}},"required":["object","id","name","slug","created_at","risk_state","plan","sender_identity","ai_assist_enabled","sso"],"additionalProperties":false},"PostalAddress":{"type":["object","null"],"properties":{"line1":{"type":"string"},"line2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"postal_code":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2, upper-case.","example":"US"}},"required":["line1","city","postal_code","country"],"additionalProperties":false},"PatchTeamRequest":{"type":"object","properties":{"sender_name":{"type":"string","description":"One line, at most 200 characters."},"postal_address":{"allOf":[{"$ref":"#/components/schemas/PostalAddress"},{"description":"The address every broadcast footer prints (A66). Sent alone, it is paired with the stored `sender_name`."}]},"ai_assist_enabled":{"type":"boolean","description":"Turning AI assist on sends the content you ask about to Anthropic; recipient addresses are never included."}},"additionalProperties":{}},"DomainRecords":{"type":"object","properties":{"object":{"type":"string","enum":["domain_records"]},"domain_id":{"type":"string","format":"uuid"},"sending_verified":{"type":"boolean"},"tracking_verified":{"type":"boolean"},"receiving_verified":{"type":"boolean"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DomainRecordObservation"}}},"required":["object","domain_id","sending_verified","tracking_verified","receiving_verified","records"],"additionalProperties":false},"DomainRecordObservation":{"type":"object","properties":{"record":{"type":"string","enum":["SPF","DKIM","Receiving","Tracking","TrackingCAA"]},"name":{"type":"string"},"type":{"type":"string","enum":["MX","TXT","CNAME","CAA"]},"ttl":{"type":"string"},"value":{"type":"string","description":"What to publish."},"priority":{"type":"integer"},"status":{"type":"string","enum":["pending","verified","failed","temporary_failure","not_started"]},"observed":{"type":"array","items":{"type":"string"},"description":"What DNS answered at `name` on the last check."},"reason":{"type":["string","null"],"description":"Why the record is not verified, such as `not_found` or `value_mismatch`."},"last_checked_at":{"type":["string","null"]}},"required":["record","name","type","ttl","value","status","observed","reason","last_checked_at"],"additionalProperties":false},"EmailEventList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"has_more":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/EmailEvent"}}},"required":["object","has_more","data"],"additionalProperties":false},"EmailEvent":{"type":"object","properties":{"object":{"type":"string","enum":["email_event"]},"id":{"type":"string","format":"uuid"},"type":{"type":"string","example":"email.delivered"},"recipient":{"type":["string","null"],"description":"The address this event is about, or null for the whole message."},"occurred_at":{"type":"string"},"data":{"description":"The event-specific object in webhook shape, stored as it arrived."}},"required":["object","id","type","recipient","occurred_at"],"additionalProperties":false},"AiSubjectSuggestions":{"type":"object","properties":{"object":{"type":"string","enum":["ai_subject_suggestions"]},"suggestions":{"type":"array","items":{"type":"string"}},"credits_remaining":{"type":"integer"},"credits":{"$ref":"#/components/schemas/AiCredits"}},"required":["object","suggestions","credits_remaining","credits"],"additionalProperties":false},"AiCredits":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"remaining":{"type":"integer"}},"required":["limit","used","remaining"],"additionalProperties":false},"AiSubjectLinesRequest":{"type":"object","properties":{"subject":{"type":"string","description":"The current subject, if any."},"html":{"type":"string","description":"The HTML body, up to 100000 characters."},"text":{"type":"string","description":"The plain-text body, up to 100000 characters."},"audience":{"type":"string","description":"Who the email is for, up to 2000 characters."},"template_id":{"type":"string","format":"uuid","description":"The template this call is about, recorded as the request's target. It must be one of this team's templates; the content itself comes from the body, not from the saved template."}}},"AiDraft":{"type":"object","properties":{"object":{"type":"string","enum":["ai_draft"]},"html":{"type":"string"},"text":{"type":"string"},"credits_remaining":{"type":"integer"},"credits":{"$ref":"#/components/schemas/AiCredits"}},"required":["object","html","text","credits_remaining","credits"],"additionalProperties":false},"AiDraftRequest":{"type":"object","properties":{"brief":{"type":"string","description":"What the email should say, up to 2000 characters.","example":"Welcome a new customer and point them at the quickstart."},"tone":{"type":"string","enum":["neutral","friendly","formal"]},"existing_html":{"type":"string","description":"A draft to rework, up to 100000 characters."},"template_id":{"type":"string","format":"uuid","description":"The template this call is about, recorded as the request's target. It must be one of this team's templates; the content itself comes from the body, not from the saved template."}},"required":["brief"]},"AiDiagnosis":{"type":"object","properties":{"object":{"type":"string","enum":["ai_diagnosis"]},"summary":{"type":"string"},"likely_causes":{"type":"array","items":{"type":"string"}},"next_steps":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string"},"stored":{"type":"boolean","description":"True when this diagnosis was made earlier for the same state of the email and read back: no credit was spent."},"credits_remaining":{"type":"integer"},"credits":{"$ref":"#/components/schemas/AiCredits"}},"required":["object","summary","likely_causes","next_steps","created_at","stored","credits_remaining","credits"],"additionalProperties":false}},"parameters":{},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An API key (rk_…) or an OAuth access token (rko_…). Send a User-Agent."},"sessionCookie":{"type":"apiKey","in":"cookie","name":"rsk_session","description":"The dashboard session cookie. Session-only routes accept nothing else."},"registrationAccessToken":{"type":"http","scheme":"bearer","description":"The `registration_access_token` `POST /oauth/register` returned once (RFC 7592). It manages that one client and nothing else."}}},"paths":{"/api/healthz":{"get":{"tags":["operations"],"summary":"The deployment is serving","responses":{"200":{"description":"Serving.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/readyz":{"get":{"tags":["operations"],"summary":"Every dependency is usable","responses":{"200":{"description":"Ready.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ready"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"One or more checks failed; `failed` names them.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ready"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/auth/signup":{"post":{"tags":["auth"],"summary":"Create an account, its first team and a session","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}}},"responses":{"201":{"description":"The account, its first team and a session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/auth/login":{"post":{"tags":["auth"],"summary":"Exchange an email and password for a session","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"The signed-in user and their current team, or — when the account has a second factor — the challenge that has to be answered before a session exists.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/Session"},{"$ref":"#/components/schemas/MfaChallenge"}]}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/auth/logout":{"post":{"tags":["auth"],"summary":"Revoke this session, or every session this user has","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutRequest"}}}},"responses":{"200":{"description":"The session is revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutResult"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/auth/verify-email":{"post":{"tags":["auth"],"summary":"Consume a verification token","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}}},"responses":{"200":{"description":"The address is verified.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailResult"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/auth/request-reset":{"post":{"tags":["auth"],"summary":"Start a password reset","description":"Always answers 200 with the same body, whether or not the address has an account.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRequest"}}}},"responses":{"200":{"description":"The request was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequested"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/auth/reset":{"post":{"tags":["auth"],"summary":"Consume a reset token and set a new password","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}}},"responses":{"200":{"description":"The password is changed and every session revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetResult"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The reset token is invalid or has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/auth/mfa":{"get":{"tags":["auth"],"summary":"Whether this account has a second factor, and how many recovery codes are left","responses":{"200":{"description":"The account's MFA state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaStatus"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/auth/mfa/enroll":{"post":{"tags":["auth"],"summary":"Generate a TOTP secret and return its otpauth: URI, once","description":"The URI and the base32 secret are returned exactly once and are never logged, stored in plaintext, or derivable again. Enrolment does not turn MFA on.","responses":{"200":{"description":"The enrolment secret, for this response only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaEnrolment"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/auth/mfa/activate":{"post":{"tags":["auth"],"summary":"Confirm the secret with a code and turn the second factor on","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaConfirmRequest"}}}},"responses":{"200":{"description":"MFA is on, and the ten recovery codes, once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaActivated"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/auth/mfa/disable":{"post":{"tags":["auth"],"summary":"Turn the second factor off and destroy every recovery code","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaConfirmRequest"}}}},"responses":{"200":{"description":"MFA is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaDisabled"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/auth/mfa/recovery-codes":{"post":{"tags":["auth"],"summary":"Replace the ten recovery codes with ten new ones","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaCodeRequest"}}}},"responses":{"200":{"description":"Ten fresh codes, once. The previous ten are gone.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaRecoveryCodes"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/auth/mfa/verify":{"post":{"tags":["auth"],"summary":"Answer a login challenge with an authenticator code","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaVerifyRequest"}}}},"responses":{"200":{"description":"The signed-in user, and the session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The code or the challenge is not valid, expired, or already used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/auth/mfa/recovery":{"post":{"tags":["auth"],"summary":"Answer a login challenge with one of the ten recovery codes","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaRecoveryRequest"}}}},"responses":{"200":{"description":"The signed-in user, and the session cookie. One code spent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The code or the challenge is not valid, expired, or already used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/me":{"get":{"tags":["auth"],"summary":"The signed-in user, their current team and every team they belong to","responses":{"200":{"description":"The signed-in user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/teams":{"post":{"tags":["teams"],"summary":"Create a team and become its admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTeamRequest"}}}},"responses":{"201":{"description":"The new team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null},"get":{"tags":["teams"],"summary":"Every team the signed-in user belongs to","responses":{"200":{"description":"The user's teams.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/teams/{team_id}/switch":{"post":{"tags":["teams"],"summary":"Remember this team as the session's current one","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"018f4c1e-0000-7000-8000-000000000000"},"required":true,"name":"team_id","in":"path"}],"responses":{"200":{"description":"The team now selected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/teams/{team_id}/members":{"get":{"tags":["teams"],"summary":"The members of a team, with their MFA state","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"018f4c1e-0000-7000-8000-000000000000"},"required":true,"name":"team_id","in":"path"}],"responses":{"200":{"description":"The team's members.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMemberList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/teams/{team_id}/invitations":{"post":{"tags":["teams"],"summary":"Invite someone to a team","description":"Reserved. Invitations need platform mail through the real pipeline (A13), which arrives with T12; acceptance is Phase 2.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"018f4c1e-0000-7000-8000-000000000000"},"required":true,"name":"team_id","in":"path"}],"responses":{"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request origin is not allowed, or the actor may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such team, or not a member of it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"sessionCookie":[]}],"x-rasket-permission":"session","x-rasket-scope":null}},"/api/v1/billing":{"get":{"tags":["billing"],"summary":"The team's plan, usage this period, payment state, add-ons and pending change","responses":{"200":{"description":"The Billing page in one object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"billing:read"}},"/api/v1/billing/checkout":{"post":{"tags":["billing"],"summary":"Start a subscription: a hosted Checkout session for the plan","description":"Answers the hosted page to send the browser to, and when it stops working. `return_url` (absolute `https`) is where Stripe sends the browser back, with `checkout=success` or `checkout=cancelled` appended; it defaults to the dashboard's Plan page. Called with an API key, no email address is sent to the payment provider: the customer enters one on the hosted page.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan_code":{"type":"string","minLength":1,"maxLength":64},"return_url":{"type":"string","minLength":1,"maxLength":2048}},"required":["plan_code"],"additionalProperties":false}}}},"responses":{"200":{"description":"Where to send the browser, and until when.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSession"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/billing/portal":{"post":{"tags":["billing"],"summary":"Payment method, address, tax ID, invoices and cancellation: the Customer Portal","responses":{"200":{"description":"Where to send the browser.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalSession"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/billing/plan":{"post":{"tags":["billing"],"summary":"Change the plan on an existing subscription","description":"An upgrade takes effect immediately with prorations; a downgrade is scheduled for the end of the current period. Free → paid is a Checkout and paid → free is a Portal cancellation, so both are refused here. A move that would turn off the team's single sign-on is refused for an API key: it decides who may sign in, so a signed-in admin makes it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan_code":{"type":"string","minLength":1,"maxLength":64}},"required":["plan_code"],"additionalProperties":false}}}},"responses":{"200":{"description":"The Billing page after the change.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/billing/invoices":{"get":{"tags":["billing"],"summary":"The team's invoices, newest first","description":"Read from the billing provider and cached for sixty seconds per team.","responses":{"200":{"description":"The invoices.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingInvoiceList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"billing:read"}},"/api/v1/domains":{"post":{"tags":["domains"],"summary":"Add a sending domain and generate its DNS records","description":"Generates a 2048-bit DKIM keypair (D5) with the selector `rasket` (D6), stores the private key envelope-encrypted, and returns every record the domain must publish. All records start `not_started`; the `dns-verify` cron checks them from now on.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"region":{"type":"string","enum":["us-east-1","eu-west-1","sa-east-1","ap-northeast-1"],"default":"us-east-1"},"custom_return_path":{"type":"string","default":"send"},"tracking_subdomain":{"type":"string","default":"links"},"open_tracking":{"type":"boolean","default":false},"click_tracking":{"type":"boolean","default":false},"tls":{"type":"string","enum":["opportunistic","enforced"],"default":"opportunistic"},"capabilities":{"type":"object","properties":{"sending":{"type":"string","enum":["enabled","disabled"]},"receiving":{"type":"string","enum":["enabled","disabled"]}},"additionalProperties":false}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The domain and its records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDomainResponse"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"},"get":{"tags":["domains"],"summary":"List the team's domains","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"before","in":"query"}],"responses":{"200":{"description":"The team's domains.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainList"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:read"}},"/api/v1/domains/claim":{"post":{"tags":["domains"],"summary":"Claim a domain another team has verified","description":"Creates a placeholder domain for your team with fresh DKIM keys and returns the TXT record that proves you control the name. The transfer runs by itself once the record resolves, unless the current owner verified within 72 hours, sent in the last 24 hours, or has scheduled mail from it. Claims expire after 7 days. Repeating the call while a claim is open returns that claim unchanged with `200`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"region":{"type":"string","enum":["us-east-1","eu-west-1","sa-east-1","ap-northeast-1"],"default":"us-east-1"},"custom_return_path":{"type":"string","default":"send"},"tracking_subdomain":{"type":"string","default":"links"},"open_tracking":{"type":"boolean","default":false},"click_tracking":{"type":"boolean","default":false},"tls":{"type":"string","enum":["opportunistic","enforced"],"default":"opportunistic"},"capabilities":{"type":"object","properties":{"sending":{"type":"string","enum":["enabled","disabled"]},"receiving":{"type":"string","enum":["enabled","disabled"]}},"additionalProperties":false}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"An open claim already existed and is returned unchanged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainClaim"}}}},"201":{"description":"The claim and the record to publish.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainClaim"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"}},"/api/v1/domains/{domain_id}/claim":{"get":{"tags":["domains"],"summary":"The latest claim for a domain","description":"`domain_id` is the placeholder domain the claim created, not the claim's own id.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"responses":{"200":{"description":"The latest claim.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainClaim"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:read"}},"/api/v1/domains/{domain_id}/claim/verify":{"post":{"tags":["domains"],"summary":"Check a claim's ownership TXT record","description":"Asks for the claim to be looked at sooner. The claim stays `pending` while the check runs, so poll this domain's claim for the result. Rate-limited to one call per minute per domain, shared with Verify a domain.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"responses":{"200":{"description":"The claim as it stands.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainClaim"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"}},"/api/v1/domains/{domain_id}":{"get":{"tags":["domains"],"summary":"One domain, with the current status of every record","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"responses":{"200":{"description":"The domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:read"},"patch":{"tags":["domains"],"summary":"Change tracking, TLS, capabilities or the tracking subdomain","description":"`region` and `custom_return_path` are chosen at creation and are refused here with `422 invalid_parameter` (05 §1).","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"open_tracking":{"type":"boolean"},"click_tracking":{"type":"boolean"},"tls":{"type":"string","enum":["opportunistic","enforced"]},"tracking_subdomain":{"type":"string"},"capabilities":{"type":"object","properties":{"sending":{"type":"string","enum":["enabled","disabled"]},"receiving":{"type":"string","enum":["enabled","disabled"]}},"additionalProperties":false},"region":{"description":"Chosen at creation and immutable (05 §1); sending it is 422 invalid_parameter."},"custom_return_path":{"description":"Chosen at creation and immutable (05 §1); sending it is 422 invalid_parameter."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The updated domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainRef"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"},"delete":{"tags":["domains"],"summary":"Delete a domain and release its SES identity","description":"Soft delete: the row is retained for 30 days for audit and purged with its DKIM ciphertext by the retention cron (05 §11). Scheduled sends from the domain are canceled and API keys restricted to it are suspended.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"responses":{"200":{"description":"The domain was deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteDomainResponse"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"}},"/api/v1/domains/{domain_id}/verify":{"post":{"tags":["domains"],"summary":"Check this domain's DNS records now","description":"Runs the same code the `dns-verify` cron runs, resets the 72-hour verification window and moves failed records back to `pending`. Rate-limited to one call per minute per domain (429), and `409 resource_locked` while a run is already in flight.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"responses":{"200":{"description":"Verification was started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainRef"}}}},"400":{"description":"Validation failed, or a capability is unavailable in this region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress, or another team has verified this name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or verification was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"}},"/api/v1/domains/{domain_id}/dkim/regenerate":{"post":{"tags":["domains"],"summary":"Generate a new DKIM keypair for this domain","description":"Mints a fresh RSA keypair at `key_bits` (2048 by default, 1024 for a DNS panel that refuses a ~392-character TXT value), stores the private key envelope-encrypted, republishes the DKIM record with the new `p=` value and re-creates the SES identity. The domain stops being verified for sending until the new record is published and checked, so publish the returned value before the next send. Rate-limited to one call per minute per domain, shared with `POST /domains/{domain_id}/verify`.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key_bits":{"type":"number","description":"The RSA modulus size: 2048 (the default) or 1024 (D5's shorter-key fallback)."}},"required":["key_bits"],"additionalProperties":false}}}},"responses":{"200":{"description":"The domain, with the DKIM record's new value.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress for this domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`key_bits` is missing, or is not 1024 or 2048.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or a key was regenerated for this domain less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"}},"/api/v1/domains/{domain_id}/autoconfigure":{"post":{"tags":["domains"],"summary":"Publish this domain's DNS records through its provider","description":"Writes the records for every capability this domain has enabled into the customer's Cloudflare zone, using an API token scoped to `Zone → DNS → Edit` for that one zone. Records we did not write are never touched: an existing record at one of our names is reported in `conflicts` rather than overwritten, and nothing is ever deleted. The token is encrypted at rest and deleted as soon as the records are written unless `keep_token` is `true`. On success the affected records move to `pending` and verification runs immediately. Rate-limited to one call per minute per domain, shared with `POST /domains/{domain_id}/verify`.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","enum":["cloudflare"],"description":"The DNS provider to configure. `cloudflare` is the only one V1 automates (05 §8)."},"token":{"type":"string","minLength":1,"description":"A Cloudflare API token scoped to `Zone → DNS → Edit` for this domain's zone, and that zone only. Global API keys are refused."},"keep_token":{"type":"boolean","default":false,"description":"`true` to keep the token as a revocable credential for re-applying records later. Left `false`, it is deleted as soon as the records are written."}},"required":["provider","token"],"additionalProperties":false}}}},"responses":{"200":{"description":"What was created, updated and left alone.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoconfigureResponse"}}}},"400":{"description":"The token was refused: invalid, a Global API key, or not scoped to this one zone.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team, or no stored credential.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress for this domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or auto-configuration was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Cloudflare could not be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"}},"/api/v1/domains/{domain_id}/autoconfigure/credential":{"delete":{"tags":["domains"],"summary":"Revoke the stored DNS provider credential","description":"Deletes the provider token kept for this domain. Records already published are left exactly as they are; only our copy of the credential goes away. Revoke the token at your provider as well — deleting it here stops us using it, not anyone else.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"responses":{"200":{"description":"The credential was deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteCredentialResponse"}}}},"400":{"description":"The token was refused: invalid, a Global API key, or not scoped to this one zone.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unusable API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This key may not manage domains, or the User-Agent header is absent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such domain in this team, or no stored credential.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A verification run is already in progress for this domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or auto-configuration was requested less than a minute ago.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Cloudflare could not be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:write"}},"/api/v1/api-keys":{"post":{"tags":["api-keys"],"summary":"Create an API key and return its token once","description":"The `token` is shown exactly once and is never recoverable; only its SHA-256 hash and the `rk_` prefix are stored. `domain_id` is accepted only with `sending_access`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"permission":{"type":"string","enum":["full_access","sending_access"],"default":"full_access"},"domain_id":{"type":"string"}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new key and its token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null},"get":{"tags":["api-keys"],"summary":"List the team's API keys","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"before","in":"query"},{"schema":{"type":"string","enum":["active","revoked","all"],"default":"active"},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"A page of API keys.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/api-keys/{api_key_id}":{"patch":{"tags":["api-keys"],"summary":"Rename an API key","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"018f4c1e-0000-7000-8000-000000000000"},"required":true,"name":"api_key_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The renamed key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateApiKeyResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null},"delete":{"tags":["api-keys"],"summary":"Revoke an API key","description":"Revocation is terminal and idempotent. The row is kept with `status = revoked` so request logs and emails keep their join; it is never deleted.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"018f4c1e-0000-7000-8000-000000000000"},"required":true,"name":"api_key_id","in":"path"}],"responses":{"200":{"description":"The revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteApiKeyResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/suppressions/batch/add":{"post":{"tags":["suppressions"],"summary":"Add up to 100 suppressions at once","description":"All-or-nothing: one malformed address rejects the request and writes nothing. Addresses already suppressed come back with their existing ids and are not re-added.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAddSuppressionsRequest"}}}},"responses":{"201":{"description":"The suppressions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedSuppressionList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key, or a sending-only key on a non-sending endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the User-Agent header is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such suppression in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter or field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"suppressions:write"}},"/api/v1/suppressions/batch/remove":{"post":{"tags":["suppressions"],"summary":"Remove up to 100 suppressions at once","description":"Takes `emails` or `ids`, never both. An entry that was not suppressed is reported with `deleted: false` rather than failing the batch.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRemoveSuppressionsRequest"}}}},"responses":{"200":{"description":"The removals.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemovedSuppressionList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key, or a sending-only key on a non-sending endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the User-Agent header is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such suppression in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter or field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"suppressions:write"}},"/api/v1/suppressions":{"post":{"tags":["suppressions"],"summary":"Suppress an email address","description":"Origin `manual`. An address that is already suppressed keeps its earliest row and its origin, and the existing id is returned.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSuppressionRequest"}}}},"responses":{"201":{"description":"The suppression.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedSuppression"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key, or a sending-only key on a non-sending endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the User-Agent header is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such suppression in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter or field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"suppressions:write"},"get":{"tags":["suppressions"],"summary":"List suppressions","parameters":[{"schema":{"type":"string","enum":["bounce","complaint","manual","unsubscribe"],"description":"Filter by origin."},"required":false,"description":"Filter by origin.","name":"origin","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key, or a sending-only key on a non-sending endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the User-Agent header is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such suppression in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter or field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"suppressions:read"}},"/api/v1/suppressions/{suppression}":{"get":{"tags":["suppressions"],"summary":"Retrieve a suppression by ID or email address","parameters":[{"schema":{"type":"string","description":"The suppression ID or the email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The suppression ID or the email address.","name":"suppression","in":"path"}],"responses":{"200":{"description":"The suppression.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Suppression"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key, or a sending-only key on a non-sending endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the User-Agent header is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such suppression in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter or field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"suppressions:read"},"delete":{"tags":["suppressions"],"summary":"Remove a suppression by ID or email address","parameters":[{"schema":{"type":"string","description":"The suppression ID or the email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The suppression ID or the email address.","name":"suppression","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemovedSuppression"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key, or a sending-only key on a non-sending endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the User-Agent header is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such suppression in this team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter or field is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"suppressions:write"}},"/api/v1/webhooks":{"post":{"tags":["webhooks"],"summary":"Create a webhook endpoint and return its signing secret once","description":"The `signing_secret` is shown exactly once and is never recoverable; afterwards it is masked. The endpoint count is limited by your plan.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["email.sent","email.scheduled","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.failed","email.suppressed","email.canceled","domain.created","domain.updated","domain.deleted","suppression.added","suppression.removed","contact.created","contact.updated","contact.deleted","email.received","automation.run.started","automation.run.completed","automation.run.failed"]},"minItems":1}},"required":["endpoint","events"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new endpoint and its signing secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:write"},"get":{"tags":["webhooks"],"summary":"List the team's webhook endpoints","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"before","in":"query"}],"responses":{"200":{"description":"A page of endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:read"}},"/api/v1/webhooks/{webhook_id}/rotate-secret":{"post":{"tags":["webhooks"],"summary":"Rotate the signing secret, keeping the previous one valid for 24 hours","description":"During the overlap every delivery is signed with both secrets and `svix-signature` carries two `v1,` values; a verifier that knows either one accepts the delivery.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"}],"responses":{"200":{"description":"The new signing secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:write"}},"/api/v1/webhooks/{webhook_id}/events/{event_id}/replay":{"post":{"tags":["webhooks"],"summary":"Deliver one event again","description":"The same bytes under the same `svix-id`, with a fresh timestamp and signature. A manual replay delivers once and schedules no automatic retries. Limited to 10 per minute.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":128,"example":"msg_0198f4c1000070008000000000000000"},"required":true,"name":"event_id","in":"path"}],"responses":{"200":{"description":"The replayed event.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEventRef"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:write"}},"/api/v1/webhooks/{webhook_id}/events/{event_id}/attempts":{"get":{"tags":["webhooks"],"summary":"List every delivery attempt made for one event","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":128,"example":"msg_0198f4c1000070008000000000000000"},"required":true,"name":"event_id","in":"path"}],"responses":{"200":{"description":"The attempts, oldest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookAttemptList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:read"}},"/api/v1/webhooks/{webhook_id}/events/{event_id}":{"get":{"tags":["webhooks"],"summary":"Read one event, with its payload and its schedule","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":128,"example":"msg_0198f4c1000070008000000000000000"},"required":true,"name":"event_id","in":"path"}],"responses":{"200":{"description":"The event.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:read"}},"/api/v1/webhooks/{webhook_id}/events":{"get":{"tags":["webhooks"],"summary":"List the events created for one endpoint","description":"Filter by delivery state, by event type, and by a window on `created_at`. Every filter is additive to the reference spec and composes with the cursor.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"before","in":"query"},{"schema":{"type":"string","enum":["pending","attempting","success","failed"],"description":"Only events in this delivery state."},"required":false,"description":"Only events in this delivery state.","name":"status","in":"query"},{"schema":{"type":"string","enum":["email.sent","email.scheduled","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.failed","email.suppressed","email.canceled","domain.created","domain.updated","domain.deleted","suppression.added","suppression.removed","contact.created","contact.updated","contact.deleted","email.received","automation.run.started","automation.run.completed","automation.run.failed"],"description":"Only events of this type, such as `email.bounced`."},"required":false,"description":"Only events of this type, such as `email.bounced`.","name":"type","in":"query"},{"schema":{"type":"string","description":"ISO 8601 instant, inclusive. Events created before this are excluded."},"required":false,"description":"ISO 8601 instant, inclusive. Events created before this are excluded.","name":"start_date","in":"query"},{"schema":{"type":"string","description":"ISO 8601 instant, inclusive. Must be at or after `start_date`."},"required":false,"description":"ISO 8601 instant, inclusive. Must be at or after `start_date`.","name":"end_date","in":"query"}],"responses":{"200":{"description":"A page of events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEventList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:read"}},"/api/v1/webhooks/{webhook_id}/parked/deliver":{"post":{"tags":["webhooks"],"summary":"Deliver the events parked while the endpoint was disabled","description":"Replays the oldest parked events in order, at most 10 per call, inside the same per-team budget as a single replay (10 per minute). When the budget runs out delivery stops with `stopped_reason: \"rate_limit_exceeded\"`; `remaining` is how many events are still parked. A disabled endpoint is `422 validation_error`: enable it first.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"}],"responses":{"200":{"description":"What was delivered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParkedDelivery"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:write"}},"/api/v1/webhooks/{webhook_id}/parked":{"get":{"tags":["webhooks"],"summary":"List the events parked while the endpoint was disabled","description":"An auto-disabled endpoint keeps receiving events without delivering them. Oldest first, because a backlog is delivered in the order it happened. `has_more` is true when more are parked than `limit`.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"The parked events, oldest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParkedWebhookEventList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:read"}},"/api/v1/webhooks/{webhook_id}":{"get":{"tags":["webhooks"],"summary":"Read one webhook endpoint","description":"`signing_secret` is masked. The plaintext is returned only by create and rotate-secret.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"}],"responses":{"200":{"description":"The endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDetail"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:read"},"patch":{"tags":["webhooks"],"summary":"Change the endpoint, its subscriptions or its status","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["email.sent","email.scheduled","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.failed","email.suppressed","email.canceled","domain.created","domain.updated","domain.deleted","suppression.added","suppression.removed","contact.created","contact.updated","contact.deleted","email.received","automation.run.started","automation.run.completed","automation.run.failed"]},"minItems":1},"status":{"type":"string","enum":["enabled","disabled"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The updated endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRef"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:write"},"delete":{"tags":["webhooks"],"summary":"Delete a webhook endpoint","description":"The row is kept so past events and attempts keep their join; it stops receiving events.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"9f8a3b21-7c4e-4f0a-9f2f-6f6d1c1a0b55"},"required":true,"name":"webhook_id","in":"path"}],"responses":{"200":{"description":"The deleted endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteWebhookResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"webhooks:write"}},"/api/v1/logs":{"get":{"tags":["logs"],"summary":"List API request logs","description":"Every request made with this team's credentials, newest first — including the writes the dashboard made on your behalf, which are logged with `source: dashboard`. Rows are kept for your plan's retention window (30 days by default) and then deleted, so a log older than that is absent rather than empty. Reading this endpoint writes a row of its own.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return logs after this ID."},"required":false,"description":"Return logs after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return logs before this ID."},"required":false,"description":"Return logs before this ID.","name":"before","in":"query"},{"schema":{"type":"integer","minimum":100,"maximum":599,"description":"The response status recorded on the row, such as 422."},"required":false,"description":"The response status recorded on the row, such as 422.","name":"status","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":512,"description":"An exact User-Agent, as it was sent."},"required":false,"description":"An exact User-Agent, as it was sent.","name":"user_agent","in":"query"},{"schema":{"type":"string","description":"The client that made the request: `api`, `dashboard`, or `sdk:<name>`."},"required":false,"description":"The client that made the request: `api`, `dashboard`, or `sdk:<name>`.","name":"source","in":"query"},{"schema":{"type":"string","description":"ISO 8601, inclusive. Logs created before this are excluded."},"required":false,"description":"ISO 8601, inclusive. Logs created before this are excluded.","name":"start_date","in":"query"},{"schema":{"type":"string","description":"ISO 8601, inclusive. Logs created after this are excluded."},"required":false,"description":"ISO 8601, inclusive. Logs created after this are excluded.","name":"end_date","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"logs:read"}},"/api/v1/logs/{log_id}":{"get":{"tags":["logs"],"summary":"Retrieve a single API request log","description":"`request_body` is the body as it was stored: a body naming a secret-looking field was dropped whole, and a send's message content was replaced by its measurements before the row was written (07 §8). `response_body` is present for a failed request only. A log belonging to another team is `404`.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"0198f4c1-0000-7000-8000-000000000000"},"required":true,"name":"log_id","in":"path"}],"responses":{"200":{"description":"The log.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Log"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"logs:read"}},"/api/v1/templates":{"post":{"tags":["templates"],"summary":"Create a template","description":"Creates the template as a draft holding version 1. Every `{{key}}` in `subject`, `html` and `text` must be declared in `variables`, and every declared key must be used; an alias must be free among the team's live templates. Nothing is sent from it until it is published.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateRequest"}}}},"responses":{"201":{"description":"The template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"templates:write"},"get":{"tags":["templates"],"summary":"Retrieve a list of templates","description":"Most recently changed first. Items carry no content and no `object`, exactly as the reference document has them; `alias` is present only where one is set.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTemplatesResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"templates:read"}},"/api/v1/templates/{id}":{"get":{"tags":["templates"],"summary":"Retrieve a single template","description":"The template with its **current** version's content -- the draft, when one is open. `has_unpublished_versions` says whether that differs from what sends use. `alias`, `from`, `subject` and `text` are absent rather than `null` when unset.","parameters":[{"schema":{"type":"string","description":"The Template ID or alias.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"required":true,"description":"The Template ID or alias.","name":"id","in":"path"}],"responses":{"200":{"description":"The template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"templates:read"},"patch":{"tags":["templates"],"summary":"Update an existing template","description":"Writes the draft. On a published template with no open draft this starts the next version and leaves sends untouched until `publish`; on an open draft it edits in place. Only the fields present change; `alias`, `from` and `subject` accept `null` to clear them. An empty body is refused.","parameters":[{"schema":{"type":"string","description":"The Template ID or alias.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"required":true,"description":"The Template ID or alias.","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTemplateOptions"}}}},"responses":{"200":{"description":"The template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTemplateResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"templates:write"},"delete":{"tags":["templates"],"summary":"Remove an existing template","description":"Soft-deletes: the template answers 404 from this moment, its alias is free to reuse, and emails already sent from it keep their record of which version they used.","parameters":[{"schema":{"type":"string","description":"The Template ID or alias.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"required":true,"description":"The Template ID or alias.","name":"id","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveTemplateResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"templates:write"}},"/api/v1/templates/{id}/publish":{"post":{"tags":["templates"],"summary":"Publish a template","description":"Makes the current version the one sends resolve to. Publishing a template whose current version is already published changes nothing and still answers 200.","parameters":[{"schema":{"type":"string","description":"The Template ID or alias.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"required":true,"description":"The Template ID or alias.","name":"id","in":"path"}],"responses":{"200":{"description":"The template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishTemplateResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"templates:write"}},"/api/v1/templates/{id}/duplicate":{"post":{"tags":["templates"],"summary":"Duplicate a template","description":"Copies the **current** version into a new draft template named `<name> (copy)` with no alias. The source is untouched.","parameters":[{"schema":{"type":"string","description":"The Template ID or alias.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"required":true,"description":"The Template ID or alias.","name":"id","in":"path"}],"responses":{"200":{"description":"The new template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicateTemplateResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"templates:write"}},"/api/v1/templates/{id}/preview":{"post":{"tags":["templates"],"summary":"Preview a template with values filled in","description":"Renders the **current** version, or the `version` named, with `variables` substituted the way a send substitutes them: an undeclared key or a value of the wrong type is `422 invalid_parameter`. A declared variable with neither a value nor a fallback is listed in `missing_variables` and its placeholder is left in place. `html` has been through the dashboard preview's sanitizer, with remote images withheld: put it in a sandboxed iframe's `srcdoc`, never straight into a page. Nothing is stored and nothing is sent.","parameters":[{"schema":{"type":"string","description":"The Template ID or alias.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"required":true,"description":"The Template ID or alias.","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplatePreviewRequest"}}}},"responses":{"200":{"description":"The rendered version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplatePreview"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"templates:read"}},"/api/v1/emails/metrics":{"get":{"tags":["emails"],"summary":"Retrieve account-level email metrics","description":"Totals are aggregated in 15-minute buckets by the `metrics-rollup` job. `end_date` is clamped to the last completed bucket, which the additive `data_as_of` field names. Rate metrics are fractions between 0 and 1.","parameters":[{"schema":{"type":"string","description":"ISO 8601 date or datetime. Defaults to 6 days before end_date."},"required":false,"description":"ISO 8601 date or datetime. Defaults to 6 days before end_date.","name":"start_date","in":"query"},{"schema":{"type":"string","description":"ISO 8601 date or datetime. Clamped to the last completed bucket."},"required":false,"description":"ISO 8601 date or datetime. Clamped to the last completed bucket.","name":"end_date","in":"query"},{"schema":{"type":"string","description":"IANA timezone."},"required":false,"description":"IANA timezone.","name":"timezone","in":"query"},{"schema":{"type":"string","enum":["hourly","daily","weekly","monthly"],"description":"Bucket size when period is a dimension."},"required":false,"description":"Bucket size when period is a dimension.","name":"granularity","in":"query"},{"schema":{"type":"string","description":"Comma-separated. One or more of: received, delivered, complained, suppressed, bounced, bounced_transient, bounced_permanent, bounced_undetermined, opened, clicked, unsubscribed, delivery_delayed, failed, sent, unique_opened, unique_clicked, delivery_rate, open_rate, click_rate, bounce_rate, complaint_rate, unsubscribe_rate."},"required":false,"description":"Comma-separated. One or more of: received, delivered, complained, suppressed, bounced, bounced_transient, bounced_permanent, bounced_undetermined, opened, clicked, unsubscribed, delivery_delayed, failed, sent, unique_opened, unique_clicked, delivery_rate, open_rate, click_rate, bounce_rate, complaint_rate, unsubscribe_rate.","name":"metrics","in":"query"},{"schema":{"type":"string","description":"Comma-separated. One or more of: period, domain, email, broadcast."},"required":false,"description":"Comma-separated. One or more of: period, domain, email, broadcast.","name":"dimensions","in":"query"},{"schema":{"type":"string","description":"Comma-separated UUIDs."},"required":false,"description":"Comma-separated UUIDs.","name":"domain_id","in":"query"},{"schema":{"type":"string","description":"Comma-separated UUIDs."},"required":false,"description":"Comma-separated UUIDs.","name":"email_id","in":"query"},{"schema":{"type":"string","description":"Comma-separated UUIDs."},"required":false,"description":"Comma-separated UUIDs.","name":"broadcast_id","in":"query"}],"responses":{"200":{"description":"The metrics.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEmailsMetricsResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/receiving/{email_id}/raw/download":{"get":{"tags":["receiving"],"summary":"Download the raw message through a signed link","description":"The message exactly as it reached us, as `raw.eml`. Authenticated by the link's own signature rather than by an API key, so a browser can follow it; valid for 15 minutes and for this message only.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"string","description":"Milliseconds since the epoch; part of the signed claim."},"required":true,"description":"Milliseconds since the epoch; part of the signed claim.","name":"expires","in":"query"},{"schema":{"type":"string","description":"The link's signature."},"required":true,"description":"The link's signature.","name":"token","in":"query"}],"responses":{"200":{"description":"The bytes, as an attachment.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"The link is invalid, has expired, or names nothing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/emails/receiving/{email_id}/attachments/{attachment_id}/download":{"get":{"tags":["receiving"],"summary":"Download a received attachment through a signed link","description":"The target of `download_url`. Authenticated by the link's own signature rather than by an API key, so a browser can follow it; valid for 15 minutes and for this attachment only.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"660e8400-e29b-41d4-a716-446655440000"},"required":true,"name":"attachment_id","in":"path"},{"schema":{"type":"string","description":"Milliseconds since the epoch; part of the signed claim."},"required":true,"description":"Milliseconds since the epoch; part of the signed claim.","name":"expires","in":"query"},{"schema":{"type":"string","description":"The link's signature."},"required":true,"description":"The link's signature.","name":"token","in":"query"}],"responses":{"200":{"description":"The bytes, as an attachment.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"The link is invalid, has expired, or names nothing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/emails/receiving":{"get":{"tags":["receiving"],"summary":"List received emails","description":"Newest first. Cursors are received-email IDs. A message we recorded but would not store carries a `dropped_reason` and no attachments.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListReceivedEmailsResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/receiving/{email_id}":{"get":{"tags":["receiving"],"summary":"Retrieve a received email","description":"The message with its headers, bodies and attachment list. The raw source is not included; `…/raw/download` serves it.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"}],"responses":{"200":{"description":"The message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetReceivedEmailResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"},"delete":{"tags":["receiving"],"summary":"Delete a received email","description":"Removes the stored objects and the record, and returns the storage to this team's inbound quota. There is no undo, and no soft delete: the message is gone.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteReceivedEmailResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/emails/receiving/{email_id}/attachments":{"get":{"tags":["receiving"],"summary":"List the attachments of a received email","description":"Cursors are attachment IDs; the page is in the order the parts appeared in the message. A stored part carries a signed `download_url`; one we refused to store is listed with its size and no link.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAttachmentsResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/receiving/{email_id}/attachments/{attachment_id}":{"get":{"tags":["receiving"],"summary":"Retrieve one attachment of a received email","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"660e8400-e29b-41d4-a716-446655440000"},"required":true,"name":"attachment_id","in":"path"}],"responses":{"200":{"description":"The attachment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceivedAttachment"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/{email_id}/share":{"post":{"tags":["emails"],"summary":"Create a shareable link for a sent email","description":"Returns a link that opens a read-only view of this email on a separate origin, with no sign-in. `expires_in` is a duration such as `10m`, `2 hours` or `1 day`; it defaults to 48 hours and may not exceed them. The link is shown once and cannot be retrieved again.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareEmailOptions"}}}},"responses":{"200":{"description":"The link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareEmailResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/{email_id}/shares/{share_id}":{"delete":{"tags":["emails"],"summary":"Revoke a shareable link","description":"Stops the link working on the next request. Idempotent: revoking a link that is already revoked answers the instant it *first* stopped working rather than the instant of this call, and the row is kept either way — a link that was shared and withdrawn is a fact about this email. A share belonging to another email, or to another team, is `404`.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"0198f4c1-0000-7000-8000-000000000000"},"required":true,"name":"share_id","in":"path"}],"responses":{"200":{"description":"The withdrawn link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteEmailShareResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/{email_id}/shares":{"get":{"tags":["emails"],"summary":"List the shareable links of a sent email","description":"Every link ever minted for this email, newest first, live and withdrawn alike. **No link is returned**: only a hash of each token is stored, so neither the URL nor any part of it can be recovered — a lost link is revoked and replaced, never re-shown. Cursors are share IDs.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailShareList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/{email_id}/attachments/{attachment_id}/download":{"get":{"tags":["emails"],"summary":"Download an attachment through a signed link","description":"The target of `download_url`. Authenticated by the link's own signature rather than by an API key, so a browser can follow it; valid for 15 minutes and for this attachment only.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"660e8400-e29b-41d4-a716-446655440000"},"required":true,"name":"attachment_id","in":"path"},{"schema":{"type":"string","description":"Milliseconds since the epoch; part of the signed claim."},"required":true,"description":"Milliseconds since the epoch; part of the signed claim.","name":"expires","in":"query"},{"schema":{"type":"string","description":"The link's signature."},"required":true,"description":"The link's signature.","name":"token","in":"query"}],"responses":{"200":{"description":"The attachment bytes.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"The link is invalid, has expired, or names nothing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/emails/{email_id}/attachments/{attachment_id}":{"get":{"tags":["emails"],"summary":"Retrieve one attachment of a sent email","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"660e8400-e29b-41d4-a716-446655440000"},"required":true,"name":"attachment_id","in":"path"}],"responses":{"200":{"description":"The attachment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetrievedAttachment"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/{email_id}/attachments":{"get":{"tags":["emails"],"summary":"List the attachments of a sent email","description":"Cursors are attachment IDs. Each item carries a signed `download_url`.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/batch":{"post":{"tags":["emails"],"summary":"Send up to 100 emails in one request","description":"All-or-nothing validation: one invalid element rejects the whole batch, naming its index as `emails[3]`, and nothing is stored. All elements are written in one transaction and the ids come back in input order.","parameters":[{"schema":{"type":"string","maxLength":256,"description":"Makes the send exactly-once for 24 hours. A replay returns the original response with `Idempotent-Replayed: true`; the same key with a different payload is `409 invalid_idempotent_request`."},"required":false,"description":"Makes the send exactly-once for 24 hours. A replay returns the original response with `Idempotent-Replayed: true`; the same key with a different payload is `409 invalid_idempotent_request`.","name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBatchEmailsRequest"}}}},"responses":{"200":{"description":"The accepted emails, in input order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBatchEmailsResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The Idempotency-Key was replayed with a different payload, or is in flight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The request body is larger than the configured limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Sending is paused, or a dependency is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"emails:send"}},"/api/v1/emails":{"post":{"tags":["emails"],"summary":"Send an email","description":"Returns as soon as the email is committed; delivery happens in the background. `scheduled_at` accepts ISO 8601 only.","parameters":[{"schema":{"type":"string","maxLength":256,"description":"Makes the send exactly-once for 24 hours. A replay returns the original response with `Idempotent-Replayed: true`; the same key with a different payload is `409 invalid_idempotent_request`."},"required":false,"description":"Makes the send exactly-once for 24 hours. A replay returns the original response with `Idempotent-Replayed: true`; the same key with a different payload is `409 invalid_idempotent_request`.","name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailRequest"}}}},"responses":{"200":{"description":"The accepted email.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The Idempotency-Key was replayed with a different payload, or is in flight.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The request body is larger than the configured limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Sending is paused, or a dependency is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"emails:send"},"get":{"tags":["emails"],"summary":"List emails, newest first","description":"Every filter is optional and additive: sending none returns the same page it always did. They are applied in the query rather than to the page, so `has_more` describes the list you asked for.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"},{"schema":{"type":"string","enum":["queued","scheduled","sent","delivered","delivery_delayed","bounced","complained","opened","clicked","failed","suppressed","canceled"],"description":"The last event the email reached, such as `delivered` or `bounced`."},"required":false,"description":"The last event the email reached, such as `delivered` or `bounced`.","name":"status","in":"query"},{"schema":{"type":"string","description":"Only emails sent with this API key. A revoked key still filters what it sent."},"required":false,"description":"Only emails sent with this API key. A revoked key still filters what it sent.","name":"api_key_id","in":"query"},{"schema":{"type":"string","description":"ISO 8601, inclusive. Emails created before this are excluded."},"required":false,"description":"ISO 8601, inclusive. Emails created before this are excluded.","name":"start_date","in":"query"},{"schema":{"type":"string","description":"ISO 8601, inclusive. Emails created after this are excluded."},"required":false,"description":"ISO 8601, inclusive. Emails created after this are excluded.","name":"end_date","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":200,"description":"Case-insensitive substring of the subject, the sender address or any recipient address. `%` and `_` match literally."},"required":false,"description":"Case-insensitive substring of the subject, the sender address or any recipient address. `%` and `_` match literally.","name":"search","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/{email_id}":{"get":{"tags":["emails"],"summary":"Retrieve a single email","description":"`html` and `text` are null once retention has removed the bodies; `last_event` still describes what happened.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"}],"responses":{"200":{"description":"The email.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"},"patch":{"tags":["emails"],"summary":"Reschedule a scheduled email","description":"Allowed only while the email is still scheduled and its job unclaimed. An email already sent, failed or canceled is `400 validation_error`; a job being claimed right now is `409 resource_locked`, which may be retried.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmailOptions"}}}},"responses":{"200":{"description":"The rescheduled email.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRef"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The send has already started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/emails/{email_id}/cancel":{"post":{"tags":["emails"],"summary":"Cancel a scheduled email","description":"Refunds the quota it was charged at acceptance and records a compensating usage event. The sleeping workflow run is left alone: it wakes, sees the canceled job and exits.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"}],"responses":{"200":{"description":"The canceled email.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailRef"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The send has already started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/contact-properties":{"post":{"tags":["contact-properties"],"summary":"Create a new contact property","description":"`key` is unique within the team; a duplicate is `422 invalid_parameter`. `fallback_value` must match `type`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactPropertyOptions"}}}},"responses":{"201":{"description":"The property.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactPropertyResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"contacts:write"},"get":{"tags":["contact-properties"],"summary":"Retrieve a list of contact properties","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactPropertiesResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"contacts:read"}},"/api/v1/contact-properties/{contact_property_id}":{"get":{"tags":["contact-properties"],"summary":"Retrieve a single contact property","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","description":"The Contact Property ID.","example":"b6d24b8e-af0b-4c3c-be0c-359bbd97381e"},"required":true,"description":"The Contact Property ID.","name":"contact_property_id","in":"path"}],"responses":{"200":{"description":"The property.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactPropertyResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"contacts:read"},"patch":{"tags":["contact-properties"],"summary":"Update an existing contact property","description":"`fallback_value` only; `key` and `type` are immutable. `null` clears it.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","description":"The Contact Property ID.","example":"b6d24b8e-af0b-4c3c-be0c-359bbd97381e"},"required":true,"description":"The Contact Property ID.","name":"contact_property_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactPropertyOptions"}}}},"responses":{"200":{"description":"The property.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactPropertyResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"contacts:write"},"delete":{"tags":["contact-properties"],"summary":"Remove an existing contact property","description":"Removes the declaration and the key from every contact that carried a value for it.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","description":"The Contact Property ID.","example":"b6d24b8e-af0b-4c3c-be0c-359bbd97381e"},"required":true,"description":"The Contact Property ID.","name":"contact_property_id","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveContactPropertyResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"contacts:write"}},"/api/v1/contacts/imports":{"post":{"tags":["contacts"],"summary":"Create a contact import","description":"Uploads a CSV of up to 50 MB as `multipart/form-data` and starts an import. The response arrives as soon as the file is stored; the import itself runs in the background, and reading the import back reports its status and counts. `column_map`, `segments` and `topics` are JSON-encoded strings. Rows past the plan's contact limit are counted as failed with `contact_limit_reached`. No `contact.*` webhook is emitted per row.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateContactImportOptions"}}}},"responses":{"201":{"description":"The import, queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactImportResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The file is over 50 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"No file store is configured.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"contacts:write"},"get":{"tags":["contacts"],"summary":"Retrieve a list of contact imports","description":"Newest first. `status` narrows the page to one status.","parameters":[{"schema":{"type":"string","enum":["queued","in_progress","completed","failed"],"description":"Filter contact imports by status."},"required":false,"description":"Filter contact imports by status.","name":"status","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactImportsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"contacts:read"}},"/api/v1/contacts/imports/{id}":{"get":{"tags":["contacts"],"summary":"Retrieve a single contact import","description":"The import's status and counts. `completed_at` is set once the import has finished, whether it completed or failed.","parameters":[{"schema":{"type":"string","description":"The Contact Import ID.","example":"479e3145-dd38-476b-932c-529ceb705947"},"required":true,"description":"The Contact Import ID.","name":"id","in":"path"}],"responses":{"200":{"description":"The import.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactImport"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"contacts:read"}},"/api/v1/contacts":{"post":{"tags":["contacts"],"summary":"Create a new contact","description":"An address the team already holds a contact for is updated with the fields the body carries and its existing id is returned; a repeat create never resubscribes an opted-out contact. Every key in `properties` must be a declared contact property of a matching type. `plans.marketing_contacts_included` is enforced here with `422 validation_error`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactOptions"}}}},"responses":{"201":{"description":"The contact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"contacts:write"},"get":{"tags":["contacts"],"summary":"Retrieve a list of contacts","description":"Newest first. Items carry no `properties`, and the envelope carries no `has_more`, exactly as the reference document has it; walk pages with `after`.","parameters":[{"schema":{"type":"string","description":"Filter by segment ID."},"required":false,"description":"Filter by segment ID.","name":"segment_id","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"contacts:read"}},"/api/v1/contacts/{contact}":{"get":{"tags":["contacts"],"summary":"Retrieve a single contact by ID or email","parameters":[{"schema":{"type":"string","description":"The Contact ID or email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Contact ID or email address.","name":"contact","in":"path"}],"responses":{"200":{"description":"The contact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"contacts:read"},"patch":{"tags":["contacts"],"summary":"Update a single contact by ID or email","description":"Only the fields present are changed. `properties` merges key by key; a `null` value removes the key. Setting `unsubscribed` is the contact's global subscription state.","parameters":[{"schema":{"type":"string","description":"The Contact ID or email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Contact ID or email address.","name":"contact","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactOptions"}}}},"responses":{"200":{"description":"The contact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"contacts:write"},"delete":{"tags":["contacts"],"summary":"Remove an existing contact by ID or email","description":"Erasure, not a soft delete: the contact's personal data is removed and the contact is a 404 from that moment. Consent records are kept with an email hash only.","parameters":[{"schema":{"type":"string","description":"The Contact ID or email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Contact ID or email address.","name":"contact","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveContactResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"contacts:write"}},"/api/v1/segments":{"post":{"tags":["segments"],"summary":"Create a new segment","description":"`filter` is validated against the team's contact properties when the segment is created: an undeclared property or an operator that does not suit its type is `422 validation_error` with one `errors[]` entry per condition. A segment without a filter has explicit membership only. The filter cannot be changed later.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSegmentOptions"}}}},"responses":{"201":{"description":"The segment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSegmentResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"segments:write"},"get":{"tags":["segments"],"summary":"Retrieve a list of segments","description":"Newest first. Items carry no `filter`; read one segment for its filter.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSegmentsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"segments:read"}},"/api/v1/segments/preview":{"post":{"tags":["segments"],"summary":"Count the contacts a filter matches","description":"How many contacts `filter` matches right now, for a segment that does not exist yet. Nothing is stored. The filter is checked exactly as `POST /segments` checks it, so a filter that would be refused there is `422 validation_error` here with the same `errors[]` paths.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentPreviewRequest"}}}},"responses":{"200":{"description":"The count.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentPreview"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"segments:read"}},"/api/v1/segments/{segment}/contacts":{"get":{"tags":["segments"],"summary":"Retrieve the contacts in a segment","description":"The segment's members: the contacts its filter matches together with those added explicitly, minus deleted contacts, evaluated now. Newest first, paged like `/contacts`. This is the audience a broadcast to the segment would resolve.","parameters":[{"schema":{"type":"string","description":"The Segment ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Segment ID.","name":"segment","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentContactList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"segments:read"}},"/api/v1/segments/{segment}/metrics":{"get":{"tags":["segments"],"summary":"Retrieve the size of a segment","description":"How many contacts the segment resolves to right now, and how they split on the global unsubscribe. One pass over the same membership `/contacts` lists.","parameters":[{"schema":{"type":"string","description":"The Segment ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Segment ID.","name":"segment","in":"path"}],"responses":{"200":{"description":"The counts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentMetrics"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"segments:read"}},"/api/v1/segments/{segment}":{"get":{"tags":["segments"],"summary":"Retrieve a single segment","parameters":[{"schema":{"type":"string","description":"The Segment ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Segment ID.","name":"segment","in":"path"}],"responses":{"200":{"description":"The segment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSegmentResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"segments:read"},"patch":{"tags":["segments"],"summary":"Update an existing segment","description":"Renames the segment. A filter cannot be changed: a `filter` in the body is `422 invalid_parameter`; create a new segment instead.","parameters":[{"schema":{"type":"string","description":"The Segment ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Segment ID.","name":"segment","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSegmentOptions"}}}},"responses":{"200":{"description":"The segment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSegmentResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"segments:write"},"delete":{"tags":["segments"],"summary":"Remove an existing segment","description":"Soft-deletes the segment and frees its name; it is a 404 from that moment. Explicit memberships are kept with the row so a past broadcast's report can still name its audience.","parameters":[{"schema":{"type":"string","description":"The Segment ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Segment ID.","name":"segment","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveSegmentResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"segments:write"}},"/api/v1/contacts/{contact}/segments":{"get":{"tags":["contacts"],"summary":"Retrieve a list of segments for a contact","description":"Every segment the contact is in right now: those it was added to explicitly and those whose filter it matches. Newest segment first.","parameters":[{"schema":{"type":"string","description":"The Contact ID or email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Contact ID or email address.","name":"contact","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactSegmentsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"segments:read"}},"/api/v1/contacts/{contact}/segments/{segment}":{"post":{"tags":["contacts"],"summary":"Add a contact to a segment","description":"Explicit membership. Adding a contact that is already a member changes nothing.","parameters":[{"schema":{"type":"string","description":"The Contact ID or email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Contact ID or email address.","name":"contact","in":"path"},{"schema":{"type":"string","description":"The Segment ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Segment ID.","name":"segment","in":"path"}],"responses":{"200":{"description":"The membership.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddContactToSegmentResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"segments:write"},"delete":{"tags":["contacts"],"summary":"Remove a contact from a segment","description":"Removes an explicit membership. A contact the segment's filter matches stays a member: a filter is a rule, not a list.","parameters":[{"schema":{"type":"string","description":"The Contact ID or email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Contact ID or email address.","name":"contact","in":"path"},{"schema":{"type":"string","description":"The Segment ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Segment ID.","name":"segment","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveContactFromSegmentResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"segments:write"}},"/api/v1/billing/payg":{"post":{"tags":["billing"],"summary":"Switch \"Continue using the service beyond your quota.\" on or off","description":"Sets `pay_as_you_go_enabled` for the caller's team. Switching it on requires a plan with an overage rate (never `free`) and a payment method on file, else `422 validation_error` naming what is missing; the first time it is switched on the overage ceiling is set to ten times the plan's included amount. Pay-as-you-go raises only the plan's monthly component, never the daily cap, the sending-tier cap or a restricted team's limits. Every toggle writes a `billing.payg_toggled` audit row. Toggle copy: \"Continue using the service beyond your quota.\"","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPaygRequest"}}}},"responses":{"200":{"description":"The toggle's state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPaygResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/billing/addons":{"post":{"tags":["billing"],"summary":"Buy an add-on, or set how many units of one the team holds","description":"A team admin's session or a `full_access` API key (A110). `extra_domains_100` ($20 per 100 domains) raises the team's domain limit by 100 per unit and takes effect at once. `dedicated_ip` ($30) is a *request*: it is billed from now and lands with an operator who provisions it by hand; its `status` moves `requested → provisioning → active`. `sso` ($150) is allowed on `scale`, any `scale_*` rung and `enterprise`, and is `422 validation_error` below that; on `enterprise` it is included, so the add-on is recorded `active` with no Stripe item and nothing is charged through the subscription. Removing `sso`, or dropping below Scale, disables the team's SSO connection and clears its enforcement first, so nobody is locked out. Every add-on is an item on the team's Stripe subscription, so a team without an active paid plan is refused with 422. `quantity` is a set, not an increment.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurchaseAddonRequest"}}}},"responses":{"200":{"description":"What the team now holds of this add-on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamAddon"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The add-on changed while the request was in flight; retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/billing/addons/{addon_code}":{"delete":{"tags":["billing"],"summary":"Remove an add-on","description":"A team admin's session or a `full_access` API key. Removing `sso` off Enterprise turns single sign-on off, so an API key is refused it with 403 and a signed-in admin removes it. The subscription item is removed with a proration and the add-on's `status` becomes `canceled`. Removing `extra_domains_100` leaves every existing domain in place: nothing is deleted, and the next domain create is refused by the lower limit. Removing a `dedicated_ip` still open with the operator withdraws the request.","parameters":[{"schema":{"type":"string","enum":["extra_domains_100","dedicated_ip","sso"],"example":"extra_domains_100"},"required":true,"name":"addon_code","in":"path"}],"responses":{"200":{"description":"The add-on, now canceled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamAddon"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/contacts/{contact_id}/topics":{"get":{"tags":["contacts"],"summary":"Retrieve topics for a contact","description":"Every live topic of the team with the contact's effective subscription: the contact's own choice where one was recorded, the topic's `default_subscription` otherwise.","parameters":[{"schema":{"type":"string","description":"The Contact ID or email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Contact ID or email address.","name":"contact_id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactTopicsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"topics:read"},"patch":{"tags":["contacts"],"summary":"Update topics for a contact","description":"Records an explicit choice per topic named, and one consent record per change. A topic id that is not a live topic of the team is `422 invalid_parameter`.","parameters":[{"schema":{"type":"string","description":"The Contact ID or email address.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Contact ID or email address.","name":"contact_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactTopicsOptions"}}}},"responses":{"200":{"description":"The subscriptions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactTopicsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"topics:write"}},"/api/v1/topics":{"post":{"tags":["topics"],"summary":"Create a new topic","description":"`default_subscription` is what a contact with no explicit choice is treated as, and cannot be changed after creation. `visibility` defaults to `private`. A live topic already named `name` is `422 invalid_parameter`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTopicOptions"}}}},"responses":{"201":{"description":"The topic.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTopicResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"topics:write"},"get":{"tags":["topics"],"summary":"Retrieve a list of topics","description":"Newest first; walk pages with `after`.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTopicsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"topics:read"}},"/api/v1/topics/{id}":{"get":{"tags":["topics"],"summary":"Retrieve a single topic","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","description":"The Topic ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Topic ID.","name":"id","in":"path"}],"responses":{"200":{"description":"The topic.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTopicResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"topics:read"},"patch":{"tags":["topics"],"summary":"Update an existing topic","description":"Only `name`, `description` and `visibility` change; a body carrying `default_subscription` is refused with `422 invalid_parameter`.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","description":"The Topic ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Topic ID.","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTopicOptions"}}}},"responses":{"200":{"description":"The topic.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTopicResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"topics:write"},"delete":{"tags":["topics"],"summary":"Remove an existing topic","description":"A soft delete: the topic is a 404 from that moment and its name is free again, while emails and consent records that name it keep doing so.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","description":"The Topic ID.","example":"78261eea-8f8b-4381-83c6-79fa7120f1cf"},"required":true,"description":"The Topic ID.","name":"id","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveTopicResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"topics:write"}},"/api/v1/broadcasts":{"post":{"tags":["broadcasts"],"summary":"Create a broadcast","description":"Creates a draft. With `send: true` the broadcast goes straight through the compliance gate and is queued (or, with `scheduled_at`, scheduled); a gate refusal creates nothing. Bodies may carry `{{{KEY|default}}}` merge variables, rendered per recipient at send time.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBroadcastOptions"}}}},"responses":{"201":{"description":"The broadcast.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBroadcastResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"broadcasts:write"},"get":{"tags":["broadcasts"],"summary":"Retrieve a list of broadcasts","description":"Newest first. Deleted drafts are not listed.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBroadcastsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"broadcasts:read"}},"/api/v1/broadcasts/{id}/send":{"post":{"tags":["broadcasts"],"summary":"Send or schedule a broadcast","description":"Moves a draft to `queued`, or to `scheduled` when `scheduled_at` is given (ISO 8601, at least one minute and at most thirty days out). The compliance gate refuses without a domain with `sending_verified_at`, a postal address on the team, a segment that resolves, the marketing kill switch on, and a team that is neither restricted nor suspended.","parameters":[{"schema":{"type":"string","description":"The Broadcast ID.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Broadcast ID.","name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBroadcastOptions"}}}},"responses":{"200":{"description":"The broadcast id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBroadcastResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"broadcasts:write"}},"/api/v1/broadcasts/{id}/cancel":{"post":{"tags":["broadcasts"],"summary":"Cancel a broadcast","description":"Cancels a broadcast that is queued or scheduled. Canceling a queued broadcast stops it mid-send; emails already sent are not affected, but no further emails will go out.","parameters":[{"schema":{"type":"string","description":"The Broadcast ID.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Broadcast ID.","name":"id","in":"path"}],"responses":{"200":{"description":"The broadcast.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelBroadcastResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"broadcasts:write"}},"/api/v1/broadcasts/{id}/recipients":{"get":{"tags":["broadcasts"],"summary":"Retrieve broadcast recipients","description":"Retrieve the recipients of a broadcast for a given event type, such as who opened, clicked, or bounced. `type` is required; `bounce_type` is only valid when `type` is `bounced`.","parameters":[{"schema":{"type":"string","description":"The Broadcast ID.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Broadcast ID.","name":"id","in":"path"},{"schema":{"type":"string","enum":["sent","delivered","opened","clicked","bounced","complained","unsubscribed","suppressed"],"description":"The recipient event type to filter by."},"required":true,"description":"The recipient event type to filter by.","name":"type","in":"query"},{"schema":{"type":"string","description":"Filter recipients whose email address contains this value."},"required":false,"description":"Filter recipients whose email address contains this value.","name":"email","in":"query"},{"schema":{"type":"string","enum":["permanent","transient","undetermined"],"description":"Filter bounced recipients by bounce type. Only valid when `type` is `bounced`."},"required":false,"description":"Filter bounced recipients by bounce type. Only valid when `type` is `bounced`.","name":"bounce_type","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBroadcastRecipientsResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"broadcasts:read"}},"/api/v1/broadcasts/{id}/clicked-links":{"get":{"tags":["broadcasts"],"summary":"Retrieve a broadcast's clicked links","description":"Every URL clicked in the broadcast's emails, with total and unique clicks.","parameters":[{"schema":{"type":"string","description":"The Broadcast ID.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Broadcast ID.","name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBroadcastClickedLinksResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"broadcasts:read"}},"/api/v1/broadcasts/{id}/checklist":{"get":{"tags":["broadcasts"],"summary":"Check what would stop a broadcast from sending","description":"Every condition of the send gate, passed or not, in the order a send checks them. A failed condition carries the error `name` and `message` the send would answer with. Advisory in time only: the send runs the same gate again when it is called.","parameters":[{"schema":{"type":"string","description":"The Broadcast ID.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Broadcast ID.","name":"id","in":"path"}],"responses":{"200":{"description":"The checklist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastCompliance"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"broadcasts:read"}},"/api/v1/broadcasts/{id}":{"get":{"tags":["broadcasts"],"summary":"Retrieve a single broadcast","parameters":[{"schema":{"type":"string","description":"The Broadcast ID.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Broadcast ID.","name":"id","in":"path"}],"responses":{"200":{"description":"The broadcast.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBroadcastResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"broadcasts:read"},"patch":{"tags":["broadcasts"],"summary":"Update an existing broadcast","description":"Draft only: a broadcast past `draft` answers `400 validation_error`.","parameters":[{"schema":{"type":"string","description":"The Broadcast ID.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Broadcast ID.","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBroadcastOptions"}}}},"responses":{"200":{"description":"The broadcast.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBroadcastResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"broadcasts:write"},"delete":{"tags":["broadcasts"],"summary":"Remove an existing broadcast that is in the draft status","description":"Draft only, as the spec requires; the broadcast is a 404 from that moment.","parameters":[{"schema":{"type":"string","description":"The Broadcast ID.","example":"e169aa45-1ecf-4183-9955-b1499d5701d3"},"required":true,"description":"The Broadcast ID.","name":"id","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveBroadcastResponseSuccess"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"broadcasts:write"}},"/api/v1/oauth/authorize":{"get":{"tags":["oauth"],"summary":"Start an authorization code flow with PKCE","description":"Validates the request and redirects the browser to the consent page. An unknown or disabled client, or a `redirect_uri` the client did not register, renders an error page and never redirects (RFC 6749 §4.1.2.1); every other failure redirects to the client with `error`, `error_description` and `state`.","parameters":[{"name":"response_type","in":"query","required":true,"description":"Always `code`.","schema":{"type":"string"}},{"name":"client_id","in":"query","required":true,"description":"The client's `rkoc_` identifier.","schema":{"type":"string"}},{"name":"redirect_uri","in":"query","required":true,"description":"Exactly one of the client's registered redirect URIs.","schema":{"type":"string"}},{"name":"scope","in":"query","required":false,"description":"Space-separated scopes; the client's registered default when omitted.","schema":{"type":"string"}},{"name":"state","in":"query","required":true,"description":"Returned unchanged with the code or the error; at most 512 characters.","schema":{"type":"string"}},{"name":"code_challenge","in":"query","required":true,"description":"`BASE64URL(SHA256(code_verifier))`, 43 characters.","schema":{"type":"string"}},{"name":"code_challenge_method","in":"query","required":true,"description":"Always `S256`; `plain` is refused.","schema":{"type":"string"}},{"name":"resource","in":"query","required":false,"description":"RFC 8707 resource indicator; must name this API.","schema":{"type":"string"}}],"responses":{"302":{"description":"To the consent page, or back to the client with an error.","headers":{"location":{"schema":{"type":"string"}}}},"400":{"description":"Unknown client or unregistered redirect URI.","content":{"text/html":{"schema":{"type":"string"}}}},"429":{"description":"Too many requests from this address.","content":{"text/html":{"schema":{"type":"string"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/oauth/token":{"post":{"tags":["oauth"],"summary":"Exchange an authorization code, or rotate a refresh token","description":"Public clients only. `authorization_code` requires the code, the same `redirect_uri`, the same `client_id` and the PKCE `code_verifier`. `refresh_token` rotates: the presented token is revoked and a new pair issued. A code or refresh token presented twice revokes the whole grant. Errors use RFC 6749 §5.2's shape, not the Rasket error body.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["grant_type","client_id"],"properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token"]},"client_id":{"type":"string"},"code":{"type":"string","description":"`authorization_code` only."},"redirect_uri":{"type":"string","description":"`authorization_code` only."},"code_verifier":{"type":"string","description":"`authorization_code` only."},"refresh_token":{"type":"string","description":"`refresh_token` only."},"scope":{"type":"string","description":"`refresh_token` only; may narrow, never widen."}}}},"application/json":{"schema":{"type":"object","required":["grant_type","client_id"],"properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token"]},"client_id":{"type":"string"},"code":{"type":"string","description":"`authorization_code` only."},"redirect_uri":{"type":"string","description":"`authorization_code` only."},"code_verifier":{"type":"string","description":"`authorization_code` only."},"refresh_token":{"type":"string","description":"`refresh_token` only."},"scope":{"type":"string","description":"`refresh_token` only; may narrow, never widen."}}}}}},"responses":{"200":{"description":"The token pair.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenResponse"}}}},"400":{"description":"The request or the grant was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"401":{"description":"`invalid_client`: unknown or disabled client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/automations":{"post":{"tags":["automations"],"summary":"Create an automation","description":"Writes the automation and version 1 of its graph in one transaction. Exactly one step must be a `trigger`, every other step must be reachable from it, the graph must be acyclic, and every template, segment, topic, contact property and custom event it names must exist in this team. `status` defaults to `disabled`, so nothing enrols until you enable it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAutomationRequest"}}}},"responses":{"201":{"description":"The automation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAutomationResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"automations:write"},"get":{"tags":["automations"],"summary":"Retrieve a list of automations","description":"Newest first. Items carry no graph and no `object`, exactly as the reference document has them; retrieve one automation for its steps and connections.","parameters":[{"schema":{"type":"string","enum":["enabled","disabled"],"description":"Filter automations by status."},"required":false,"description":"Filter automations by status.","name":"status","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAutomationsResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"automations:read"}},"/api/v1/automations/{automation_id}":{"get":{"tags":["automations"],"summary":"Retrieve a single automation","description":"The automation with its **active** version's `steps` and `connections` -- the version new enrolments will run. A run already in flight keeps the version it started on.","parameters":[{"schema":{"type":"string","description":"The ID of the automation.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"required":true,"description":"The ID of the automation.","name":"automation_id","in":"path"}],"responses":{"200":{"description":"The automation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Automation"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"automations:read"},"patch":{"tags":["automations"],"summary":"Update an automation","description":"A `PATCH` carrying `steps` and `connections` is the publish: it validates the graph, writes the next immutable version and re-points the automation at it, leaving runs in flight on the version they pinned. The two must be sent together. A `PATCH` with only `name` and/or `status` creates no version. `status: \"disabled\"` stops new enrolments and does **not** cancel live runs -- that is `stop`. An empty body is refused.","parameters":[{"schema":{"type":"string","description":"The ID of the automation.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"required":true,"description":"The ID of the automation.","name":"automation_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchAutomationRequest"}}}},"responses":{"200":{"description":"The automation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchAutomationResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"automations:write"},"delete":{"tags":["automations"],"summary":"Delete an automation","description":"Cancels every run still `running`, then soft-deletes: the automation answers 404 from this moment, and each cancelled run raises `automation.run.failed` with the reason `cancelled`.","parameters":[{"schema":{"type":"string","description":"The ID of the automation.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"required":true,"description":"The ID of the automation.","name":"automation_id","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAutomationResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"automations:write"}},"/api/v1/automations/{automation_id}/duplicate":{"post":{"tags":["automations"],"summary":"Duplicate an automation","description":"Copies the **active** version verbatim into a new `disabled` automation named `<name> (copy)`, at version 1. The copy is not re-validated: what it copies was valid when it was written, and a re-parse would refuse a `delay` whose `until` has since moved closer.","parameters":[{"schema":{"type":"string","description":"The ID of the automation.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"required":true,"description":"The ID of the automation.","name":"automation_id","in":"path"}],"responses":{"201":{"description":"The new automation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicateAutomationResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"automations:write"}},"/api/v1/automations/{automation_id}/stop":{"post":{"tags":["automations"],"summary":"Stop an automation","description":"Disables the automation **and** cancels every run still `running`. Stopping an automation that is already disabled still cancels its live runs, and still answers 200.","parameters":[{"schema":{"type":"string","description":"The ID of the automation.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"required":true,"description":"The ID of the automation.","name":"automation_id","in":"path"}],"responses":{"200":{"description":"The automation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StopAutomationResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"automations:write"}},"/api/v1/automations/{automation_id}/versions":{"get":{"tags":["automations"],"summary":"List an automation's versions","description":"Every published version, newest first, with its graph and whether it is the active one. To make an earlier version active again, `PATCH /automations/{automation_id}` with that version's `steps` and `connections`: this publishes it as the next version.","parameters":[{"schema":{"type":"string","description":"The ID of the automation.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"required":true,"description":"The ID of the automation.","name":"automation_id","in":"path"}],"responses":{"200":{"description":"The versions, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationVersionList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"automations:read"}},"/api/v1/automations/{automation_id}/runs":{"get":{"tags":["automations"],"summary":"Retrieve a list of automation runs","description":"One run per contact per enrolling event, newest first. A run parked on a `delay` is reported as `running`, and `?status=running` returns it, because the public status enum has no word for the difference.","parameters":[{"schema":{"type":"string","description":"The ID of the automation.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"required":true,"description":"The ID of the automation.","name":"automation_id","in":"path"},{"schema":{"type":"string","description":"Filter runs by status. Comma-separated list of: running, completed, failed, cancelled. A run parked on a `delay` is reported as `running`."},"required":false,"description":"Filter runs by status. Comma-separated list of: running, completed, failed, cancelled. A run parked on a `delay` is reported as `running`.","name":"status","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAutomationRunsResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"automations:read"}},"/api/v1/automations/{automation_id}/runs/{run_id}":{"get":{"tags":["automations"],"summary":"Retrieve a single automation run","description":"The run with its `steps[]` in **graph order** -- a breadth-first walk from the trigger of the version this run pinned, taking `condition_met` before `condition_not_met`, so a condition's two branches read in the order the editor draws them.","parameters":[{"schema":{"type":"string","description":"The ID of the automation.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"},"required":true,"description":"The ID of the automation.","name":"automation_id","in":"path"},{"schema":{"type":"string","description":"The ID of the automation run.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e02"},"required":true,"description":"The ID of the automation run.","name":"run_id","in":"path"}],"responses":{"200":{"description":"The run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationRun"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"automations:read"}},"/api/v1/events":{"post":{"tags":["events"],"summary":"Create an event","description":"Declares a custom event an automation may trigger on and `POST /events/send` may fire. Names are lower-case letters, digits, `.`, `_` and `-`, starting with a letter, unique among this team's live events, and never under the reserved `rasket:` prefix. An optional `schema` type-checks every payload sent under the name.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventRequest"}}}},"responses":{"201":{"description":"The event.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"events:write"},"get":{"tags":["events"],"summary":"Retrieve a list of events","description":"Every live event definition, newest first. Items carry no `object`.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"1–100, default 20."},"required":false,"description":"1–100, default 20.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items after this ID."},"required":false,"description":"Return items after this ID.","name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Return items before this ID."},"required":false,"description":"Return items before this ID.","name":"before","in":"query"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListEventsResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"events:read"}},"/api/v1/events/send":{"post":{"tags":["events"],"summary":"Send an event","description":"Records the event against one contact and enrols them into every enabled automation triggering on it. Answers 202: the send is durable the moment this returns, and the runs start on the next tick. Exactly one of `contact_id` or `email` identifies the contact. There is no `Idempotency-Key` here -- two calls are two events and two runs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEventRequest"}}}},"responses":{"202":{"description":"The event was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEventResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"sending_access","x-rasket-scope":"events:send"}},"/api/v1/events/{identifier}":{"get":{"tags":["events"],"summary":"Retrieve a single event","description":"By ID or by name. `schema` is `null` when the event declares none.","parameters":[{"schema":{"type":"string","description":"The event ID (UUID) or event name.","example":"trial.started"},"required":true,"description":"The event ID (UUID) or event name.","name":"identifier","in":"path"}],"responses":{"200":{"description":"The event.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"events:read"},"patch":{"tags":["events"],"summary":"Update an event","description":"Replaces the declared payload schema; `null` clears it. `schema` is required, because the only field a `PATCH` can change is that one -- an event's name is immutable, so that a version already triggering on it never loses its trigger.","parameters":[{"schema":{"type":"string","description":"The event ID (UUID) or event name.","example":"trial.started"},"required":true,"description":"The event ID (UUID) or event name.","name":"identifier","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventRequest"}}}},"responses":{"200":{"description":"The event.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"events:write"},"delete":{"tags":["events"],"summary":"Delete an event","description":"Soft-deletes and frees the name. A published automation version still naming it simply never fires again; runs already in flight are untouched.","parameters":[{"schema":{"type":"string","description":"The event ID (UUID) or event name.","example":"trial.started"},"required":true,"description":"The event ID (UUID) or event name.","name":"identifier","in":"path"}],"responses":{"200":{"description":"The removal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveEventResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"events:write"}},"/api/v1/oauth/register":{"post":{"tags":["oauth"],"summary":"Register an OAuth client (RFC 7591)","description":"Unauthenticated dynamic client registration. Public clients only: `token_endpoint_auth_method` must be `none` and `response_types` must be `[\"code\"]`. Limited to 10 registrations per IP per hour and 1,000 a day platform-wide. The `registration_access_token` is shown exactly once and is the only credential for the management routes below.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["redirect_uris","client_name"],"properties":{"redirect_uris":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":10,"description":"https URLs, or RFC 8252 §7.3 loopback URLs for a native client."},"client_name":{"type":"string","maxLength":100},"client_uri":{"type":"string","description":"https only; shown on the consent page."},"logo_uri":{"type":"string","description":"https only."},"scope":{"type":"string","description":"Space-separated, from: emails:send, emails:read, domains:read, domains:write, templates:read, templates:write, contacts:read, contacts:write, segments:read, segments:write, topics:read, topics:write, broadcasts:read, broadcasts:write, suppressions:read, suppressions:write, webhooks:read, webhooks:write, logs:read, automations:read, automations:write, events:read, events:write, events:send, team:read, team:write, billing:read, ai:use."},"grant_types":{"type":"array","items":{"type":"string","enum":["authorization_code","refresh_token"]}},"response_types":{"type":"array","items":{"type":"string","enum":["code"]}},"token_endpoint_auth_method":{"type":"string","enum":["none"]},"software_id":{"type":"string"},"software_version":{"type":"string"}}}}}},"responses":{"201":{"description":"The registered client and its one-time token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisteredClient"}}}},"400":{"description":"RFC 7591 §3.2.2: the metadata was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthRegistrationError"}}}},"429":{"description":"Too many registrations from this address, or platform-wide today.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/oauth/register/{client_id}":{"get":{"tags":["oauth"],"summary":"Read a registered client (RFC 7592)","description":"Requires `Authorization: Bearer <registration_access_token>`.","parameters":[{"schema":{"type":"string","description":"The `rkoc_` client identifier.","example":"rkoc_7Fq2Lm9pXw3Kd8Vn1Zt5Rb4C"},"required":true,"description":"The `rkoc_` client identifier.","name":"client_id","in":"path"}],"responses":{"200":{"description":"The client's metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthClientInformation"}}}},"401":{"description":"Missing, malformed or unknown registration token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthRegistrationError"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"registrationAccessToken":[]}],"x-rasket-permission":"none","x-rasket-scope":null},"put":{"tags":["oauth"],"summary":"Replace a registered client's metadata (RFC 7592)","description":"A full replacement: a field the request omits is cleared. The registration access token is not rotated — a client has no channel to learn a new one.","parameters":[{"schema":{"type":"string","description":"The `rkoc_` client identifier.","example":"rkoc_7Fq2Lm9pXw3Kd8Vn1Zt5Rb4C"},"required":true,"description":"The `rkoc_` client identifier.","name":"client_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["redirect_uris","client_name"],"properties":{"redirect_uris":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":10,"description":"https URLs, or RFC 8252 §7.3 loopback URLs for a native client."},"client_name":{"type":"string","maxLength":100},"client_uri":{"type":"string","description":"https only; shown on the consent page."},"logo_uri":{"type":"string","description":"https only."},"scope":{"type":"string","description":"Space-separated, from: emails:send, emails:read, domains:read, domains:write, templates:read, templates:write, contacts:read, contacts:write, segments:read, segments:write, topics:read, topics:write, broadcasts:read, broadcasts:write, suppressions:read, suppressions:write, webhooks:read, webhooks:write, logs:read, automations:read, automations:write, events:read, events:write, events:send, team:read, team:write, billing:read, ai:use."},"grant_types":{"type":"array","items":{"type":"string","enum":["authorization_code","refresh_token"]}},"response_types":{"type":"array","items":{"type":"string","enum":["code"]}},"token_endpoint_auth_method":{"type":"string","enum":["none"]},"software_id":{"type":"string"},"software_version":{"type":"string"}}}}}},"responses":{"200":{"description":"The replaced metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthClientInformation"}}}},"400":{"description":"RFC 7591 §3.2.2: the metadata was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthRegistrationError"}}}},"401":{"description":"Missing, malformed or unknown registration token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthRegistrationError"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"registrationAccessToken":[]}],"x-rasket-permission":"none","x-rasket-scope":null},"delete":{"tags":["oauth"],"summary":"Delete a registered client (RFC 7592)","description":"Revokes every grant the client holds, on every team, with `revoked_reason = client`, and every token under them. The client row is kept as `disabled` so those grants keep their history; retention removes it later.","parameters":[{"schema":{"type":"string","description":"The `rkoc_` client identifier.","example":"rkoc_7Fq2Lm9pXw3Kd8Vn1Zt5Rb4C"},"required":true,"description":"The `rkoc_` client identifier.","name":"client_id","in":"path"}],"responses":{"204":{"description":"The client is deleted and its grants revoked."},"401":{"description":"Missing, malformed or unknown registration token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthRegistrationError"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"registrationAccessToken":[]}],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/oauth/revoke":{"post":{"tags":["oauth"],"summary":"Revoke an access or refresh token","description":"An access token is revoked alone; a refresh token takes its whole family and every access token of the same grant (RFC 7009 §2.1). The grant itself stays live — only the customer or the client's deletion revokes that. A token that is unknown, expired, already revoked or another client's still answers **200** with an empty body (RFC 7009 §2.2).","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["token","client_id"],"properties":{"token":{"type":"string","description":"The access or refresh token to revoke."},"token_type_hint":{"type":"string","enum":["access_token","refresh_token"],"description":"Accepted and ignored: one lookup finds either kind."},"client_id":{"type":"string","description":"The client the token was issued to."}}}},"application/json":{"schema":{"type":"object","required":["token","client_id"],"properties":{"token":{"type":"string","description":"The access or refresh token to revoke."},"token_type_hint":{"type":"string","enum":["access_token","refresh_token"],"description":"Accepted and ignored: one lookup finds either kind."},"client_id":{"type":"string","description":"The client the token was issued to."}}}}}},"responses":{"200":{"description":"The token is revoked, or was never valid. Empty body."},"400":{"description":"The request was malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"401":{"description":"`invalid_client`: unknown or disabled client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"x-rasket-permission":"none","x-rasket-scope":null}},"/api/v1/oauth/grants":{"get":{"tags":["oauth"],"summary":"Retrieve a list of OAuth grants","description":"Every grant this team has given an OAuth client, newest first — live and revoked alike, so a revoked one is visible rather than silently gone.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"before","in":"query"}],"responses":{"200":{"description":"A page of grants.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListOAuthGrantsResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/oauth/grants/{oauth_grant_id}":{"delete":{"tags":["oauth"],"summary":"Revoke an OAuth grant","description":"Revokes the grant and every token issued under it, with `revoked_reason = user`. Idempotent: revoking a revoked grant answers the revocation it already has.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","description":"The OAuth grant ID.","example":"0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"},"required":true,"description":"The OAuth grant ID.","name":"oauth_grant_id","in":"path"}],"responses":{"200":{"description":"The revoked grant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeOAuthGrantResponse"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/mcp":{"post":{"tags":["mcp"],"summary":"The MCP endpoint","description":"A remote Model Context Protocol server in stateless JSON mode, authenticated by an OAuth access token. The body is a single JSON-RPC 2.0 request; a batch is refused. Accept must list both application/json and text/event-stream.","parameters":[{"schema":{"type":"string","description":"Comma-separated toolsets to register: `setup`, `send`, `audience`, `marketing`, `insight`, `ai`, `billing`. Absent means all seven; `describe_setup` is always registered. An unknown name is JSON-RPC error `-32602`.","example":"setup,send"},"required":false,"description":"Comma-separated toolsets to register: `setup`, `send`, `audience`, `marketing`, `insight`, `ai`, `billing`. Absent means all seven; `describe_setup` is always registered. An unknown name is JSON-RPC error `-32602`.","name":"toolset","in":"query"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{}}}},"responses":{"200":{"description":"A JSON-RPC 2.0 response.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":null,"x-rasket-scope":null}},"/api/v1/team":{"get":{"tags":["team"],"summary":"The team this credential belongs to","description":"The team's profile, plan and limits, risk state, sender identity, whether AI assist is on, and a summary of its single sign-on connection. Never the SSO client secret, and never the member list (`GET /team/members`).","responses":{"200":{"description":"The team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamProfile"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"team:read"},"patch":{"tags":["team"],"summary":"Change the team's sender identity or AI assist","description":"Every field is optional and at least one is required. `sender_name` and `postal_address` may be sent separately; each is paired with the value already stored, and a team with no postal address yet must send one. Each field sent writes an audit row (`team.postal_address_set`, `team.ai_assist_toggled`). The team cannot be renamed through the API: a body naming `name` is `422 validation_error`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchTeamRequest"}}}},"responses":{"200":{"description":"The team after the change.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamProfile"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":"team:write"}},"/api/v1/team/members":{"get":{"tags":["team"],"summary":"The people on the team","description":"A `full_access` API key or a session. No OAuth scope reaches this route: who is on a team is never shared with a connected app.","responses":{"200":{"description":"The team's members.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMemberList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-rasket-permission":"full_access","x-rasket-scope":null}},"/api/v1/domains/{domain_id}/records":{"get":{"tags":["domains"],"summary":"Compare a domain's DNS records with what DNS answered","description":"Each record to publish, with its verification `status`, the values DNS answered at its `name` on the last check (`observed`), why it is not verified (`reason`) and when it was last checked. Use it to fix a domain that will not verify: a record with no `observed` value was not found, and one whose `observed` value differs from `value` was published wrong. Request a new check with `POST /domains/{domain_id}/verify`.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"d91cd9bd-1176-453e-8fc1-35364d380206"},"required":true,"name":"domain_id","in":"path"}],"responses":{"200":{"description":"The records and what DNS answered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainRecords"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"domains:read"}},"/api/v1/emails/{email_id}/events":{"get":{"tags":["emails"],"summary":"List an email's delivery events","description":"Every event recorded for the email — sent, delivered, bounced, opened, clicked and the rest — oldest first, each with the recipient it is about (null for a whole-message event) and its event-specific `data`. Ordered by when the event happened, not by when it was received.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"}],"responses":{"200":{"description":"The events, oldest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailEventList"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"emails:read"}},"/api/v1/ai/subject-lines":{"post":{"tags":["ai"],"summary":"Suggest subject lines for an email","description":"Suggestions for the subject of the email described by `subject`, `html` and `text`. Nothing is saved. AI assist must be on for the team (`403 invalid_permission` otherwise), the month's credits must not be spent (`422 validation_error`), and a team may make 10 AI requests a minute (`429 rate_limit_exceeded`). An accepted request spends one credit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSubjectLinesRequest"}}}},"responses":{"200":{"description":"The suggestions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSubjectSuggestions"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"ai:use"}},"/api/v1/ai/draft":{"post":{"tags":["ai"],"summary":"Draft an email body from a brief","description":"An HTML and a plain-text body written from `brief`, or a rework of `existing_html`. Nothing is saved or sent. AI assist must be on for the team (`403 invalid_permission` otherwise), the month's credits must not be spent (`422 validation_error`), and a team may make 10 AI requests a minute (`429 rate_limit_exceeded`). An accepted request spends one credit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiDraftRequest"}}}},"responses":{"200":{"description":"The draft.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiDraft"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"ai:use"}},"/api/v1/emails/{email_id}/diagnose":{"post":{"tags":["ai"],"summary":"Explain what happened to an email","description":"A summary of the email's delivery, its likely causes and next steps. The assistant sees recipient domains, statuses and the event timeline, never a recipient's address or the body. A diagnosis already made for the same state of the email is returned again with `stored: true` and costs nothing. AI assist must be on for the team (`403 invalid_permission` otherwise), the month's credits must not be spent (`422 validation_error`), and a team may make 10 AI requests a minute (`429 rate_limit_exceeded`). An accepted request spends one credit.","parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i","example":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"},"required":true,"name":"email_id","in":"path"}],"responses":{"200":{"description":"The diagnosis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiDiagnosis"}}}},"400":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or restricted API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is revoked or suspended, or the actor lacks the permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such resource, or it belongs to another team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field or parameter is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rasket-permission":"full_access","x-rasket-scope":"ai:use"}}},"webhooks":{}}