# Sendtier > Sendtier is a transactional email API with EU data residency and transparent deliverability. ## Docs - [Authentication](https://sendtier.com/docs/authentication.md): API keys, scopes, version headers and test mode. - [Domains and DNS](https://sendtier.com/docs/domains.md): Publish six SES records and verify your sending domain. - [Errors](https://sendtier.com/docs/errors-guide.md): Read structured API errors and find their remediation pages. - [Introduction](https://sendtier.com/docs/index.md): Transactional email API hosted in AWS Frankfurt, with delivery events, signed webhooks and suppressions. - [Migrate from Postmark to Sendtier](https://sendtier.com/docs/migrate-from-postmark.md): Move a Postmark integration to Sendtier: update DNS, API calls, webhooks, and suppressions, then prepare for cut-over. - [Migrate from Resend](https://sendtier.com/docs/migrate-from-resend.md): Move a Resend HTTP integration to Sendtier. Covers DNS records, the send call, webhooks, and suppressions. - [Quickstart](https://sendtier.com/docs/quickstart.md): Submit a test email before DNS verification. Test emails are never delivered; live sending is limited during the public preview. - [Rate limits](https://sendtier.com/docs/rate-limits.md): Plan send caps, the test-mode cap, and the per-caller request rate. - [Data retention](https://sendtier.com/docs/retention.md): How long Sendtier keeps messages, events, webhook deliveries, logs, idempotency keys, and a deleted account. - [Sending](https://sendtier.com/docs/sending.md): Single sends, batches, scheduling, idempotency and tags. - [Suppressions](https://sendtier.com/docs/suppressions.md): Protect recipients from further sends after a bounce, complaint or manual block. - [Webhooks](https://sendtier.com/docs/webhooks.md): Event payloads, signature verification and delivery retries. ## API reference - [Stream changes for the selected dashboard tenant](https://sendtier.com/docs/api/getDashboardEvents.md): One server-sent events stream per dashboard tab. Select a current membership with Sendtier-Tenant; the sole membership is the default. Sendtier-Mode defaults to live and filters email events by the email's test mode. API keys receive 403. Last-Event-ID resumes email events with a two-second overlap; deduplicate by id. Without it, replay the last two minutes. Replay pages forward by created_at and id, up to five pages of 200 rows per pass; exceeding 1000 rows sends reset so the client refetches. Email hints only rewind within the last two minutes and retained history. Domain and webhook hints are not durable. Starts with retry: 3000 and a comment; comment pings arrive every 20 seconds. The stream closes after 50 minutes; reconnect with Last-Event-ID. Membership is rechecked every 60 seconds on a ping; removal closes without reset. In-process limits are five streams per user and 25 per tenant. - [Get the signed-in user and memberships](https://sendtier.com/docs/api/getMe.md): Creates the user on first use and refreshes their email from the verified token. - [Create an organization with the caller as owner](https://sendtier.com/docs/api/createOrganization.md): Call GET /me first to provision the user. No existing membership is required. Idempotency-Key is not supported because no tenant exists yet. A retry that is still under both caps creates another organization. The owned-organization cap and the 24-hour creation cap return 422 organization_limit_reached. That response has no Retry-After header. The message names the cap. The 24-hour cap message includes the UTC time when the next creation is possible. - [Export the selected organization](https://sendtier.com/docs/api/exportOrganization.md): Owner only; the path must match the selected tenant. Streams one JSON document, format version 1, without Content-Length. HTTP/1.1 uses chunked transfer. Includes live and test emails and bodies within the configured UTC-day retention window. Every array is paged. A failed stream is incomplete JSON and must be discarded. One export per tenant per ten minutes; 429 includes Retry-After in seconds. Includes pending invitations without tokens or hashes. Excludes accepted and revoked invitations, global suppressions, authentication subjects, secrets, previous webhook signing secrets, hashes, usage counters, idempotency responses, webhook delivery retries and internal notification bookkeeping. Pages are individually consistent; concurrent changes can appear between pages. - [Schedule organization deletion](https://sendtier.com/docs/api/deleteOrganization.md): Owner only; the path must match the selected tenant. Confirm the exact organization name. Revokes all API keys permanently, disables webhooks and rejects new sends, invitations, invitation acceptance and member changes immediately. Unused invitations can still be revoked. Repeating deletion preserves the original purge time. Purge starts after 30 days. - [Restore an organization during the deletion window](https://sendtier.com/docs/api/restoreOrganization.md): Owner only; the path must match the selected tenant. Available strictly before the purge time. Restores sending and previously active webhooks; revoked API keys must be replaced. Restoring an active organization succeeds. Pending webhook deliveries resume. - [List members of the selected organization](https://sendtier.com/docs/api/listOrganizationMembers.md): The path must match the selected tenant. With multiple memberships, send Sendtier-Tenant. - [Invite a teammate](https://sendtier.com/docs/api/createInvitation.md): Owners and admins may invite; admins cannot invite owners. The path must match the selected membership. One pending invitation per normalized email; expires in seven days. At most 20 invitations per tenant in a rolling hour. The token is delivered by system email and never returned by this API. - [List pending invitations](https://sendtier.com/docs/api/listInvitations.md): Owners and admins only; the path must match the selected membership. Expired invitations are omitted. - [Revoke a pending invitation](https://sendtier.com/docs/api/revokeInvitation.md): Owners and admins only; the path must match the selected membership. - [Preview an invitation](https://sendtier.com/docs/api/previewInvitation.md): Requires a dashboard token. No selected membership is required. Returns the organization name, role, expiry, whether the signed-in email matches the invitation, and whether this user already accepted it. The response never includes the token. It never includes the invited address, including when the emails differ. Expired, revoked, used by someone else, unknown tokens, and an invitation whose accepting user no longer has a membership all return not_found with the same error. The user who already accepted and still has a membership receives this preview with already_accepted true, including after expiry. Any other caller still receives not_found, so the used state is not disclosed to them. An organization pending deletion returns the same error as acceptance. The dashboard user request limiter applies per user. - [Join an invited organization](https://sendtier.com/docs/api/acceptInvitation.md): Call GET /me first. Any signed-in dashboard user may accept without selecting a tenant, including viewers and users with no memberships. The normalized signed-in email must match. Expired, revoked, and used tokens return not_found. Repeating acceptance by the same user succeeds without recreating membership while that membership still exists. That response returns the member's current role, which can differ from the role stored on the invitation. When that user no longer has a membership, acceptance returns not_found and does not recreate it. Acceptance into an organization pending deletion fails. Idempotency-Key is ignored; acceptance itself is idempotent per user and token. - [Remove an organization member](https://sendtier.com/docs/api/removeOrganizationMember.md): Owners may remove any member; admins may remove non-owners. The last owner cannot be removed. The path must match the selected membership. - [Change an organization member's role](https://sendtier.com/docs/api/updateOrganizationMemberRole.md): Owners only. The last owner cannot be demoted. The path must match the selected membership. - [Create an API key](https://sendtier.com/docs/api/createAPIKey.md): Requires a full-scope key. A test key may create only test keys. The full secret is returned only by this operation and is never stored. Idempotency-Key is not supported. Retrying creates a second key; the first can be revoked. - [List active API keys, newest first](https://sendtier.com/docs/api/listAPIKeys.md): Requires a full-scope key. - [Get an active API key](https://sendtier.com/docs/api/getAPIKey.md): Requires a full-scope key. - [Revoke an API key](https://sendtier.com/docs/api/revokeAPIKey.md): Requires a full-scope key. A key may revoke itself. Unknown or revoked keys return not_found. - [Current tenant send usage](https://sendtier.com/docs/api/getUsage.md): Requires a full or read_only key. Limits are null when uncapped. Counts accepted recipients, including scheduled sends. - [Dependency readiness check](https://sendtier.com/docs/api/getReady.md): Dependency readiness check - [Liveness check](https://sendtier.com/docs/api/getHealth.md): Liveness check - [List emails newest first](https://sendtier.com/docs/api/listEmails.md): List emails newest first - [Send an email](https://sendtier.com/docs/api/sendEmail.md): Validates and queues one email. A st_test_ key never sends a real email. It may use any domain the tenant has added that is not deleted, including pending and failed. A live key needs that domain verified. An unknown, deleted, or other-tenant domain returns 404 not_found. Optional resend_of keeps the source email's mode. A test email stays in test and is never delivered, even when the caller is live. A test key cannot resend a live email. - [Send up to 100 emails](https://sendtier.com/docs/api/sendEmailBatch.md): All emails are validated first. If one is invalid, none is queued. The domain rule matches POST /emails. - [Get one email with its events](https://sendtier.com/docs/api/getEmail.md): Get one email with its events - [Add a sending domain](https://sendtier.com/docs/api/createDomain.md): Add a sending domain - [List domains](https://sendtier.com/docs/api/listDomains.md): List domains - [Get one domain](https://sendtier.com/docs/api/getDomain.md): Get one domain - [Delete a domain](https://sendtier.com/docs/api/deleteDomain.md): Delete a domain - [Check the DNS records now](https://sendtier.com/docs/api/verifyDomain.md): Check the DNS records now - [Add a webhook endpoint](https://sendtier.com/docs/api/createWebhook.md): The signing secret is returned only on the first successful response. A replay with the same Idempotency-Key and request body returns the same webhook without signing_secret, with the usual response headers and Idempotent-Replayed set to true. The caller's mode sets the endpoint mode: a test key or dashboard test mode creates a test endpoint (test_mode true), which receives only test-mode events. Any other caller creates a live endpoint, which receives only live events. - [List webhooks](https://sendtier.com/docs/api/listWebhooks.md): List webhooks - [Get a webhook without its signing secret](https://sendtier.com/docs/api/getWebhook.md): Get a webhook without its signing secret - [Delete a webhook](https://sendtier.com/docs/api/deleteWebhook.md): Delete a webhook - [Rotate a webhook signing secret](https://sendtier.com/docs/api/rotateWebhookSecret.md): Requires a full-scope API key or dashboard owner, admin or developer. Returns the new signing_secret once; idempotent replays omit it. The previous secret stays valid for 24 hours after it stops being current. Deliveries are signed with both secrets until that expiry, then only with the new secret. A second rotation during the overlap returns 400 invalid_request and does not replace the previous secret. - [List retained webhook deliveries, newest first](https://sendtier.com/docs/api/listWebhookDeliveries.md): List retained webhook deliveries, newest first - [Get a delivery, its payload and ordered attempts](https://sendtier.com/docs/api/getWebhookDelivery.md): Get a delivery, its payload and ordered attempts - [Resend a succeeded or failed delivery, preserving its attempt history](https://sendtier.com/docs/api/resendWebhookDelivery.md): Resend a succeeded or failed delivery, preserving its attempt history - [Add a recipient to this account's suppression list](https://sendtier.com/docs/api/createSuppression.md): Requires a full-scope key. Emails are normalized to lower case. Existing entries are returned unchanged. - [List suppressed recipients](https://sendtier.com/docs/api/listSuppressions.md): Requires a full-scope key. Global suppressions are not included. - [Get one suppression for this account](https://sendtier.com/docs/api/getSuppression.md): Requires a full-scope key. Emails are normalized to lower case. Global suppressions are not visible. - [Remove a recipient from this account's suppression list](https://sendtier.com/docs/api/deleteSuppression.md): Requires a full-scope key. Emails are normalized to lower case. Global suppressions cannot be removed. ## Errors - [invalid_request](https://sendtier.com/docs/errors/invalid_request.md): Remediation for invalid_request. - [unauthorized](https://sendtier.com/docs/errors/unauthorized.md): Remediation for unauthorized. - [forbidden](https://sendtier.com/docs/errors/forbidden.md): Remediation for forbidden. - [not_found](https://sendtier.com/docs/errors/not_found.md): Remediation for not_found. - [idempotency_conflict](https://sendtier.com/docs/errors/idempotency_conflict.md): Remediation for idempotency_conflict. - [already_exists](https://sendtier.com/docs/errors/already_exists.md): Remediation for already_exists. - [domain_not_verified](https://sendtier.com/docs/errors/domain_not_verified.md): Remediation for domain_not_verified. - [recipient_suppressed](https://sendtier.com/docs/errors/recipient_suppressed.md): Remediation for recipient_suppressed. - [organization_limit_reached](https://sendtier.com/docs/errors/organization_limit_reached.md): Remediation for organization_limit_reached. - [rate_limited](https://sendtier.com/docs/errors/rate_limited.md): Remediation for rate_limited. - [not_implemented](https://sendtier.com/docs/errors/not_implemented.md): Remediation for not_implemented. - [internal_error](https://sendtier.com/docs/errors/internal_error.md): Remediation for internal_error. ## Downloads - [OpenAPI](https://sendtier.com/openapi.yaml): Public API document matching the API reference. - [Full documentation](https://sendtier.com/llms-full.txt): Full Markdown text of every guide.