Build SecureSMTP into any stack.
Same API the WordPress plugin uses. Send transactional mail, accept form submissions, manage sending domains, and subscribe to delivery events from any HTTP-capable platform.
Overview
The SecureSMTP API is a JSON REST API rooted at https://securessmtp.com/api/v1. All requests use TLS 1.2+; HTTP redirects to HTTPS. The same endpoints power the official WordPress plugin and the JavaScript SDK.
| Base URL | https://securessmtp.com/api/v1 |
| Content type | application/json |
| Auth header | X-QCS-API-Key: sk_xxx |
| Site URL header | X-QCS-Site-URL: https://yourdomain.com |
| Rate limit | 60 / minute / API key (burstable) |
Authentication
Every authenticated request needs two headers:
X-QCS-API-Key— your site’s API key from the SecureSMTP dashboardX-QCS-Site-URL— the canonical URL of the site the key belongs to (used to bind requests to the registered origin)
Keys are scoped per site. Rotate or revoke them anytime from /app/forms/api-keys — we never email or display them after creation.
Errors
Errors return a JSON body and a meaningful HTTP status.
{
"error": "invalid_api_key",
"message": "API key not recognised or revoked."
}| Code | Meaning |
|---|---|
| 400 | Malformed JSON, missing required field, or schema mismatch |
| 401 | Missing / invalid X-QCS-API-Key |
| 403 | Site disabled or quota cap hit |
| 404 | Resource not found |
| 409 | Conflict (e.g. duplicate domain registration) |
| 429 | Rate limit exceeded |
| 5xx | Our problem — retry with exponential backoff |
Rate limits
Default is 60 requests per minute per API key, with a small burst allowance. Submission and mail-send endpoints have separate per-IP quotas; abusive sites are auto-disabled.
Need a higher limit? Enterprise plans get dedicated quotas and rate profiles — contact us.
Endpoints
/mail/sendSend a transactional email
Sends a single email through SecureSMTP's authenticated relay. Returns the Resend message ID for delivery tracking.
{
"to": "recipient@example.com",
"subject": "Your order confirmation",
"html": "<p>Hi Zain,</p><p>Thanks for your order.</p>",
"text": "Hi Zain,\n\nThanks for your order.",
"from": "orders@yourdomain.com",
"reply_to": "support@yourdomain.com",
"tag": "order_confirmation"
}{
"ok": true,
"message_id": "c3c56229-c9c2-4661-bcd0-c431a8d45713"
}curl -X POST 'https://securessmtp.com/api/v1/mail/send' \
-H 'X-QCS-API-Key: sk_live_xxx' \
-H 'X-QCS-Site-URL: https://yourdomain.com' \
-H 'Content-Type: application/json' \
-d '{
"to": "you@example.com",
"subject": "Hello",
"html": "<p>It works.</p>"
}'/forms/submitSubmit a form
Accepts a form submission, runs anti-abuse + AI spam classification, sends the notification email, and stores the submission for review.
{
"form_id": 12,
"form_name": "contact",
"fields": {
"name": "Jane Doe",
"email": "jane@example.com",
"message": "Tell me more about pricing."
},
"notify_email": "you@yourdomain.com",
"turnstile_token": "0.XXXX..."
}{
"ok": true,
"submission_id": "9a4f...c12",
"classification": "legitimate"
}curl -X POST 'https://securessmtp.com/api/v1/forms/submit' \
-H 'X-QCS-API-Key: sk_live_xxx' \
-H 'X-QCS-Site-URL: https://yourdomain.com' \
-H 'Content-Type: application/json' \
-d '{
"form_id": 12,
"form_name": "contact",
"fields": {"name": "Jane", "email": "jane@example.com", "message": "Hi"}
}'/sites/verifyVerify site ownership
Marks the registered site as verified after the install handshake. Required before /forms/submit and /mail/send begin accepting traffic.
{
"site_url": "https://yourdomain.com",
"plugin_version": "1.20.0",
"wp_version": "6.5.0",
"php_version": "8.2"
}{
"ok": true,
"verified": true,
"site_id": "b41383ee-..."
}curl -X POST 'https://securessmtp.com/api/v1/sites/verify' \
-H 'X-QCS-API-Key: sk_live_xxx' \
-H 'X-QCS-Site-URL: https://yourdomain.com' \
-H 'Content-Type: application/json' \
-d '{"site_url": "https://yourdomain.com"}'/mail/domain-statusCheck sending-domain status
Returns the current DKIM + SPF verification state for a domain you've registered for sending.
{
"ok": true,
"domain": "send.yourdomain.com",
"status": "verified",
"records_pending": []
}curl 'https://securessmtp.com/api/v1/mail/domain-status?domain=send.yourdomain.com' \
-H 'X-QCS-API-Key: sk_live_xxx' \
-H 'X-QCS-Site-URL: https://yourdomain.com'Webhook events
Subscribe to delivery + engagement events from the SecureSMTP dashboard. We POST a JSON payload to the URL you register and sign every request.
| Event | Fires when |
|---|---|
| email.sent | Relay accepted the message |
| email.delivered | Recipient's mailbox provider accepted the message |
| email.opened | Recipient opened the email (includes geo + UA) |
| email.clicked | Recipient clicked a link (includes link_url) |
| email.bounced | Hard or soft bounce (includes bounce_type) |
| email.complained | Recipient marked as spam |
| email.delivery_delayed | Transient delay — will retry |
Signature verification
Every webhook is signed using the standard Svix scheme. Verify the signature with your webhook secret before trusting the payload.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(rawBody, msgId, ts, sigHeader, secretBase64) {
const key = Buffer.from(secretBase64.replace(/^whsec_/, ''), 'base64');
const expected = createHmac('sha256', key)
.update(`${msgId}.${ts}.${rawBody}`)
.digest('base64');
for (const part of sigHeader.split(' ')) {
const [v, sig] = part.split(',');
if (v !== 'v1') continue;
const a = Buffer.from(sig, 'base64');
const b = Buffer.from(expected, 'base64');
if (a.length === b.length && timingSafeEqual(a, b)) return true;
}
return false;
}Reject any event whose svix-timestamp is more than 5 minutes from current server time — this prevents replay attacks.
Build something with us.
Building an integration for your platform? We’ll co-promote and feature finished integrations on the /integrations page.