{"openapi":"3.1.0","info":{"title":"MepMail API","version":"1.0.0","description":"Resend-compatible email API: send transactional email and manage contacts, domains, broadcasts, webhooks and suppressions."},"servers":[{"url":"https://api.mepmail.dev","description":"MepMail Cloud"},{"url":"{baseUrl}","description":"Self-hosted instance","variables":{"baseUrl":{"default":"http://localhost:3001"}}}],"components":{"schemas":{"ContactIdResponse":{"type":"object","properties":{"object":{"type":"string","enum":["contact"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"]},"ErrorResponse":{"type":"object","properties":{"statusCode":{"type":"number"},"name":{"type":"string"},"message":{"type":"string"}},"required":["statusCode","name","message"]},"CreateContactRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Bare email address (no display name); unique per team"},"first_name":{"type":"string","description":"First name"},"last_name":{"type":"string","description":"Last name"},"unsubscribed":{"type":"boolean","description":"Global opt-out from all marketing sends"},"properties":{"type":"object","additionalProperties":{},"description":"Flat map of custom properties (string or number values)"},"segments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"description":"Segments to add the contact to on creation"},"topics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"subscription":{"type":"string","enum":["opt_in","opt_out"]}},"required":["id","subscription"]},"description":"Initial per-topic subscription choices"}},"required":["email"]},"BatchGetContactsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"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"},"properties":{"type":"object","additionalProperties":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["string"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["number"]},"value":{"type":"number"}},"required":["type","value"]}]},"description":"Present with include=properties"},"topics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"subscription":{"type":"string","enum":["opt_in","opt_out"],"description":"Effective choice: the contact's explicit one, else the topic's default"},"explicit":{"type":"boolean","description":"True when the contact or the API chose this; false when it is the topic's default"},"visibility":{"type":"string","enum":["public","private"],"description":"The hosted preference page lists public topics only"}},"required":["id","name","description","subscription","explicit","visibility"]},"description":"Present with include=topics"},"object":{"type":"string","enum":["contact"]}},"required":["id","email","first_name","last_name","created_at","unsubscribed","object"]},"description":"The contacts found, in request order"},"missing":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","description":"Position in the request's contacts array"},"id":{"type":"string","format":"uuid"},"email":{"type":"string"}},"required":["index"]},"description":"Request entries that matched no contact of the team"}},"required":["object","data","missing"]},"BatchGetContactsRequest":{"type":"object","properties":{"contacts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"}}},"minItems":1,"maxItems":1000,"description":"Up to 1000 contacts, each by id or by email address (matched case-insensitively)"},"include":{"type":"array","items":{"type":"string","enum":["properties","topics"]},"description":"Facets to attach to every contact returned: properties and/or topics"}},"required":["contacts"]},"BatchRemoveContactsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RemoveContactResponse"}}},"required":["data"]},"RemoveContactResponse":{"type":"object","properties":{"object":{"type":"string","enum":["contact"]},"contact":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","contact","deleted"]},"BatchRemoveContactsRequest":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"description":"Contact ids to delete, up to 1000"},"emails":{"type":"array","items":{"type":"string","format":"email"},"minItems":1,"maxItems":1000,"description":"Contact email addresses to delete, up to 1000; matched case-insensitively"},"erase":{"type":"boolean","description":"Also erase each address from email history, event payloads and API logs (GDPR/LGPD); by default the send log is kept"}}},"BatchContactsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","enum":["contact"]},"index":{"type":"integer","description":"Position of the item in the request array"},"id":{"type":"string","format":"uuid","description":"The contact's id (the existing one for skipped/updated)"},"status":{"type":"string","enum":["created","updated","skipped"]}},"required":["object","index","id","status"]},"description":"One entry per successful item, in request order"},"counts":{"type":"object","properties":{"created":{"type":"integer"},"updated":{"type":"integer"},"skipped":{"type":"integer"},"failed":{"type":"integer"}},"required":["created","updated","skipped","failed"],"description":"Per-status totals over the request items; they sum to the request length"},"errors":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"message":{"type":"string"}},"required":["index","message"]},"description":"Permissive mode only: the failed items by request index"}},"required":["data","counts"]},"BatchContactsRequest":{"type":"array","items":{"description":"A CreateContactRequest item"},"minItems":1,"maxItems":1000,"description":"1-1000 CreateContactRequest items"},"ListContactsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"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"},"properties":{"type":"object","additionalProperties":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["string"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["number"]},"value":{"type":"number"}},"required":["type","value"]}]},"description":"Present with include=properties"},"topics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"subscription":{"type":"string","enum":["opt_in","opt_out"],"description":"Effective choice: the contact's explicit one, else the topic's default"},"explicit":{"type":"boolean","description":"True when the contact or the API chose this; false when it is the topic's default"},"visibility":{"type":"string","enum":["public","private"],"description":"The hosted preference page lists public topics only"}},"required":["id","name","description","subscription","explicit","visibility"]},"description":"Present with include=topics"}},"required":["id","email","first_name","last_name","created_at","unsubscribed"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"GetContactResponse":{"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"},"object":{"type":"string","enum":["contact"]},"properties":{"type":"object","additionalProperties":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["string"]},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["number"]},"value":{"type":"number"}},"required":["type","value"]}]}}},"required":["id","email","first_name","last_name","created_at","unsubscribed","object","properties"]},"UpdateContactRequest":{"type":"object","properties":{"first_name":{"type":["string","null"],"description":"First name; null clears it"},"last_name":{"type":["string","null"],"description":"Last name; null clears it"},"unsubscribed":{"type":"boolean","description":"Global opt-out from all marketing sends"},"properties":{"type":"object","additionalProperties":{},"description":"Custom properties to set (merged); null removes a key"}}},"ContactPreferencesLinkResponse":{"type":"object","properties":{"object":{"type":"string","enum":["preferences_link"]},"contact":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri","description":"The contact's hosted preference page; no expiry, treat as a secret"}},"required":["object","contact","url"]},"ListContactTopicsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"subscription":{"type":"string","enum":["opt_in","opt_out"],"description":"Effective choice: the contact's explicit one, else the topic's default"},"explicit":{"type":"boolean","description":"True when the contact or the API chose this; false when it is the topic's default"},"visibility":{"type":"string","enum":["public","private"],"description":"The hosted preference page lists public topics only"}},"required":["id","name","description","subscription","explicit","visibility"]}},"has_more":{"type":"boolean","enum":[false]}},"required":["object","data","has_more"]},"UpdateContactTopicsResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"UpdateContactTopicsRequest":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"subscription":{"type":"string","enum":["opt_in","opt_out"]}},"required":["id","subscription"]}},"AddContactSegmentResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"RemoveContactSegmentResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"audienceId":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["id","audienceId","deleted"]},"GetContactPropertyResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"},"key":{"type":"string"},"type":{"type":"string","enum":["string","number"]},"fallback_value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"null"}]},"object":{"type":"string","enum":["contact_property"]}},"required":["id","created_at","key","type","fallback_value","object"]},"CreateContactPropertyRequest":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":200},"type":{"type":"string","enum":["string","number"]},"fallback_value":{"anyOf":[{"type":"string","maxLength":1000},{"type":"number"},{"type":"null"}]}},"required":["key","type"]},"ListContactPropertiesResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"created_at":{"type":"string"},"key":{"type":"string"},"type":{"type":"string","enum":["string","number"]},"fallback_value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"null"}]}},"required":["id","created_at","key","type","fallback_value"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"ContactPropertyIdResponse":{"type":"object","properties":{"object":{"type":"string","enum":["contact_property"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"]},"UpdateContactPropertyRequest":{"type":"object","properties":{"fallback_value":{"anyOf":[{"type":"string","maxLength":1000},{"type":"number"},{"type":"null"}]}}},"RemoveContactPropertyResponse":{"type":"object","properties":{"object":{"type":"string","enum":["contact_property"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]},"SegmentResponse":{"type":"object","properties":{"object":{"type":"string","enum":["segment"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"filter":{"$ref":"#/components/schemas/SegmentFilter"},"created_at":{"type":"string"}},"required":["object","id","name","filter","created_at"]},"SegmentFilter":{"type":["object","null"],"properties":{"match":{"type":"string","enum":["all","any"]},"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string"},"value":{"type":["string","null"],"maxLength":500}},"required":["field","op","value"]},"maxItems":50}},"required":["match","conditions"]},"CreateSegmentRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"filter":{"$ref":"#/components/schemas/SegmentFilter"}},"required":["name"]},"ListSegmentsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","enum":["segment"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"filter":{"$ref":"#/components/schemas/SegmentFilter"},"created_at":{"type":"string"}},"required":["object","id","name","filter","created_at"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"GetSegmentResponse":{"type":"object","properties":{"object":{"type":"string","enum":["segment"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"filter":{"$ref":"#/components/schemas/SegmentFilter"},"created_at":{"type":"string"},"contact_count":{"type":"number"}},"required":["object","id","name","filter","created_at","contact_count"]},"UpdateSegmentRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"filter":{"$ref":"#/components/schemas/SegmentFilter"}}},"RemoveSegmentResponse":{"type":"object","properties":{"object":{"type":"string","enum":["segment"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]},"SendBroadcastResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"finishes_at":{"type":["string","null"],"description":"When the last email is expected to go out (ISO 8601); null when unknown"},"estimated":{"type":"boolean","enum":[true],"description":"finishes_at is an estimate that moves as other sends come in"},"warning":{"type":"object","properties":{"code":{"type":"string","enum":["paced","queued_behind"],"description":"paced: more than the capacity available now; queued_behind: other sends go first"},"days":{"type":"integer","description":"Days the send spans"},"message":{"type":"string"}},"required":["code","days","message"]}},"required":["id"]},"CreateBroadcastRequest":{"type":"object","properties":{"name":{"type":"string","description":"Internal name shown in the dashboard"},"segment_id":{"type":"string","format":"uuid","description":"Segment to send to; omitted means every contact of the team"},"from":{"type":"string","description":"Sender, \"Name <user@domain>\"; the domain must be verified for the team"},"subject":{"type":"string","minLength":1,"description":"Subject line; supports {{{FIRST_NAME|there}}} merge fields"},"html":{"type":"string","description":"HTML body; include {{{UNSUBSCRIBE_URL}}} for the opt-out link"},"text":{"type":"string","description":"Plain-text body; at least one of html/text is required"},"reply_to":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}],"description":"Reply-To address or list"},"preview_text":{"type":"string","description":"Inbox preview (preheader) text"},"topic_id":{"type":["string","null"],"format":"uuid","description":"Topic id; only contacts subscribed to it receive the broadcast"},"send":{"type":"boolean","description":"true sends (or schedules) immediately instead of saving a draft"},"scheduled_at":{"type":"string","description":"Deliver later (requires send: true): ISO 8601 with offset or relative like \"in 1 hour\""}},"required":["from","subject"]},"ListBroadcastsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"segment_id":{"type":["string","null"],"format":"uuid"},"status":{"type":"string"},"created_at":{"type":"string"},"scheduled_at":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"sent_count":{"type":["integer","null"],"description":"Emails handed off so far; null before the send starts and once its emails have left the retention window"},"finishes_at":{"type":["string","null"],"description":"Estimated instant the last email goes out, while the broadcast is going out; else null"}},"required":["id","name","segment_id","status","created_at","scheduled_at","sent_at","sent_count","finishes_at"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"GetBroadcastResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"segment_id":{"type":["string","null"],"format":"uuid"},"status":{"type":"string"},"created_at":{"type":"string"},"scheduled_at":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"sent_count":{"type":["integer","null"],"description":"Emails handed off so far; null before the send starts and once its emails have left the retention window"},"finishes_at":{"type":["string","null"],"description":"Estimated instant the last email goes out, while the broadcast is going out; else null"},"object":{"type":"string","enum":["broadcast"]},"from":{"type":"string"},"subject":{"type":"string"},"reply_to":{"type":["array","null"],"items":{"type":"string"}},"preview_text":{"type":["string","null"]},"topic_id":{"type":["string","null"],"format":"uuid"},"html":{"type":["string","null"]},"text":{"type":["string","null"]}},"required":["id","name","segment_id","status","created_at","scheduled_at","sent_at","sent_count","finishes_at","object","from","subject","reply_to","preview_text","topic_id","html","text"]},"BroadcastIdResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"UpdateBroadcastRequest":{"type":"object","properties":{"name":{"type":"string"},"segment_id":{"type":"string","format":"uuid"},"from":{"type":"string"},"subject":{"type":"string","minLength":1},"html":{"type":"string"},"text":{"type":"string"},"reply_to":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}]},"preview_text":{"type":"string"},"topic_id":{"type":["string","null"],"format":"uuid"}}},"RemoveBroadcastResponse":{"type":"object","properties":{"object":{"type":"string","enum":["broadcast"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]},"SendBroadcastRequest":{"type":"object","properties":{"scheduled_at":{"type":"string","description":"Deliver later: ISO 8601 with offset or relative like \"in 1 hour\"; omitted sends now"}}},"CancelBroadcastResponse":{"type":"object","properties":{"object":{"type":"string","enum":["broadcast"]},"id":{"type":"string","format":"uuid"},"canceled_remaining":{"type":"integer","description":"Emails stopped before going out; the ones already sent are not recalled"}},"required":["object","id","canceled_remaining"]},"TopicResponse":{"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":["private","public"]},"created_at":{"type":"string"}},"required":["id","name","default_subscription","visibility","created_at"]},"CreateTopicRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"description":{"type":"string"},"default_subscription":{"type":"string","enum":["opt_in","opt_out"]},"visibility":{"type":"string","enum":["private","public"]}},"required":["name","default_subscription"]},"ListTopicsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"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":["private","public"]},"created_at":{"type":"string"}},"required":["id","name","default_subscription","visibility","created_at"]}},"has_more":{"type":"boolean","enum":[false]}},"required":["object","data","has_more"]},"TopicIdResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"UpdateTopicRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"description":{"type":"string"},"visibility":{"type":"string","enum":["private","public"]}}},"RemoveTopicResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["topic"]},"deleted":{"type":"boolean","enum":[true]}},"required":["id","object","deleted"]},"CreateDomainResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string"},"region":{"type":"string"},"open_tracking":{"type":"boolean"},"click_tracking":{"type":"boolean"},"tracking_subdomain":{"type":["string","null"]},"capabilities":{"type":"object","properties":{"sending":{"type":"string"},"receiving":{"type":"string"}},"required":["sending","receiving"]},"records":{"type":"array","items":{"type":"object","properties":{"record":{"type":"string","description":"Which record this is: DKIM, SPF (the MAIL FROM MX and TXT rows), DMARC, or Tracking (the branded tracking CNAME, present once a tracking subdomain is set). Only the DKIM and SPF rows gate sending."},"name":{"type":"string"},"type":{"type":"string"},"ttl":{"type":"string"},"status":{"type":"string","description":"not_started | pending | verified | failed. DKIM and SPF rows combine public DNS with the provider's verification: found in DNS but not yet confirmed reads pending, a different published value reads failed, no record reads not_started. DMARC reads verified when a policy covers the domain — its own or a parent domain's (see inherited_from) — and not_started when none does. Tracking reads verified once its CNAME resolves."},"value":{"type":"string"},"priority":{"type":"number"},"live":{"type":"string","enum":["found","missing","mismatch","unknown"],"description":"What public DNS answers for this record right now: found, missing, mismatch (a different value is published) or unknown (the lookup did not conclude). Omitted when no live check ran (the create response)."},"detail":{"type":"string","description":"One sentence explaining a row that is not verified: found but awaiting the provider, the value that is published instead, no record at the name, or which parent DMARC policy covers the domain. Omitted when there is nothing to add."},"inherited_from":{"type":"string","description":"DMARC only: the _dmarc name whose policy covers this domain when it has no record of its own (RFC 7489 organizational-domain fallback)."},"policy":{"type":"string","enum":["none","quarantine","reject"],"description":"DMARC only, alongside inherited_from: the inherited policy's p= value."}},"required":["record","name","type","ttl","status","value"]}}},"required":["id","name","status","created_at","region","open_tracking","click_tracking","tracking_subdomain","capabilities","records"]},"CreateDomainRequest":{"type":"object","properties":{"name":{"type":"string"},"region":{"type":"string","enum":["us-east-1"],"description":"SES region of the identity, one of the regions this deployment serves (the values listed here; the first is the default). Any other region is rejected with 422. A domain has one region: to move it, delete and re-add it."},"custom_return_path":{"type":"string","default":"send"},"open_tracking":{"type":"boolean","description":"Inject a tracking pixel served from the tracking subdomain and record email.opened events. Off by default."},"click_tracking":{"type":"boolean","description":"Rewrite links to redirect through the tracking subdomain and record email.clicked events. Off by default."},"tracking_subdomain":{"type":"string","description":"DNS label of the branded tracking host, e.g. \"links\" for links.<domain>. Setting it adds a Tracking CNAME to records[]; links are tracked through it once that CNAME resolves. Required on MepMail Cloud to turn tracking on."}},"required":["name"]},"ListDomainsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string"},"region":{"type":"string"},"open_tracking":{"type":"boolean"},"click_tracking":{"type":"boolean"},"tracking_subdomain":{"type":["string","null"]},"capabilities":{"type":"object","properties":{"sending":{"type":"string"},"receiving":{"type":"string"}},"required":["sending","receiving"]}},"required":["id","name","status","created_at","region","open_tracking","click_tracking","tracking_subdomain","capabilities"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"GetDomainResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string"},"region":{"type":"string"},"open_tracking":{"type":"boolean"},"click_tracking":{"type":"boolean"},"tracking_subdomain":{"type":["string","null"]},"capabilities":{"type":"object","properties":{"sending":{"type":"string"},"receiving":{"type":"string"}},"required":["sending","receiving"]},"object":{"type":"string","enum":["domain"]},"records":{"type":"array","items":{"type":"object","properties":{"record":{"type":"string","description":"Which record this is: DKIM, SPF (the MAIL FROM MX and TXT rows), DMARC, or Tracking (the branded tracking CNAME, present once a tracking subdomain is set). Only the DKIM and SPF rows gate sending."},"name":{"type":"string"},"type":{"type":"string"},"ttl":{"type":"string"},"status":{"type":"string","description":"not_started | pending | verified | failed. DKIM and SPF rows combine public DNS with the provider's verification: found in DNS but not yet confirmed reads pending, a different published value reads failed, no record reads not_started. DMARC reads verified when a policy covers the domain — its own or a parent domain's (see inherited_from) — and not_started when none does. Tracking reads verified once its CNAME resolves."},"value":{"type":"string"},"priority":{"type":"number"},"live":{"type":"string","enum":["found","missing","mismatch","unknown"],"description":"What public DNS answers for this record right now: found, missing, mismatch (a different value is published) or unknown (the lookup did not conclude). Omitted when no live check ran (the create response)."},"detail":{"type":"string","description":"One sentence explaining a row that is not verified: found but awaiting the provider, the value that is published instead, no record at the name, or which parent DMARC policy covers the domain. Omitted when there is nothing to add."},"inherited_from":{"type":"string","description":"DMARC only: the _dmarc name whose policy covers this domain when it has no record of its own (RFC 7489 organizational-domain fallback)."},"policy":{"type":"string","enum":["none","quarantine","reject"],"description":"DMARC only, alongside inherited_from: the inherited policy's p= value."}},"required":["record","name","type","ttl","status","value"]}}},"required":["id","name","status","created_at","region","open_tracking","click_tracking","tracking_subdomain","capabilities","object","records"]},"UpdateDomainRequest":{"type":"object","properties":{"click_tracking":{"type":"boolean","description":"Rewrite links to redirect through the tracking subdomain and record email.clicked events. Off by default."},"open_tracking":{"type":"boolean","description":"Inject a tracking pixel served from the tracking subdomain and record email.opened events. Off by default."},"tracking_subdomain":{"type":["string","null"],"description":"DNS label of the branded tracking host, e.g. \"links\" for links.<domain>. Setting it adds a Tracking CNAME to records[]; links are tracked through it once that CNAME resolves. Required on MepMail Cloud to turn tracking on. Empty string or null clears it."},"tls":{},"capabilities":{}}},"RemoveDomainResponse":{"type":"object","properties":{"object":{"type":"string","enum":["domain"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]},"CreateApiKeyResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"token":{"type":"string"}},"required":["id","token"]},"CreateApiKeyRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"permission":{"type":"string","enum":["full_access","sending_access"],"default":"full_access"},"domain_id":{"type":["string","null"],"format":"uuid"}},"required":["name"]},"ListApiKeysResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]}},"required":["id","name","created_at","last_used_at"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"RemoveApiKeyResponse":{"type":"object","properties":{"object":{"type":"string","enum":["api_key"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]},"CreateWebhookResponse":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string","format":"uuid"},"signing_secret":{"type":"string"}},"required":["object","id","signing_secret"]},"CreateWebhookRequest":{"type":"object","properties":{"endpoint":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["email.sent","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.prefetched","deliverability.warning","deliverability.paused","quota.warning","quota.reached","quota.paused","contact.created","contact.updated","contact.deleted","contact.unsubscribed","contact.resubscribed","contact.topic_opt_in","contact.topic_opt_out","suppression.added","suppression.removed","mailbox.received"]},"minItems":1},"signing_secret":{"type":"string","description":"Signing secret to use instead of minting one: whsec_ followed by base64 of 24-64 bytes, the format Resend/Svix issue. Carry over an existing secret so the receiver keeps verifying unchanged; omit to generate a new one."}},"required":["endpoint","events"]},"ListWebhooksResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpoint":{"type":"string"},"created_at":{"type":"string"},"status":{"type":"string","enum":["enabled","disabled"]},"events":{"type":["array","null"],"items":{"type":"string"}}},"required":["id","endpoint","created_at","status","events"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"GetWebhookResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpoint":{"type":"string"},"created_at":{"type":"string"},"status":{"type":"string","enum":["enabled","disabled"]},"events":{"type":["array","null"],"items":{"type":"string"}},"object":{"type":"string","enum":["webhook"]},"signing_secret":{"type":"string"},"previous_secret_expires_at":{"type":["string","null"],"description":"While set, deliveries are also signed with the secret this one replaced (a rotation's overlap window)"}},"required":["id","endpoint","created_at","status","events","object","signing_secret","previous_secret_expires_at"]},"RotateWebhookSecretResponse":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string","format":"uuid"},"signing_secret":{"type":"string"},"previous_secret_expires_at":{"type":["string","null"]}},"required":["object","id","signing_secret","previous_secret_expires_at"]},"RotateWebhookSecretRequest":{"type":"object","properties":{"signing_secret":{"type":"string","description":"New secret to sign with: whsec_ followed by base64 of 24-64 bytes. Omit to mint one."},"overlap_hours":{"type":"integer","minimum":0,"maximum":72,"description":"Hours the previous secret keeps signing alongside the new one (default 24, max 72). Every delivery in the window carries both signatures, so a receiver holding either verifies; 0 drops the old secret at once."}}},"WebhookIdResponse":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"]},"UpdateWebhookRequest":{"type":"object","properties":{"endpoint":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["email.sent","email.delivered","email.delivery_delayed","email.bounced","email.complained","email.opened","email.clicked","email.prefetched","deliverability.warning","deliverability.paused","quota.warning","quota.reached","quota.paused","contact.created","contact.updated","contact.deleted","contact.unsubscribed","contact.resubscribed","contact.topic_opt_in","contact.topic_opt_out","suppression.added","suppression.removed","mailbox.received"]},"minItems":1},"status":{"type":"string","enum":["enabled","disabled"]}}},"RemoveWebhookResponse":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]},"BatchAddSuppressionsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SuppressionIdResponse"}}},"required":["data"]},"SuppressionIdResponse":{"type":"object","properties":{"object":{"type":"string","enum":["suppression"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"]},"BatchAddSuppressionsRequest":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string","format":"email"},"minItems":1,"maxItems":1000,"description":"Addresses to block, up to 1000; duplicates collapse"},"origin":{"type":"string","enum":["bounce","complaint","manual","unsubscribe"],"description":"Origin recorded on rows this request creates (default manual): bounce, complaint, manual or unsubscribe; an address already suppressed keeps its origin"}},"required":["emails"]},"BatchRemoveSuppressionsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RemoveSuppressionResponse"}}},"required":["data"]},"RemoveSuppressionResponse":{"type":"object","properties":{"object":{"type":"string","enum":["suppression"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]},"BatchRemoveSuppressionsRequest":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string","format":"email"},"minItems":1,"maxItems":1000,"description":"Addresses to unblock, up to 1000"},"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"description":"Suppression ids to remove, up to 1000"}}},"CreateSuppressionRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Bare email address to block; stored normalized (lowercase)"},"origin":{"type":"string","enum":["bounce","complaint","manual","unsubscribe"],"description":"Origin recorded on rows this request creates (default manual): bounce, complaint, manual or unsubscribe; an address already suppressed keeps its origin"}},"required":["email"]},"ListSuppressionsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"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","description":"Email id whose bounce/complaint created the entry"},"created_at":{"type":"string"}},"required":["id","email","origin","source_id","created_at"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"GetSuppressionResponse":{"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","description":"Email id whose bounce/complaint created the entry"},"created_at":{"type":"string"},"object":{"type":"string","enum":["suppression"]}},"required":["id","email","origin","source_id","created_at","object"]},"TemplateIdResponse":{"type":"object","properties":{"object":{"type":"string","enum":["template"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"]},"CreateTemplateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"subject":{"type":["string","null"],"maxLength":998,"description":"\"\" or null clears the subject"},"html":{"type":"string","minLength":1,"maxLength":500000,"description":"Stored as sent; the dashboard sanitizes at render"},"text":{"type":["string","null"],"maxLength":500000,"description":"\"\" or null clears the text part"},"alias":{"type":["string","null"],"minLength":1,"maxLength":100,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","description":"Case-sensitive handle, unique per team; GET /templates/{alias} resolves it"},"from":{"type":["string","null"],"description":"Not supported yet: any value is a 422"},"reply_to":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Not supported yet: any value is a 422"},"variables":{"type":"array","items":{},"description":"Not supported yet: a non-empty list is a 422"}},"required":["name","html"]},"ListTemplatesResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"alias":{"type":["string","null"]},"status":{"type":"string","enum":["published"]},"published_at":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","alias","status","published_at","created_at","updated_at"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"GetTemplateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"alias":{"type":["string","null"]},"status":{"type":"string","enum":["published"]},"published_at":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"object":{"type":"string","enum":["template"]},"current_version_id":{"type":"string","format":"uuid"},"from":{"type":"null"},"subject":{"type":["string","null"]},"reply_to":{"type":"null"},"html":{"type":"string"},"text":{"type":["string","null"]},"variables":{"type":"array","items":{},"description":"Always empty"},"has_unpublished_versions":{"type":"boolean","enum":[false]}},"required":["id","name","alias","status","published_at","created_at","updated_at","object","current_version_id","from","subject","reply_to","html","text","variables","has_unpublished_versions"]},"UpdateTemplateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"subject":{"type":["string","null"],"maxLength":998,"description":"\"\" or null clears the subject"},"html":{"type":"string","minLength":1,"maxLength":500000},"text":{"type":["string","null"],"maxLength":500000},"alias":{"type":["string","null"],"minLength":1,"maxLength":100,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","description":"null clears the alias"},"from":{"type":["string","null"],"description":"Not supported yet: any value is a 422"},"reply_to":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Not supported yet: any value is a 422"},"variables":{"type":"array","items":{},"description":"Not supported yet: a non-empty list is a 422"}}},"RemoveTemplateResponse":{"type":"object","properties":{"object":{"type":"string","enum":["template"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]},"UsageResponse":{"type":"object","properties":{"object":{"type":"string","enum":["usage"]},"cloud":{"type":"boolean","description":"True on MepMail Cloud, where plan limits apply"},"plan":{"type":["string","null"],"enum":["free","starter","pro","scale",null],"description":"Effective plan; null self-hosted or on the instance's own (system) team"},"limits":{"type":"object","properties":{"emails_per_day":{"type":["integer","null"],"description":"Daily cap (UTC day) on Free and Starter; null on monthly plans and self-hosted"},"emails_per_month":{"type":["integer","null"],"description":"Emails included per billing period on Pro and Scale; null on daily plans and self-hosted"},"domains":{"type":["integer","null"],"description":"null = unlimited or self-hosted"},"contacts":{"type":["integer","null"],"description":"Contacts the team may hold; null = unlimited or self-hosted"}},"required":["emails_per_day","emails_per_month","domains","contacts"]},"today":{"type":"object","properties":{"emails_sent":{"type":"integer","description":"Emails accepted so far this UTC day"},"resets_at":{"type":"string","description":"Next UTC midnight, when the daily counter resets"}},"required":["emails_sent","resets_at"]},"period":{"type":["object","null"],"properties":{"emails_sent":{"type":"integer","description":"Emails accepted so far this billing period"},"included":{"type":"integer","description":"Emails the plan includes per period"},"overage_enabled":{"type":"boolean","description":"Whether sends past `included` bill overage instead of being refused"},"overage_usd_per_1k":{"type":"number","description":"Overage price per 1,000 emails, in USD"},"starts_at":{"type":"string","description":"Billing period start"},"ends_at":{"type":"string","description":"Billing period end, when the counter resets"}},"required":["emails_sent","included","overage_enabled","overage_usd_per_1k","starts_at","ends_at"],"description":"Billing-period usage on monthly plans; null on daily plans and self-hosted"},"team":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"]},"app_url":{"type":["string","null"],"description":"Dashboard origin, for building links; null when unset"}},"required":["object","cloud","plan","limits","today","period","team","app_url"]},"UsageTermsUnavailable":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"type":"object","properties":{"usage":{"type":"object","properties":{"today":{"type":"object","properties":{"emails_sent":{"type":"integer","description":"Emails accepted so far this UTC day"},"resets_at":{"type":"string","description":"Next UTC midnight, when the daily counter resets"}},"required":["emails_sent","resets_at"]},"period":{"type":["object","null"],"properties":{"emails_sent":{"type":"integer"},"included":{"type":"integer"},"overage_enabled":{"type":"boolean"},"starts_at":{"type":"string"},"ends_at":{"type":"string"}},"required":["emails_sent","included","overage_enabled","starts_at","ends_at"]}},"required":["today","period"]}},"required":["usage"]}]},"SendEmailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]},"SendEmailRequest":{"type":"object","properties":{"from":{"type":"string","description":"Sender, \"Name <user@domain>\" or bare address; the domain must be verified for the team","example":"Acme <onboarding@acme.dev>"},"to":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}],"description":"Recipient address or list of up to 50","example":["delivered@resend.dev"]},"subject":{"type":"string","minLength":1,"description":"Subject line"},"html":{"type":"string","description":"HTML body; at least one of html/text is required"},"text":{"type":"string","description":"Plain-text body; at least one of html/text is required"},"cc":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}],"description":"Cc address or list"},"bcc":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}],"description":"Bcc address or list"},"reply_to":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}],"description":"Reply-To address or list"},"scheduled_at":{"type":"string","description":"Deliver later: ISO 8601 with offset, or relative like \"in 2 hours\" (an ISO 8601 datetime with offset (e.g. \"2026-09-01T12:00:00Z\") or a relative time like \"in 5 mins\", \"in 2 hours\", or \"in 1 day\"); max 30 days ahead"},"tags":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1},"value":{"type":"string"}},"required":["name","value"]},"description":"Key/value labels attached to the email for filtering"},"topic_id":{"type":["string","null"],"format":"uuid","description":"Topic id: recipients opted out of the topic are skipped and an unsubscribe link is added"},"attachments":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string","minLength":1},"content":{"type":"string"},"content_type":{"type":"string"},"content_id":{"type":"string"},"path":{"type":"string"}},"required":["filename"]},"description":"Attachments with base64 content (no remote paths)"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Extra message headers (transport headers are rejected)"},"template":{"description":"Not supported yet: any value is a 422. Send html/text instead"}},"required":["from","to","subject"]},"BatchEmailResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}},"errors":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"message":{"type":"string"}},"required":["index","message"]}}},"required":["data"]},"BatchEmailRequest":{"type":"array","items":{},"minItems":1,"maxItems":100},"CancelEmailResponse":{"type":"object","properties":{"object":{"type":"string","enum":["email"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"]},"UpdateEmailResponse":{"type":"object","properties":{"object":{"type":"string","enum":["email"]},"id":{"type":"string","format":"uuid"}},"required":["object","id"]},"UpdateEmailRequest":{"type":"object","properties":{"scheduled_at":{"type":"string"}},"required":["scheduled_at"]},"GetEmailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"from":{"type":"string"},"to":{"type":"array","items":{"type":"string"}},"cc":{"type":["array","null"],"items":{"type":"string"}},"bcc":{"type":["array","null"],"items":{"type":"string"}},"reply_to":{"type":["array","null"],"items":{"type":"string"}},"subject":{"type":"string"},"created_at":{"type":"string"},"scheduled_at":{"type":["string","null"]},"last_event":{"type":"string"},"object":{"type":"string","enum":["email"]},"html":{"type":["string","null"]},"text":{"type":["string","null"]},"message_id":{"type":"string"},"score":{"type":["number","null"]}},"required":["id","from","to","cc","bcc","reply_to","subject","created_at","scheduled_at","last_event","object","html","text","message_id","score"]},"EmailInsightsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["email_insights"]},"email_id":{"type":"string","format":"uuid"},"score":{"type":"number","description":"Best-practice score, 0-10, one decimal"},"score_version":{"type":"integer"},"band":{"type":"string","enum":["excellent","good","needs_attention","at_risk"]},"marketing":{"type":"boolean"},"html_size_bytes":{"type":["integer","null"]},"computed_at":{"type":"string"},"checks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Check id from the @millionsend/core check catalog"},"severity":{"type":"string","enum":["critical","major","minor","info"]},"status":{"type":"string","enum":["pass","fail","passed_by_design","not_applicable","unknown"]},"penalty":{"type":"number","description":"Points deducted from the score; 0 unless status is fail"},"detail":{"type":"object","additionalProperties":{}}},"required":["id","severity","status","penalty"]}}},"required":["object","email_id","score","score_version","band","marketing","html_size_bytes","computed_at","checks"]},"DeliverabilityResponse":{"type":"object","properties":{"object":{"type":"string","enum":["deliverability"]},"score":{"type":["number","null"]},"band":{"type":["string","null"],"enum":["excellent","good","needs_attention","at_risk",null]},"content_score":{"type":["number","null"]},"outcome_score":{"type":["number","null"]},"complaint_rate":{"type":"number"},"hard_bounce_rate":{"type":"number"},"emails_sent":{"type":"integer"},"scored_recipients":{"type":"integer"},"window_days":{"type":"integer"},"insufficient_outcome_data":{"type":"boolean"},"guardrail_status":{"type":"string","enum":["ok","warning","paused"]},"score_version":{"type":"integer"}},"required":["object","score","band","content_score","outcome_score","complaint_rate","hard_bounce_rate","emails_sent","scored_recipients","window_days","insufficient_outcome_data","guardrail_status","score_version"]},"ListEmailsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"from":{"type":"string"},"to":{"type":"array","items":{"type":"string"}},"cc":{"type":["array","null"],"items":{"type":"string"}},"bcc":{"type":["array","null"],"items":{"type":"string"}},"reply_to":{"type":["array","null"],"items":{"type":"string"}},"subject":{"type":"string"},"created_at":{"type":"string"},"scheduled_at":{"type":["string","null"]},"last_event":{"type":"string"}},"required":["id","from","to","cc","bcc","reply_to","subject","created_at","scheduled_at","last_event"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]},"RemoveEmailResponse":{"type":"object","properties":{"object":{"type":"string","enum":["email"]},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]}},"parameters":{},"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key from the dashboard (ms_…), sent as Authorization: Bearer. A sending-only key reaches the /emails routes only."}}},"paths":{"/contacts":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactRequest"},"example":{"email":"customer@example.com","first_name":"Ana","last_name":"Silva"}}}},"responses":{"200":{"description":"Contact created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Unknown segment or topic","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Contact already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createContact","summary":"Create a contact","tags":["Contacts"],"description":"Creates a contact with its properties, topic subscriptions and segments."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"},{"schema":{"type":"string","description":"MepMail extension: comma-separated facets attached to every item — `properties` (the {type, value} map GET /contacts/{id} returns) and `topics` (the rows GET /contacts/{id}/topics returns). Omitted, each item has the Resend shape."},"required":false,"description":"MepMail extension: comma-separated facets attached to every item — `properties` (the {type, value} map GET /contacts/{id} returns) and `topics` (the rows GET /contacts/{id}/topics returns). Omitted, each item has the Resend shape.","name":"include","in":"query"}],"responses":{"200":{"description":"Contacts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listContacts","summary":"List contacts","tags":["Contacts"],"description":"Lists the team's contacts one page at a time."}},"/contacts/batch/get":{"post":{"summary":"Read contacts in bulk","description":"MepMail extension: returns up to 1000 contacts by id or by email address in one request, in request order, optionally with their properties and topic subscriptions. Entries that match no contact are listed under `missing` instead of failing the call. One call counts as one request against the rate limit.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchGetContactsRequest"}}}},"responses":{"200":{"description":"The contacts found, and the entries that matched none","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchGetContactsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getContactsBatch","tags":["Contacts"]}},"/contacts/batch/remove":{"post":{"summary":"Delete contacts in bulk","description":"MepMail extension (Resend deletes contacts one at a time): deletes up to 1000 contacts by id or by email address in one request and lists the rows actually deleted; unknown ids or addresses are skipped. Emails stay in the log; `erase: true` also scrubs each address from email history, event payloads and API logs, like DELETE /contacts/{id}?erase=true.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRemoveContactsRequest"}}}},"responses":{"200":{"description":"The contacts that were deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRemoveContactsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"removeContactsBatch","tags":["Contacts"]}},"/contacts/batch":{"post":{"summary":"Create contacts in bulk","description":"MepMail extension: creates up to 1000 contacts in one request (Resend imports contacts only via CSV). Each item is a CreateContactRequest. `on_conflict` decides what happens to an email that already belongs to a contact — `error` (default), `skip`, or `upsert`. An upsert updates `first_name`/`last_name` only when provided, merges `properties` (provided keys overwrite), adds `segments` and upserts `topics`. `unsubscribed: true` opts the contact out; `unsubscribed: false` on an already unsubscribed contact is ignored — a batch never re-subscribes anyone, that stays an explicit PATCH /contacts/{id}. The `x-batch-validation` header picks strict (default, all-or-nothing) or permissive (valid subset written, failures listed in `errors`).","parameters":[{"schema":{"type":"string","enum":["error","skip","upsert"],"default":"error","description":"What to do with an item whose email (case-insensitive) already belongs to a contact: `error` fails the item, `skip` leaves the contact untouched and reports its id, `upsert` merges the item into it. Also decides how an email repeated inside the batch is handled: `error` fails the later occurrence, `skip` keeps the first, `upsert` collapses them into one write (later scalar fields win, associations are unioned)."},"required":false,"description":"What to do with an item whose email (case-insensitive) already belongs to a contact: `error` fails the item, `skip` leaves the contact untouched and reports its id, `upsert` merges the item into it. Also decides how an email repeated inside the batch is handled: `error` fails the later occurrence, `skip` keeps the first, `upsert` collapses them into one write (later scalar fields win, associations are unioned).","name":"on_conflict","in":"query"},{"schema":{"type":"string","enum":["strict","permissive"],"description":"`strict` (default): any invalid item rejects the whole batch with that item's status and a `contacts.{index}: ` message prefix, writing nothing. `permissive`: invalid items are listed in `errors` and the valid subset is written."},"required":false,"description":"`strict` (default): any invalid item rejects the whole batch with that item's status and a `contacts.{index}: ` message prefix, writing nothing. `permissive`: invalid items are listed in `errors` and the valid subset is written.","name":"x-batch-validation","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchContactsRequest"}}}},"responses":{"200":{"description":"Batch processed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchContactsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan limit reached (strict mode)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Unknown segment or topic (strict mode)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Contact already exists (strict mode, on_conflict=error)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createContactsBatch","tags":["Contacts"]}},"/contacts/{id}":{"get":{"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Contact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getContact","summary":"Retrieve a contact","tags":["Contacts"],"description":"Returns one contact by id or email address, with its properties."},"patch":{"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactRequest"}}}},"responses":{"200":{"description":"Contact updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateContact","summary":"Update a contact","tags":["Contacts"],"description":"Updates a contact's name, properties or unsubscribed flag."},"delete":{"description":"Deletes the contact and its segment memberships. Its emails stay in the log; pass `erase=true` to also scrub the address from email history, event payloads and API logs.","parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["true","false"],"description":"MepMail extension. `true` also erases the address from email history, event payloads and API logs (a GDPR/LGPD erasure); by default the send log is kept and ages out with the team's retention window"},"required":false,"description":"MepMail extension. `true` also erases the address from email history, event payloads and API logs (a GDPR/LGPD erasure); by default the send log is kept and ages out with the team's retention window","name":"erase","in":"query"}],"responses":{"200":{"description":"Contact deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveContactResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteContact","summary":"Delete a contact","tags":["Contacts"]}},"/contacts/{id}/preferences-link":{"post":{"summary":"Mint a preference-center link for a contact","description":"MepMail extension. Returns the contact's hosted preferences URL, the same page the unsubscribe links in their emails open, so a product settings screen can deep-link into it. The page lists the team's public topics and carries the global unsubscribe. The link is a signed, contact-scoped capability with no expiry: anyone holding it can change that contact's preferences, so hand it only to the contact.","parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The contact's preference page URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactPreferencesLinkResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"APP_BASE_URL or the encryption key is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createContactPreferencesLink","tags":["Contacts"]}},"/contacts/{id}/topics":{"get":{"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Every topic of the team with the contact's effective subscription and whether it was chosen explicitly","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactTopicsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listContactTopics","summary":"List a contact's topics","tags":["Contacts"],"description":"Lists every topic of the team with the contact's effective subscription."},"patch":{"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactTopicsRequest"}}}},"responses":{"200":{"description":"Contact topic subscriptions updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactTopicsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateContactTopics","summary":"Update a contact's topics","tags":["Contacts"],"description":"Opts a contact in or out of topics."}},"/contacts/{id}/segments/{segmentId}":{"post":{"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"segmentId","in":"path"}],"responses":{"200":{"description":"Contact added to the segment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddContactSegmentResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"addContactToSegment","summary":"Add a contact to a segment","tags":["Contacts"],"description":"Adds a contact to a static segment."},"delete":{"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"segmentId","in":"path"}],"responses":{"200":{"description":"Contact removed from the segment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveContactSegmentResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"removeContactFromSegment","summary":"Remove a contact from a segment","tags":["Contacts"],"description":"Removes a contact from a static segment."}},"/audiences/{audienceId}/contacts":{"post":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"audienceId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactRequest"}}}},"responses":{"200":{"description":"Contact created in the audience","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Contact already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createAudienceContact","summary":"Create a contact in an audience","tags":["Audiences"],"description":"Resend-compatible route: creates a contact under an audience id."}},"/audiences/{audienceId}/contacts/{id}":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"audienceId","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Contact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getAudienceContact","summary":"Retrieve a contact in an audience","tags":["Audiences"],"description":"Resend-compatible route: returns a contact under an audience id."},"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"audienceId","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactRequest"}}}},"responses":{"200":{"description":"Contact updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateAudienceContact","summary":"Update a contact in an audience","tags":["Audiences"],"description":"Resend-compatible route: updates a contact under an audience id."},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"audienceId","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["true","false"],"description":"MepMail extension. `true` also erases the address from email history, event payloads and API logs (a GDPR/LGPD erasure); by default the send log is kept and ages out with the team's retention window"},"required":false,"description":"MepMail extension. `true` also erases the address from email history, event payloads and API logs (a GDPR/LGPD erasure); by default the send log is kept and ages out with the team's retention window","name":"erase","in":"query"}],"responses":{"200":{"description":"Contact deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveContactResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteAudienceContact","summary":"Delete a contact in an audience","tags":["Audiences"],"description":"Resend-compatible route: deletes a contact under an audience id."}},"/contact-properties":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactPropertyRequest"}}}},"responses":{"200":{"description":"Contact property created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactPropertyResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Property already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createContactProperty","summary":"Create a contact property","tags":["Contact properties"],"description":"Defines a custom field that every contact can carry."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"}],"responses":{"200":{"description":"Contact properties","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactPropertiesResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listContactProperties","summary":"List contact properties","tags":["Contact properties"],"description":"Lists the team's custom contact fields."}},"/contact-properties/{id}":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Contact property","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactPropertyResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getContactProperty","summary":"Retrieve a contact property","tags":["Contact properties"],"description":"Returns one custom contact field."},"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactPropertyRequest"}}}},"responses":{"200":{"description":"Contact property updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactPropertyIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateContactProperty","summary":"Update a contact property","tags":["Contact properties"],"description":"Renames a custom contact field or changes its fallback value."},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Contact property deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveContactPropertyResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteContactProperty","summary":"Delete a contact property","tags":["Contact properties"],"description":"Deletes a custom contact field and its values."}},"/segments":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSegmentRequest"}}}},"responses":{"200":{"description":"Segment created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createSegment","summary":"Create a segment","tags":["Segments"],"description":"Creates a segment of contacts for broadcasts."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"}],"responses":{"200":{"description":"Segments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSegmentsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listSegments","summary":"List segments","tags":["Segments"],"description":"Lists the team's segments."}},"/segments/{id}":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Segment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSegmentResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getSegment","summary":"Retrieve a segment","tags":["Segments"],"description":"Returns one segment and its filter."},"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSegmentRequest"}}}},"responses":{"200":{"description":"Segment updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SegmentResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateSegment","summary":"Update a segment","tags":["Segments"],"description":"Renames a segment or changes its filter."},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Segment deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveSegmentResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Segment is in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteSegment","summary":"Delete a segment","tags":["Segments"],"description":"Deletes a segment; its contacts stay."}},"/segments/{id}/contacts":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"},{"schema":{"type":"string","description":"MepMail extension: comma-separated facets attached to every item — `properties` (the {type, value} map GET /contacts/{id} returns) and `topics` (the rows GET /contacts/{id}/topics returns). Omitted, each item has the Resend shape."},"required":false,"description":"MepMail extension: comma-separated facets attached to every item — `properties` (the {type, value} map GET /contacts/{id} returns) and `topics` (the rows GET /contacts/{id}/topics returns). Omitted, each item has the Resend shape.","name":"include","in":"query"}],"responses":{"200":{"description":"Contacts the segment resolves to","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listSegmentContacts","summary":"List a segment's contacts","tags":["Segments"],"description":"Lists the contacts a segment resolves to right now."}},"/broadcasts":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBroadcastRequest"}}}},"responses":{"200":{"description":"Broadcast created (and scheduled when send: true)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBroadcastResponse"}}}},"400":{"description":"Broadcast state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key or sending paused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createBroadcast","summary":"Create a broadcast","tags":["Broadcasts"],"description":"Creates a broadcast to a segment, and schedules it when send is true."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"}],"responses":{"200":{"description":"Broadcasts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBroadcastsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listBroadcasts","summary":"List broadcasts","tags":["Broadcasts"],"description":"Lists the team's broadcasts."}},"/broadcasts/{id}":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Broadcast","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBroadcastResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getBroadcast","summary":"Retrieve a broadcast","tags":["Broadcasts"],"description":"Returns one broadcast with its status and counts."},"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBroadcastRequest"}}}},"responses":{"200":{"description":"Broadcast updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastIdResponse"}}}},"400":{"description":"Not a draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateBroadcast","summary":"Update a broadcast","tags":["Broadcasts"],"description":"Changes a draft broadcast before it is sent."},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Broadcast deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveBroadcastResponse"}}}},"400":{"description":"Not a draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteBroadcast","summary":"Delete a broadcast","tags":["Broadcasts"],"description":"Deletes a draft broadcast."}},"/broadcasts/{id}/send":{"post":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBroadcastRequest"}}}},"responses":{"200":{"description":"Broadcast scheduled; finishes_at and warning say when it goes out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBroadcastResponse"}}}},"400":{"description":"Not a draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Sending paused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"sendBroadcast","summary":"Send a broadcast","tags":["Broadcasts"],"description":"Schedules a broadcast now or at a later time."}},"/broadcasts/{id}/cancel":{"post":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Broadcast canceled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelBroadcastResponse"}}}},"400":{"description":"Not queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"cancelBroadcast","summary":"Cancel a broadcast","tags":["Broadcasts"],"description":"Cancels a scheduled broadcast before it goes out."}},"/topics":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTopicRequest"}}}},"responses":{"200":{"description":"Topic created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopicResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createTopic","summary":"Create a topic","tags":["Topics"],"description":"Creates a subscription topic with its default opt-in."},"get":{"responses":{"200":{"description":"Topics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTopicsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listTopics","summary":"List topics","tags":["Topics"],"description":"Lists the team's topics."}},"/topics/{id}":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Topic","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopicResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getTopic","summary":"Retrieve a topic","tags":["Topics"],"description":"Returns one topic."},"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTopicRequest"}}}},"responses":{"200":{"description":"Topic updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopicIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateTopic","summary":"Update a topic","tags":["Topics"],"description":"Renames a topic or changes its description or visibility."},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Topic deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveTopicResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Topic is in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteTopic","summary":"Delete a topic","tags":["Topics"],"description":"Deletes a topic."}},"/domains":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDomainRequest"},"example":{"name":"mail.yourdomain.com"}}}},"responses":{"200":{"description":"Domain created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDomainResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan domain limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Domain already added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many domains created recently, or the rate limit was exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}}},"operationId":"createDomain","summary":"Add a domain","tags":["Domains"],"description":"Adds a sending domain and returns the DNS records to publish."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"}],"responses":{"200":{"description":"Domains","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDomainsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listDomains","summary":"List domains","tags":["Domains"],"description":"Lists the team's domains."}},"/domains/{id}":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Domain with its DNS records","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDomainResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getDomain","summary":"Retrieve a domain","tags":["Domains"],"description":"Returns one domain with its DNS records and their status."},"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDomainRequest"}}}},"responses":{"200":{"description":"Domain updated; full object with records","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDomainResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateDomain","summary":"Update a domain","tags":["Domains"],"description":"Changes a domain's click and open tracking or TLS policy."},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Domain deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveDomainResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteDomain","summary":"Delete a domain","tags":["Domains"],"description":"Removes a sending domain from the team."}},"/domains/{id}/verify":{"post":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Verification result: the domain with per-record status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDomainResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"verifyDomain","summary":"Verify a domain","tags":["Domains"],"description":"Checks the domain's DNS records now and returns each record's status."}},"/api-keys":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}}},"responses":{"200":{"description":"API key created; the token is returned only here","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Account review restricts key creation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createApiKey","summary":"Create an API key","tags":["API keys"],"description":"Creates an API key; the token is returned only in this response."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"}],"responses":{"200":{"description":"API keys (never tokens)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListApiKeysResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listApiKeys","summary":"List API keys","tags":["API keys"],"description":"Lists the team's active API keys, never their tokens."}},"/api-keys/{id}":{"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"API key revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveApiKeyResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteApiKey","summary":"Revoke an API key","tags":["API keys"],"description":"Revokes an API key at once."}},"/webhooks":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"200":{"description":"Webhook created; signing_secret is also retrievable via GET /webhooks/{id}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createWebhook","summary":"Create a webhook","tags":["Webhooks"],"description":"Registers an endpoint for the chosen events and returns its signing secret."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"}],"responses":{"200":{"description":"Webhooks (list rows never carry the signing secret)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWebhooksResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listWebhooks","summary":"List webhooks","tags":["Webhooks"],"description":"Lists the team's webhooks."}},"/webhooks/{id}":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Webhook, including its signing secret","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetWebhookResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getWebhook","summary":"Retrieve a webhook","tags":["Webhooks"],"description":"Returns one webhook, including its signing secret."},"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookRequest"}}}},"responses":{"200":{"description":"Webhook updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateWebhook","summary":"Update a webhook","tags":["Webhooks"],"description":"Changes a webhook's endpoint, events or status."},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Webhook deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveWebhookResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteWebhook","summary":"Delete a webhook","tags":["Webhooks"],"description":"Deletes a webhook; nothing is delivered to it afterwards."}},"/webhooks/{id}/rotate":{"post":{"summary":"Rotate a webhook's signing secret","description":"MepMail extension. Mints a new signing secret (or takes the one in signing_secret) and returns it. For overlap_hours the previous secret keeps signing too: every delivery in that window carries both signatures, space-separated in webhook-signature, so the receiver can switch at any point without a gap. A second rotation inside the window replaces the previous secret.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateWebhookSecretRequest"}}}},"responses":{"200":{"description":"The new secret and when the previous one stops signing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateWebhookSecretResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"rotateWebhookSecret","tags":["Webhooks"]}},"/suppressions/batch/add":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAddSuppressionsRequest"}}}},"responses":{"200":{"description":"One entry per distinct address (case-insensitive) in input order; addresses already suppressed for any reason return their existing id and keep their origin. New rows record the request's origin (bounce, complaint, manual or unsubscribe; default manual). Accepts up to 1000 addresses (Resend: 100).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAddSuppressionsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"addSuppressionsBatch","summary":"Suppress addresses in bulk","tags":["Suppressions"],"description":"Blocks up to 1,000 addresses in one request."}},"/suppressions/batch/remove":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRemoveSuppressionsRequest"}}}},"responses":{"200":{"description":"Exactly one of emails or ids (up to 1000 each); lists only the rows actually removed. Rows whose address was erased (GDPR/LGPD) keep blocking sends but are hidden from the list and from lookups by email; they are reachable by id only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRemoveSuppressionsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"removeSuppressionsBatch","summary":"Remove suppressions in bulk","tags":["Suppressions"],"description":"Unblocks up to 1,000 addresses or ids in one request."}},"/suppressions":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSuppressionRequest"}}}},"responses":{"200":{"description":"Address blocked with the given origin (bounce, complaint, manual or unsubscribe; default manual). Idempotent: an address already suppressed for any reason (bounce, complaint, unsubscribe, manual) keeps its entry and origin, and its existing id is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createSuppression","summary":"Suppress an address","tags":["Suppressions"],"description":"Blocks sending to one address."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"},{"schema":{"type":"string","enum":["bounce","complaint","manual","unsubscribe"],"description":"Only suppressions of this origin: bounce, complaint, manual or unsubscribe"},"required":false,"description":"Only suppressions of this origin: bounce, complaint, manual or unsubscribe","name":"origin","in":"query"}],"responses":{"200":{"description":"Suppressions, optionally filtered by origin (bounce, complaint, manual, or the superset value unsubscribe for retained one-click opt-outs). Rows whose address was erased (GDPR/LGPD) keep blocking sends but are hidden from the list and from lookups by email; they are reachable by id only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSuppressionsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listSuppressions","summary":"List suppressions","tags":["Suppressions"],"description":"Lists suppressed addresses, optionally by origin."}},"/suppressions/{id}":{"get":{"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Suppression by id or by email address. Rows whose address was erased (GDPR/LGPD) keep blocking sends but are hidden from the list and from lookups by email; they are reachable by id only. An erased row reports \"[erased]\" as its email.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSuppressionResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getSuppression","summary":"Retrieve a suppression","tags":["Suppressions"],"description":"Returns one suppression by id or email address."},"delete":{"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Suppression removed, by id or by email address; the address can receive mail again. Rows whose address was erased (GDPR/LGPD) keep blocking sends but are hidden from the list and from lookups by email; they are reachable by id only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveSuppressionResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteSuppression","summary":"Remove a suppression","tags":["Suppressions"],"description":"Unblocks one address so it can receive mail again."}},"/templates":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateRequest"}}}},"responses":{"200":{"description":"Template created. Templates have no draft/publish cycle: every save is live, so status is always published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Alias already in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error, including from/reply_to/variables (not supported yet)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createTemplate","summary":"Create a template","tags":["Templates"],"description":"Creates a reusable email template; every save is live."},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"}],"responses":{"200":{"description":"Templates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTemplatesResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listTemplates","summary":"List templates","tags":["Templates"],"description":"Lists the team's templates."}},"/templates/{id}":{"get":{"parameters":[{"schema":{"type":"string","minLength":1,"description":"Template id or alias"},"required":true,"description":"Template id or alias","name":"id","in":"path"}],"responses":{"200":{"description":"Template by id or alias. Templates have no draft/publish cycle: every save is live, so status is always published. from, reply_to and variables are not supported yet and read as null, null and [].","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTemplateResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getTemplate","summary":"Retrieve a template","tags":["Templates"],"description":"Returns one template by id or alias."},"patch":{"parameters":[{"schema":{"type":"string","minLength":1,"description":"Template id or alias"},"required":true,"description":"Template id or alias","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTemplateRequest"}}}},"responses":{"200":{"description":"Template updated (live immediately)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Alias already in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error, including from/reply_to/variables (not supported yet)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateTemplate","summary":"Update a template","tags":["Templates"],"description":"Changes a template; the change is live immediately."},"delete":{"parameters":[{"schema":{"type":"string","minLength":1,"description":"Template id or alias"},"required":true,"description":"Template id or alias","name":"id","in":"path"}],"responses":{"200":{"description":"Template deleted. Broadcasts keep their own copy of the content.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveTemplateResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteTemplate","summary":"Delete a template","tags":["Templates"],"description":"Deletes a template; broadcasts keep their own copy."}},"/templates/{id}/publish":{"post":{"parameters":[{"schema":{"type":"string","minLength":1,"description":"Template id or alias"},"required":true,"description":"Template id or alias","name":"id","in":"path"}],"responses":{"200":{"description":"No-op kept for SDK compatibility. Templates have no draft/publish cycle: every save is live, so status is always published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"publishTemplate","summary":"Publish a template","tags":["Templates"],"description":"Kept for SDK compatibility: templates are always published."}},"/templates/{id}/duplicate":{"post":{"parameters":[{"schema":{"type":"string","minLength":1,"description":"Template id or alias"},"required":true,"description":"Template id or alias","name":"id","in":"path"}],"responses":{"200":{"description":"Copy named \"<name> (copy)\" with no alias; returns the new template id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateIdResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"duplicateTemplate","summary":"Duplicate a template","tags":["Templates"],"description":"Copies a template under a new id."}},"/usage":{"get":{"responses":{"200":{"description":"Effective plan and usage limits. Annual Send contracts renew their 110K allowance monthly within the paid year; overage is disabled and its numeric rate is zero. MepMail extension; plan, limits and period are null on self-hosted and system teams.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Contract terms or bindings unavailable. Counters remain under usage; period is null when no monthly allowance is verified. No estimated or null overage rate is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageTermsUnavailable"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getUsage","summary":"Get plan and usage","tags":["Account"],"description":"Returns the team's plan, limits and usage in the current period."}},"/emails":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailRequest"},"example":{"from":"Acme <hello@yourdomain.com>","to":["customer@example.com"],"subject":"Your order has shipped","html":"<p>Your order is on its way.</p>"}}}},"responses":{"200":{"description":"Email accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailResponse"},"example":{"id":"4ef9a417-02e9-4d39-ad75-9611e0fcc33c"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Sending quota exceeded, or the rate limit was exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}}},"operationId":"sendEmail","summary":"Send an email","tags":["Emails"],"description":"Queues one email for delivery, now or at scheduled_at, from a verified domain of the team.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional retry key, scoped to the team across single and batch sends for 24 hours from the initial claim. The same key and canonical payload replay the original email ids; a different payload returns 409 invalid_idempotent_request and a request still processing returns 409 concurrent_idempotent_requests. An incomplete claim can be recovered after 10 minutes. After expiry, the key can accept a new send. This is an HTTP header, not an email header.","schema":{"type":"string","minLength":1},"example":"order-123-confirmation"}]},"get":{"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, 1-100 (default 20)"},"required":false,"description":"Page size, 1-100 (default 20)","name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value."},"required":false,"description":"Cursor: id of the last item of the previous page. Must be an id this list returned; there is no sentinel value.","name":"after","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Cursor: id of the first item of the next page (page backwards); same rule as after."},"required":false,"description":"Cursor: id of the first item of the next page (page backwards); same rule as after.","name":"before","in":"query"}],"responses":{"200":{"description":"Emails","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListEmailsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listEmails","summary":"List emails","tags":["Emails"],"description":"Lists the team's sent and scheduled emails, newest first, one page at a time."}},"/emails/batch":{"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchEmailRequest"},"example":[{"from":"Acme <hello@yourdomain.com>","to":["customer@example.com"],"subject":"Your order has shipped","html":"<p>Your order is on its way.</p>"},{"from":"Acme <hello@yourdomain.com>","to":["another@example.com"],"subject":"Your order has shipped","html":"<p>Your order is on its way.</p>"}]}}},"responses":{"200":{"description":"Batch accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchEmailResponse"},"example":{"data":[{"id":"ae2014de-c168-4c61-8267-70d2662a1ce1"},{"id":"faccb7a5-8a28-4e9a-ac64-8da1cc3bc1cb"}]}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Sending quota exceeded, or the rate limit was exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}}},"operationId":"sendEmailBatch","summary":"Send a batch of emails","tags":["Emails"],"description":"Queues up to 100 different emails in one request; each item is a send request.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional retry key, scoped to the team across single and batch sends for 24 hours from the initial claim. The same key and canonical payload replay the original email ids; a different payload returns 409 invalid_idempotent_request and a request still processing returns 409 concurrent_idempotent_requests. An incomplete claim can be recovered after 10 minutes. After expiry, the key can accept a new send. This is an HTTP header, not an email header.","schema":{"type":"string","minLength":1},"example":"order-123-confirmation"}]}},"/emails/{id}/cancel":{"post":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Email canceled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelEmailResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Not cancelable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"cancelEmail","summary":"Cancel a scheduled email","tags":["Emails"],"description":"Cancels an email that is still scheduled, so it is never sent."}},"/emails/{id}":{"patch":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmailRequest"}}}},"responses":{"200":{"description":"Email rescheduled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmailResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Not reschedulable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateEmail","summary":"Reschedule an email","tags":["Emails"],"description":"Moves a scheduled email to a new scheduled_at before it is sent."},"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEmailResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getEmail","summary":"Retrieve an email","tags":["Emails"],"description":"Returns one email with its recipients, content and last delivery event."},"delete":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Email deleted, including its events","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveEmailResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"deleteEmail","summary":"Delete an email","tags":["Emails"],"description":"Deletes an email and its events from the log."}},"/emails/{id}/insights":{"get":{"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Best-practice check results and score computed when the email was sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailInsightsResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getEmailInsights","summary":"Get email insights","tags":["Emails"],"description":"Returns the best-practice checks and the score computed when the email was sent."}},"/deliverability":{"get":{"responses":{"200":{"description":"Account deliverability score over the trailing 30 days","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliverabilityResponse"}}}},"401":{"description":"Missing, malformed or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Restricted API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: 600 requests per minute per API key and 3,000 per team; wait for Retry-After","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getDeliverability","summary":"Get the deliverability score","tags":["Account"],"description":"Returns the account's deliverability score over the trailing 30 days."}}},"webhooks":{},"security":[{"apiKey":[]}],"tags":[{"name":"Emails","description":"Send, schedule, read and cancel emails."},{"name":"Contacts","description":"The people you send to, their topics and segments."},{"name":"Audiences","description":"Resend's audience-scoped contact routes, kept for SDK compatibility."},{"name":"Contact properties","description":"Custom fields stored on every contact."},{"name":"Segments","description":"Saved contact filters for broadcasts."},{"name":"Broadcasts","description":"One email to a whole segment."},{"name":"Topics","description":"Subscription topics contacts can opt in and out of."},{"name":"Domains","description":"Sending domains and their DNS records."},{"name":"API keys","description":"Keys that authenticate API calls."},{"name":"Webhooks","description":"Signed event deliveries to your endpoints."},{"name":"Suppressions","description":"Addresses MepMail will not send to (bounces, complaints, unsubscribes)."},{"name":"Templates","description":"Reusable email content."},{"name":"Account","description":"Plan, usage and deliverability of the team."}]}