API Reference
The Sendex API lets you send and receive email programmatically using your verified domains. All endpoints follow RESTful conventions and return JSON.
Base URL
https://sendexapi.com/api/v1Authentication
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.
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.
| Tier | Daily guideline | How to reach it |
|---|---|---|
new | 500 emails / day | All accounts start here |
trusted | 5,000 emails / day | Automatic — 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.
| Requirement | Threshold |
|---|---|
| Account age | At least 14 days |
| Emails sent (last 30 days) | At least 100 |
| Bounce rate (last 30 days) | Below 2% |
| Account standing | Not 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.
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
| Signal | Threshold | Notes |
|---|---|---|
| Bounce rate | Above 4% (last 15 days) | Requires at least 50 sent emails before this check activates. |
| Spam complaints | Counted toward bounce rate | ISP complaint feedback is included in the bounce rate calculation. |
| AI content review | Ongoing — all tiers | Automated analysis of email content. Flags phishing and impersonation. Does not flag marketing or newsletters. |
What happens when an account is suspended
- All email sending is immediately paused. API calls return
403 account_suspended. - You receive an email at your account address with the specific reason.
- 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
- Your
POST /api/v1/emailsrequest returns202 Acceptedimmediately — the email is queued, not yet sent. - A background worker picks up the job and sends it to AWS SES.
- If SES returns an error, the job is automatically retried with exponential backoff.
- Once sent (or permanently failed), a webhook fires so you know the outcome.
Retry schedule
| Attempt | Delay before retry |
|---|---|
| 1 → 2 | 30 s |
| 2 → 3 | 60 s |
| 3 → 4 | 2 min |
| 4 → 5 | 4 min |
| 5+ | 8 min → 30 min (cap) |
| Max attempts | 54 total — ~24 h coverage |
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 status | error slug | Meaning |
|---|---|---|
| 400 | bad_request | Missing or invalid parameters. |
| 401 | unauthorized | Missing or invalid API key. |
| 403 | forbidden | Key lacks permission for this resource. |
| 403 | account_suspended | Account is suspended. Check your dashboard for the reason. |
| 404 | not_found | The requested resource does not exist. |
| 422 | unprocessable_entity | Domain is not verified for sending. |
| 422 | invalid_recipient | A recipient domain has no MX records. |
| 429 | too_many_requests | Rate limit exceeded. |
| 402 | insufficient_credits | Account has no remaining credits. |
| 502 | bad_gateway | Upstream SES error. |
| 500 | internal_server_error | Unexpected 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
| Event | Description | Requires |
|---|---|---|
email.sent | Email successfully sent via SES. | — |
email.failed | Email send to SES failed. | — |
email.received | Inbound email received. | — |
email.delivered | SES confirmed delivery. | SES_CONFIG_SET |
email.bounced | SES reported a bounce. | SES_CONFIG_SET |
email.complained | Recipient marked as spam. | SES_CONFIG_SET |
email.opened | Recipient opened the email. | SES_CONFIG_SET + open tracking |
email.clicked | Recipient clicked a link. | SES_CONFIG_SET + click tracking |
broadcast.queued | Broadcast was created and queued. | — |
broadcast.started | Broadcast worker began sending. | — |
broadcast.completed | Broadcast finished sending. | — |
broadcast.paused | Broadcast was paused. | — |
broadcast.cancelled | Broadcast was cancelled. | — |
broadcast.failed | Broadcast worker encountered a fatal error. | — |
contact.created | A contact was created or upserted. | — |
contact.subscribed | Contact subscription was set to true. | — |
contact.unsubscribed | Contact 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.