Sendex

API Reference

The Sendex API lets you send and receive email programmatically using your verified domains. All endpoints follow RESTful conventions and return JSON.

Email content is encrypted at rest using AES-256-GCM and stored for up to 30 days. If you prefer that no email content is saved to our servers, you can opt out at any time from Dashboard → Settings

Base URL

https://sendexapi.com/api/v1

Authentication

Every request must include your API key in the Authorization header as a Bearer token. Generate keys from the API Keys section of your dashboard.

Authorization: Bearer sk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

send_only

Can send emails via POST /api/v1/emails. Cannot read or list messages.

full

Full read and write access: send, list, and retrieve emails and domains.

Keys can optionally be scoped to specific domains. Requests from out-of-scope domains return 403 Forbidden.

Rate Limits

Rate limits are enforced per API key. Exceeding the limit returns 429 Too Many Requests. The underlying AWS SES sending limits apply to outbound mail regardless of API limits.

Sending Limits & Tiers

Sendex accounts have a daily sending guideline based on their tier. These are not hard blocks — crossing the threshold does not reject your emails. Instead, it triggers an automated AI review of your recent sending content to verify it is not spam or phishing. Legitimate senders are not affected. Guidelines reset at midnight UTC.

TierDaily guidelineHow to reach it
new500 emails / dayAll accounts start here
trusted5,000 emails / dayAutomatic — see below

Automatic tier upgrade

Accounts are automatically promoted to trusted once all of the following are met. This is checked once per day on your first send of the day.

RequirementThreshold
Account ageAt least 14 days
Emails sent (last 30 days)At least 100
Bounce rate (last 30 days)Below 2%
Account standingNot suspended

Recipient address validation

Before an email is queued, Sendex verifies that each recipient domain has valid MX records. Sending to a domain with no mail server returns a 422 invalid_recipient error rather than queueing a send that would immediately bounce.

AI monitoring

All accounts are continuously monitored by automated AI systems that analyse sending patterns and email content. Monitoring runs throughout the lifetime of your account — it does not stop after reaching trusted tier. The AI is tuned to flag phishing, impersonation, and scam content only. Transactional emails, marketing campaigns, newsletters, and product updates sent to opted-in lists are not flagged.

False positives can occasionally occur. If your account is suspended and you believe it was a mistake, see the Account Suspension section for how to appeal.

If you regularly send above 5,000 emails per day and need a higher guideline, contact [email protected].

Account Suspension

Sendex automatically monitors sending behaviour to protect shared infrastructure and maintain deliverability for all customers. Accounts that breach these thresholds are suspended automatically.

What triggers a suspension

SignalThresholdNotes
Bounce rateAbove 4% (last 15 days)Requires at least 50 sent emails before this check activates.
Spam complaintsCounted toward bounce rateISP complaint feedback is included in the bounce rate calculation.
AI content reviewOngoing — all tiersAutomated analysis of email content. Flags phishing and impersonation. Does not flag marketing or newsletters.

What happens when an account is suspended

  1. All email sending is immediately paused. API calls return 403 account_suspended.
  2. You receive an email at your account address with the specific reason.
  3. Your dashboard shows a banner with the reason and a link to appeal.

Appealing a suspension

If you believe your account was suspended in error, email [email protected] from your registered account address. Include a brief explanation of your sending use case. Most appeals are reviewed within one business day.

Keeping your bounce rate low

  • Only send to addresses that have explicitly opted in and recently engaged.
  • Remove hard bounces from your list immediately — Sendex adds them to a suppression list automatically, but clean your source list too.
  • Use a double opt-in flow for marketing lists.
  • Avoid purchased or scraped email lists entirely.

Delivery & Retries

Sendex uses an internal queue between your API call and the actual SES send. This decouples your request from the network call to AWS, so transient SES failures are handled automatically without any effort on your side.

How it works

  1. Your POST /api/v1/emails request returns 202 Accepted immediately — the email is queued, not yet sent.
  2. A background worker picks up the job and sends it to AWS SES.
  3. If SES returns an error, the job is automatically retried with exponential backoff.
  4. Once sent (or permanently failed), a webhook fires so you know the outcome.

Retry schedule

AttemptDelay before retry
1 → 230 s
2 → 360 s
3 → 42 min
4 → 54 min
5+8 min → 30 min (cap)
Max attempts54 total — ~24 h coverage
A 202 Accepted response does not mean the email was delivered — only that it was queued. Subscribe to the email.sent and email.failed webhooks to track the actual outcome.

Errors

All errors return a JSON body with error (machine-readable slug) and message (human-readable string).

{
  "error": "bad_request",
  "message": "from, to, subject, and text or html are required."
}
HTTP statuserror slugMeaning
400bad_requestMissing or invalid parameters.
401unauthorizedMissing or invalid API key.
403forbiddenKey lacks permission for this resource.
403account_suspendedAccount is suspended. Check your dashboard for the reason.
404not_foundThe requested resource does not exist.
422unprocessable_entityDomain is not verified for sending.
422invalid_recipientA recipient domain has no MX records.
429too_many_requestsRate limit exceeded.
402insufficient_creditsAccount has no remaining credits.
502bad_gatewayUpstream SES error.
500internal_server_errorUnexpected server error.

Webhooks

Webhooks allow Sendex to push real-time event notifications to your server. Register endpoints from the Webhooks section of your dashboard.

Payload format

Every webhook request is an HTTP POST with a JSON body and a signature header.

POST https://your-server.com/webhook
Content-Type: application/json
X-Sendex-Signature: sha256=<hmac-sha256-hex>

{
  "event": "email.sent",
  "created_at": "2026-03-05T12:00:00.000Z",
  "data": { ... }
}

Verifying signatures

Compute HMAC-SHA256(secret, rawBody) and compare it to the value in the X-Sendex-Signature header (after stripping the sha256= prefix). Use a timing-safe comparison.

import crypto from "crypto";

function verifyWebhook(rawBody: string, secret: string, header: string): boolean {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(header),
    Buffer.from(expected)
  );
}

Events

EventDescriptionRequires
email.sentEmail successfully sent via SES.
email.failedEmail send to SES failed.
email.receivedInbound email received.
email.deliveredSES confirmed delivery.SES_CONFIG_SET
email.bouncedSES reported a bounce.SES_CONFIG_SET
email.complainedRecipient marked as spam.SES_CONFIG_SET
email.openedRecipient opened the email.SES_CONFIG_SET + open tracking
email.clickedRecipient clicked a link.SES_CONFIG_SET + click tracking
broadcast.queuedBroadcast was created and queued.
broadcast.startedBroadcast worker began sending.
broadcast.completedBroadcast finished sending.
broadcast.pausedBroadcast was paused.
broadcast.cancelledBroadcast was cancelled.
broadcast.failedBroadcast worker encountered a fatal error.
contact.createdA contact was created or upserted.
contact.subscribedContact subscription was set to true.
contact.unsubscribedContact unsubscribed (via API or unsubscribe page).

SES delivery events setup

Events like email.delivered, email.bounced, and email.complained require an AWS SES Configuration Set with an SNS destination pointing to /api/ses-notifications. Set the SES_CONFIG_SET environment variable to the name of your configuration set.