One POST sends an email.
Give the endpoint from, to, subject and html. Add reply-to, cc, bcc, attachments or custom headers when a message needs them. There is no proprietary envelope format to learn first.
A REST API you can read in one sitting, an SMTP relay for the stack you already have, and official SDKs in the language you work in. Send from your application, keep the message ID, and get back to the product.
One POST to send. One header to authenticate. Attachments, cc, bcc, reply-to, custom headers, and React Email are supported. Sending runs on AWS SES.
curl --request POST \
'https://api.email.utobo.com/functions/v1/send-email' \
--header 'Authorization: Bearer av_live_...' \
--header 'Content-Type: application/json' \
--data '{
"from": "Northstar <hello@example.com>",
"to": "alex@example.net",
"subject": "Your workspace is ready",
"html": "<p>Sign in to start your first project.</p>"
}'{ "id": "3c9b0f4e-7a2d-4f8b-9c1e-5d6a8b3f2e1c",
"message": "Email sent." }Keep the ID. A successful response means the message was accepted for sending — not that it reached an inbox.
Send from an address on your verified domain. Nothing on this page sends email.
Give the endpoint from, to, subject and html. Add reply-to, cc, bcc, attachments or custom headers when a message needs them. There is no proprietary envelope format to learn first.
Send Authorization: Bearer av_live_… and you are through. No signing steps, no token exchange, no separate auth path for the SDKs. The full key is shown once at creation, so keep it in your server environment.
Every failure returns { error, name, message }. Branch on the machine-readable name — a missing field and an unverified domain are different problems, and the response tells you which one you have.
utobo email speaks the two interfaces your stack already speaks. If your application can make an HTTPS request or open an SMTP connection, it can send through utobo — and it can send through something else tomorrow. Leaving is a change of host and credentials, not a rewrite.
Sending runs on AWS SES. Add your own sending domain, complete DKIM, SPF and DMARC in the setup flow, and let automatic bounce and complaint handling keep the suppression list current without a job of your own.
Already sending over SMTP? Point your existing mailer at smtp.mail.utobo.com. The username is the literal word apikey — your API key goes in the password field.
The username is always apikey, never an email address. Store the key in the application’s secure settings, not in source control.
Use the same verified sending domain you use on the API.
Everything lives under https://api.email.utobo.com/functions/v1. One call sends the message, the other looks it up again.
| Endpoint | What it does | What you get back |
|---|---|---|
POST /functions/v1/send-email | Send one message to up to 50 combined recipients.Supports reply-to, cc, bcc, attachments and custom headers. | { "id": "…", "message": "Email sent." } |
GET /functions/v1/send-email/:id | Look a message up by the ID the send response returned.The place to start when someone asks where an email went. | The status record for that message |
smtp.mail.utobo.com, ports 587 or 465Features are not a pricing tier. Transactional starts at $9 a month for 10,000 emails, and AI drafting is included on every plan at no extra cost. Compare the three tracks ↗
Error handling stays in the application that made the request. Branch on name, not on the wording of message.
validation_error — a field is missing or malformed. Correct the payload and retry; this one will not resolve itself.
unauthorized — the API key is missing, revoked or mistyped. Confirm the header reads Authorization: Bearer av_live_…
insufficient_scope — the key is valid but not permitted to do this. Issue a key with the access this integration needs.
domain_not_verified — the from-address is not on a verified domain, or every recipient is suppressed.
rate_limit_exceeded — you are sending faster than your allowance. Wait for the returned Retry-After window before the next attempt.
100 requests/minute/key500 requests/minute/organization50 combined recipients/request
Queue and pace bulk work rather than retrying immediately on 429. Expecting heavier volume? Talk through your requirements ↗
The Node.js SDK is the official library. Python, Ruby and Go are published too, and every one of them talks to the same two endpoints.
npm install utobo-emailimport { UtoboEmail } from 'utobo-email';
const apiKey = process.env.UTOBO_EMAIL_API_KEY;
if (!apiKey) throw new Error('Set UTOBO_EMAIL_API_KEY on the server.');
const client = new UtoboEmail(apiKey);
const { data, error } = await client.emails.send({
from: 'Northstar <hello@example.com>',
to: 'alex@example.net',
subject: 'Your workspace is ready',
html: '<p>Sign in to start your first project.</p>',
});
if (error) console.error(error);
else console.log(data);npm install utobo-emailOpen package ↗pip install utobo-emailOpen package ↗gem install utobo-emailOpen package ↗go get github.com/myutobo/utobo-email-goOpen package ↗# Coming soon — send from PHP today with the REST API or SMTPComing soonAdd the DKIM, SPF and DMARC records from the setup flow and wait for verification before sending from that address.
Copy av_live_… once at creation and load it from UTOBO_EMAIL_API_KEY on the server.
Use curl or your SDK to send a short message to an address you control. Confirm the response carries an ID.
Move the call behind the signup, reset or receipt that should trigger it, and store the returned ID with that record.
The detail worth checking before you write the integration.
Talk to the team ↗Two. POST /functions/v1/send-email sends a message and GET /functions/v1/send-email/:id looks one up, both under https://api.email.utobo.com/functions/v1. See the request and response shapes.
100 requests per minute per key and 500 per minute per organization, with a maximum of 50 combined recipients on a single request. Exceeding them returns 429 rate_limit_exceeded with a Retry-After header to wait on.
Yes, and you can mix the two. Connect to smtp.mail.utobo.com on port 587 with STARTTLS or 465 with implicit TLS. The username is the literal word apikey and the password is your API key. See the SMTP settings.
A native PHP SDK is coming soon. Node.js, Python, Ruby and Go are published today, and PHP can send right now through the REST API or the SMTP relay with any HTTP or mail library. Choose your language.
As hard as changing a base URL and a credential. There is no proprietary transport or template format in the sending path — it is HTTPS with JSON, or SMTP. Anything you build against it stays portable.
No. It means the message was accepted for sending. Delivery is decided by the recipient’s mail system, so keep the returned ID and check the message record rather than treating a 200 as proof of inbox placement.
Transactional starts at $9 a month for 10,000 emails. Promotional starts at $19 a month for 2,500 contacts with unlimited campaign sends — you pay for contacts, not sends — and All-in-one starts at $24 a month. AI is included on every plan. See the plans.
Create a key, verify a domain, and send your first message in an afternoon. Transactional starts at $9 a month for 10,000 emails, with AI included.