Email verification API
Confirm a new user owns their email address with a verification link or code, using one Mailbot API call.
Answer first: to verify an email, POST https://api.mailbot.id/v1/send with your Bearer key and a JSON body whose html/text contains a single-use verification link (or code) that points back to your app. Your backend generates and stores the token with an expiry; Mailbot delivers the message.
Use case
A verification email confirms that the address a user signed up with actually belongs to them. Your backend generates a signed, single-use token, stores it with an expiry, and embeds it in a link like https://yourapp.com/verify?token=.... When the user clicks, your backend marks the account verified. Mailbot handles the send request and returns a message id.
Your backend owns the verification logic: generate the token, store it with an expiry, validate it on click, and invalidate it after use. Mailbot delivers the message containing that link or code.
When to send
- A new account is created at signup and needs to confirm its email address.
- A user changes the email address on their account.
- Periodic re-verification of stale or unconfirmed accounts.
API call
curl https://api.mailbot.id/v1/send \
-H "Authorization: Bearer $MAILBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@yourdomain.com",
"to": "user@example.com",
"subject": "Confirm your email address",
"text": "Confirm your email address: https://yourapp.com/verify?token=eyJhbGciOiJIUzI1NiJ9... This link expires in 24 hours.",
"idempotency_key": "verify-user-142"
}'
import os, requests
token = generate_verification_token() # your signed, single-use token
store_token(user.id, token, expires_in=86400) # store with a 24-hour expiry
link = f"https://yourapp.com/verify?token={token}"
res = requests.post(
"https://api.mailbot.id/v1/send",
headers={
"Authorization": f"Bearer {os.environ['MAILBOT_API_KEY']}",
"Content-Type": "application/json",
},
json={
"from": "noreply@yourdomain.com",
"to": user.email,
"subject": "Confirm your email address",
"text": f"Confirm your email address: {link} This link expires in 24 hours.",
"idempotency_key": f"verify-user-{user.id}",
},
)
res.raise_for_status()
Required fields
| Field | Required | Notes |
|---|---|---|
to | Yes | The user's email address being verified. |
subject | Yes | State the purpose clearly, for example "Confirm your email address". |
text or html | Yes | The body must contain the verification link or code. |
from | No | Verified sender; defaults to the configured sender if omitted. |
idempotency_key | Recommended | Tie to the verification request so retries don't double-send. |
Example payload
{
"from": "noreply@yourdomain.com",
"to": "user@example.com",
"subject": "Confirm your email address",
"text": "Confirm your email address: https://yourapp.com/verify?token=eyJhbGciOiJIUzI1NiJ9... This link expires in 24 hours. If you didn't create this account, ignore this email.",
"html": "<p>Confirm your email address by clicking the link below.</p><p><a href=\"https://yourapp.com/verify?token=eyJhbGciOiJIUzI1NiJ9...\">Confirm email address</a></p><p>This link expires in 24 hours.</p>",
"idempotency_key": "verify-user-142"
}
Example response
{
"ok": true,
"id": "msg_3f8c1a...",
"status": "queued"
}
For delivered messages, the response can include status: "sent" and a delivery_id. See the API reference for every response shape.
Errors
| Status | Meaning | What to do |
|---|---|---|
400 | Invalid payload (bad to, missing subject/body). | Fix the request; read details. |
401 | Bad or missing API key. | Check the Bearer header. |
429 | Send limit reached. | Back off; surface a "try again later" message to the user. |
502 / 503 | Mailbot is temporarily unable to accept the send. | Retry with backoff using the same idempotency_key. |
Full error handling guidance is in the integration guide.
Testing
For safe setup, use the standard test endpoint to confirm delivery reaches an address you control:
curl https://api.mailbot.id/v1/test-email \
-H "Authorization: Bearer $MAILBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "safe@yourdomain.com", "label": "Verify test" }'
Production checklist
- Verification tokens are single-use, expire, and are invalidated after use.
- No sensitive data embedded in the link beyond an opaque token.
- Verified sender domain;
fromset to a verified address. - API key kept server-side; never sent to the browser or mobile client.
429/5xxhandled with backoff and a clear user message.idempotency_keyset so retries don't double-send.