Your application already knows how to send email somehow — through a REST API, through the envelope it uses today, or over SMTP. All three come in here and leave through the same infrastructure, with the same events and the same statement.
This is not one API with two adapters bolted on: they are three ways into the same sending engine. What changes is how your code gets here.
POST /api/v1/email/messages JSON over HTTP, with the message id already in the response and idempotency by key. It is how you follow what happened next.
POST /v3/mail/send Same path, same auth header, same body. To migrate, swap the base URL and the key — the code that builds the payload stays as it is.
smtp.qsendyx.com:587 Port 587 with STARTTLS and token auth. For what already speaks SMTP and is not going to be rewritten to speak HTTP.
Send a field we will not use and the request is refused with a 4xx and a sentence telling you what to do — never accepted with a 202 and dropped in silence. The compatibility matrix is published field by field, with the reason for every refusal, and a test keeps it from drifting from the code.
Accepting is the easy part; the rest of the path is what decides. We authenticate the domain, look after the outbound reputation, and hand back every outcome over webhook — the bad ones included.
POST /v1/emails202Delivered to the inbox
Every outcome comes back as a webhook
Templates with variables, rendered in a sandbox. No code execution inside a template.
SPF, DKIM and DMARC verified in the dashboard, with the records ready to copy.
Addresses verified before the first send — the gate refuses whatever has not passed.
Checks syntax, whether the domain routes mail, disposable addresses, role accounts and typos — plus whoever is already on your suppression list.
Opens and clicks per message, with one-click unsubscribe in the footer.
Whoever bounced or complained goes on the list and stops receiving. The rule holds even if you send again.
Sending to a contact list, kept apart from transactional right down to the schema — mixing the two poisons your reputation.
Every event delivered signed, with retries. A cron redelivers whatever your end refused.
The migration page shows the two-line diff, what comes across and what does not — before you start.
Account created, domain verified, token in hand. The send is one request.