REST API · v1

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 URLhttps://securessmtp.com/api/v1
Content typeapplication/json
Auth headerX-QCS-API-Key: sk_xxx
Site URL headerX-QCS-Site-URL: https://yourdomain.com
Rate limit60 / minute / API key (burstable)

Authentication

Every authenticated request needs two headers:

  • X-QCS-API-Key — your site’s API key from the SecureSMTP dashboard
  • X-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.

jsoncopy
{
  "error": "invalid_api_key",
  "message": "API key not recognised or revoked."
}
CodeMeaning
400Malformed JSON, missing required field, or schema mismatch
401Missing / invalid X-QCS-API-Key
403Site disabled or quota cap hit
404Resource not found
409Conflict (e.g. duplicate domain registration)
429Rate limit exceeded
5xxOur 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

POST/mail/send

Send a transactional email

Sends a single email through SecureSMTP's authenticated relay. Returns the Resend message ID for delivery tracking.

Request body
jsoncopy
{
  "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"
}
200 OK response
jsoncopy
{
  "ok": true,
  "message_id": "c3c56229-c9c2-4661-bcd0-c431a8d45713"
}
cURL example
curlcopy
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>"
  }'
POST/forms/submit

Submit a form

Accepts a form submission, runs anti-abuse + AI spam classification, sends the notification email, and stores the submission for review.

Request body
jsoncopy
{
  "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..."
}
200 OK response
jsoncopy
{
  "ok": true,
  "submission_id": "9a4f...c12",
  "classification": "legitimate"
}
cURL example
curlcopy
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"}
  }'
POST/sites/verify

Verify site ownership

Marks the registered site as verified after the install handshake. Required before /forms/submit and /mail/send begin accepting traffic.

Request body
jsoncopy
{
  "site_url": "https://yourdomain.com",
  "plugin_version": "1.20.0",
  "wp_version": "6.5.0",
  "php_version": "8.2"
}
200 OK response
jsoncopy
{
  "ok": true,
  "verified": true,
  "site_id": "b41383ee-..."
}
cURL example
curlcopy
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"}'
GET/mail/domain-status

Check sending-domain status

Returns the current DKIM + SPF verification state for a domain you've registered for sending.

200 OK response
jsoncopy
{
  "ok": true,
  "domain": "send.yourdomain.com",
  "status": "verified",
  "records_pending": []
}
cURL example
curlcopy
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.

EventFires when
email.sentRelay accepted the message
email.deliveredRecipient's mailbox provider accepted the message
email.openedRecipient opened the email (includes geo + UA)
email.clickedRecipient clicked a link (includes link_url)
email.bouncedHard or soft bounce (includes bounce_type)
email.complainedRecipient marked as spam
email.delivery_delayedTransient delay &mdash; will retry

Signature verification

Every webhook is signed using the standard Svix scheme. Verify the signature with your webhook secret before trusting the payload.

nodejscopy
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.