Authentication
Both methods use the same credential: an API key, which has a key ID (public) and a key secret. Create keys in the dashboard at app.onesend.eu.
REST auth uses a bearer token that is the key ID and secret joined by a colon:
Authorization: Bearer YOUR_KEY_ID:YOUR_KEY_SECRET
SMTP auth uses the key ID as the username and the key secret as the password. There is no separate SMTP username or password to generate. The API key is the credential for both REST and SMTP.
Verify your sending domain
You can only send from an address on a domain you have added and verified. This is required even during the trial, to protect shared IP reputation. Verification is done once, in the dashboard.
When you add a domain, onesend generates a DKIM key and gives you four TXT records to publish at your DNS provider:
| Purpose | Host | Value (example) |
|---|---|---|
| DKIM | onesend._domainkey.yourdomain.com | v=DKIM1; k=rsa; p=MIIB... |
| SPF | yourdomain.com | v=spf1 include:onesend.eu ~all |
| DMARC | _dmarc.yourdomain.com | v=DMARC1; p=none; rua=mailto:dmarc@onesend.eu |
| Ownership | _onesend.yourdomain.com | onesend-verify=YOUR_TOKEN |
DKIM is what gates verification. SPF and DMARC are strongly recommended but the domain verifies on DKIM alone. The DKIM selector is onesend. If you already have an SPF record, add include:onesend.eu to your existing record rather than creating a second one, since a domain can only have one SPF record. DNS changes take a few minutes to a few hours to propagate.
Send with the REST API
POST https://api.onesend.eu/v1/email/send
Authorization: Bearer YOUR_KEY_ID:YOUR_KEY_SECRET
Content-Type: application/json
Request body:
{
"from": "hello@yourdomain.com",
"to": ["recipient@example.com"],
"cc": ["optional@example.com"],
"bcc": ["optional@example.com"],
"reply_to": "reply@yourdomain.com",
"subject": "Hello from onesend",
"html": "<h1>It works</h1>",
"text": "It works",
"headers": { "X-Custom": "value" },
"tags": { "campaign": "welcome" }
}
Required fields are from, to, subject, and at least one of html or text. The from address must be on a verified domain. The cc, bcc, reply_to, text, headers and tags fields are optional.
On success the response is 202 Accepted and the message is queued for delivery:
{ "message_id": "...", "status": "queued" }
If the recipient is on your suppression list, the request still returns 200 (not an error), the send is skipped, and it is not counted toward billing:
{ "message_id": "...", "status": "suppressed", "reason": "Recipient on suppression list (bounce)" }
Send with SMTP
Point your existing SMTP mailer at onesend. No code changes beyond host and credentials.
Host: smtp.onesend.eu
Port: 587
Security: STARTTLS (required)
Username: YOUR_KEY_ID
Password: YOUR_KEY_SECRET
The same rules apply as REST: the From address must be on a verified domain, and suppressed recipients are skipped and not billed.
Code examples
curl (REST)
curl -X POST https://api.onesend.eu/v1/email/send \
-H "Authorization: Bearer $ONESEND_KEY_ID:$ONESEND_KEY_SECRET" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Hello from onesend",
"html": "<h1>It works</h1>",
"text": "It works"
}'
Node.js (REST, fetch)
const res = await fetch("https://api.onesend.eu/v1/email/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.ONESEND_KEY_ID}:${process.env.ONESEND_KEY_SECRET}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "hello@yourdomain.com",
to: ["recipient@example.com"],
subject: "Hello from onesend",
html: "<h1>It works</h1>",
}),
});
const data = await res.json();
console.log(res.status, data);
Node.js (SMTP, nodemailer)
import nodemailer from "nodemailer";
const transport = nodemailer.createTransport({
host: "smtp.onesend.eu",
port: 587,
requireTLS: true,
auth: {
user: process.env.ONESEND_KEY_ID,
pass: process.env.ONESEND_KEY_SECRET,
},
});
await transport.sendMail({
from: "hello@yourdomain.com",
to: "recipient@example.com",
subject: "Hello from onesend",
html: "<h1>It works</h1>",
});
Python (REST, requests)
import os, requests
r = requests.post(
"https://api.onesend.eu/v1/email/send",
headers={
"Authorization": f"Bearer {os.environ['ONESEND_KEY_ID']}:{os.environ['ONESEND_KEY_SECRET']}"
},
json={
"from": "hello@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Hello from onesend",
"html": "<h1>It works</h1>",
},
)
print(r.status_code, r.json())
Python (SMTP, smtplib)
import os, smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["From"] = "hello@yourdomain.com"
msg["To"] = "recipient@example.com"
msg["Subject"] = "Hello from onesend"
msg.set_content("It works")
msg.add_alternative("<h1>It works</h1>", subtype="html")
with smtplib.SMTP("smtp.onesend.eu", 587) as s:
s.starttls()
s.login(os.environ["ONESEND_KEY_ID"], os.environ["ONESEND_KEY_SECRET"])
s.send_message(msg)
PHP (REST, curl)
$ch = curl_init("https://api.onesend.eu/v1/email/send");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer {$keyId}:{$keySecret}",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"from" => "hello@yourdomain.com",
"to" => ["recipient@example.com"],
"subject" => "Hello from onesend",
"html" => "<h1>It works</h1>",
]),
]);
$response = curl_exec($ch);
Any other language, framework or tool sends through the SMTP settings above, including Go net/smtp, Ruby, Java, Laravel, Rails, Django, WordPress and n8n.
Migrating from another provider
The fastest migration is SMTP: change the host and the credentials, and leave everything else alone. In every case, add and verify your sending domain in onesend first, because sending is gated on a verified domain.
Amazon SES
For SMTP, change the host from email-smtp.REGION.amazonaws.com to smtp.onesend.eu on port 587, and use your onesend key ID and secret instead of the SES SMTP credentials. This is drop-in. For REST, SES uses SigV4-signed requests, so onesend's REST API is a different shape; either switch to POST /v1/email/send or use SMTP for a migration with no code changes. You can export your SES suppression list and import the CSV in the dashboard.
SendGrid
For SMTP, SendGrid uses smtp.sendgrid.net with the username apikey. onesend uses smtp.onesend.eu with the username set to your key ID and the password set to your key secret. For REST, SendGrid's /v3/mail/send uses a different JSON structure, so use onesend's POST /v1/email/send instead.
Mailgun
For SMTP, change the host from smtp.mailgun.org to smtp.onesend.eu and swap the credentials. For REST, Mailgun uses form-encoded requests to /v3/DOMAIN/messages, so use onesend's JSON POST /v1/email/send instead.
Postmark
For SMTP, change the host from smtp.postmarkapp.com to smtp.onesend.eu and swap the credentials. For REST, Postmark uses an X-Postmark-Server-Token header and a different body, so use onesend's POST /v1/email/send.
Delivery status values
A message moves through these statuses:
queuedaccepted and waiting for the worker to send.senthanded off to the receiving mail server.bouncedhard bounce (permanent). The address is added to your suppression list.soft_bouncedtemporary failure such as a full mailbox. Retried, not suppressed.complainedrecipient marked it as spam. Added to your suppression list.suppressedrecipient was already on your suppression list. Skipped, not billed.invalidaddress failed validation before sending (bad syntax or dead domain).blockedblocked by a policy check before sending.failedan internal send failure.
Suppression list
onesend keeps a per-account suppression list. Addresses land on it automatically from hard bounces and complaints, from pre-send validation, or you can add them yourself. onesend records both the reason (why it is suppressed) and the source (how it got there), plus the real diagnostic code. You manage the list in the dashboard, and you can import or export it as CSV.
Plans and billing
Sending needs a verified domain and a plan. The trial covers 100 emails with no time limit. Paid plans are Starter and Growth, billed monthly through Mollie (an EU payment provider), with VAT applied correctly for EU and non-EU customers, including reverse charge for validated EU business VAT IDs. Overage is billed, not blocked, and suppressed sends are never counted. For current prices and included volumes, see the pricing page.
Sovereignty and compliance
- Operating company: WOCOO Management and Consulting GmbH, Vienna, Austria.
- Infrastructure: Hetzner, Falkenstein, Germany. No US subprocessors in the sending path.
- Built for GDPR: recipient data sits in an identity vault separated from send logs, and each account sets its own retention policy. Suppression data and aggregate statistics are kept.
- Deliverability: SPF, DKIM with 2048-bit per-domain keys, and DMARC per sending domain. Dedicated sending IPs on request.
Building an integration with an AI assistant? A plain-text copy of this reference lives at /llms-full.txt