E-mails transacionais são as mensagens que o seu produto envia porque um usuário fez algo: se cadastrou, redefiniu a senha, pagou uma fatura, foi convidado para um workspace. Eles precisam sair rápido, do seu próprio domínio, e sem deixar lenta a requisição que os disparou.
Este artigo mostra como enviá-los pela API REST da Inbixio nas linguagens que as equipes mais usam e depois transforma a chamada avulsa em um pequeno helper que você pode colocar em qualquer código.
A requisição, em um só lugar
Todos os exemplos abaixo enviam a mesma requisição HTTP:
- Método e URL:
POST https://backend.inbixio.com/api/send-email/, incluindo a barra final - Autenticação: um header
X-API-Keycom uma chave que tenha a permissão Send (enviar) - Corpo: JSON com
to_email,subjectemessage(HTML)
Uma chamada bem-sucedida retorna 200 com {"message": "Email queued successfully."}. Se você ainda não criou uma chave nem conectou um servidor SMTP, comece pelo guia de início rápido de cinco minutos.
Em todos os exemplos, a chave é lida de uma variável de ambiente chamada INBIXIO_API_KEY. Mantenha-a no servidor; nunca a envie para um navegador ou app mobile.
cURL
Útil para testar uma chave, depurar a partir de um servidor ou chamar de um script shell ou cron job:
curl -sS -X POST https://backend.inbixio.com/api/send-email/ \
-H "X-API-Key: $INBIXIO_API_KEY" \
-H "Content-Type: application/json" \
--max-time 15 \
-d '{
"to_email": "ada@example.com",
"subject": "Your invoice is ready",
"message": "<p>Hi Ada, your invoice for October is ready.</p>"
}'
-sS esconde a barra de progresso, mas continua exibindo os erros, e --max-time impede que um script fique travado se a rede travar.
Node.js
O Node.js 18 e versões posteriores já vêm com fetch, então você não precisa de uma biblioteca HTTP:
// send-email.js
const INBIXIO_URL = 'https://backend.inbixio.com/api/send-email/';
export async function sendEmail({ to, subject, html }) {
const res = await fetch(INBIXIO_URL, {
method: 'POST',
headers: {
'X-API-Key': process.env.INBIXIO_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ to_email: to, subject, message: html }),
signal: AbortSignal.timeout(15_000),
});
const body = await res.json().catch(() => ({}));
if (!res.ok) {
const reason = body.error || body.detail || res.statusText;
throw new Error(`Inbixio ${res.status}: ${reason}`);
}
return body; // { message: 'Email queued successfully.' }
}
E usando-o em uma rota do Express:
app.post('/signup', async (req, res) => {
const user = await createUser(req.body);
await sendEmail({
to: user.email,
subject: 'Welcome aboard',
html: `<h1>Welcome, ${escapeHtml(user.name)}!</h1><p>Your account is ready.</p>`,
});
res.status(201).json({ id: user.id });
});
Repare no escapeHtml. O campo message é renderizado como HTML, então tudo o que um usuário digitou, como o nome dele, precisa ser escapado antes de entrar no corpo.
Python
Com requests:
# send_email.py
import os
import requests
INBIXIO_URL = "https://backend.inbixio.com/api/send-email/"
class EmailError(Exception):
pass
def send_email(to: str, subject: str, html: str) -> dict:
res = requests.post(
INBIXIO_URL,
headers={"X-API-Key": os.environ["INBIXIO_API_KEY"]},
json={"to_email": to, "subject": subject, "message": html},
timeout=15,
)
if not res.ok:
try:
body = res.json()
except ValueError:
body = {}
reason = body.get("error") or body.get("detail") or res.reason
raise EmailError(f"Inbixio {res.status_code}: {reason}")
return res.json()
Passar json= define o header Content-Type para você. Sempre defina um timeout: por padrão, o requests espera para sempre.
No Django, chame a função depois do commit da transação no banco de dados, para nunca enviar e-mail sobre um registro que sofreu rollback:
from django.db import transaction
transaction.on_commit(lambda: send_email(user.email, "Welcome!", render_welcome(user)))
PHP
<?php
function send_email(string $to, string $subject, string $html): array {
$ch = curl_init('https://backend.inbixio.com/api/send-email/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . getenv('INBIXIO_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'to_email' => $to,
'subject' => $subject,
'message' => $html,
]),
]);
$body = json_decode(curl_exec($ch), true) ?? [];
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException("Inbixio $status: " . ($body['error'] ?? $body['detail'] ?? 'request failed'));
}
return $body;
}
Envio para várias pessoas
Cada requisição entrega para um único to_email. Para notificar uma lista de usuários, envie uma requisição por destinatário. É isso que você quer em e-mails transacionais de qualquer forma: cada usuário recebe a própria mensagem, ninguém vê o endereço de ninguém e um endereço inválido não bloqueia os demais.
Mantenha a concorrência moderada para não sobrecarregar o seu próprio servidor SMTP. Um pequeno pool de 5–10 requisições paralelas é suficiente para a maioria dos apps.
Não envie no caminho da requisição
Chamar a API é rápido, mas ainda é uma ida e volta pela rede. Para tudo o que não for urgente, coloque o envio em um job em segundo plano (BullMQ, Celery, Sidekiq, uma fila na nuvem) para que:
- a página do usuário carregue sem esperar pelo e-mail,
- um erro temporário possa ser repetido sem que o usuário perceba, e
- um pico repentino, como uma grande importação que dispara milhares de e-mails de boas-vindas, seja escoado em ritmo constante.
Para códigos OTP e redefinições de senha, os usuários estão esperando ativamente, então envie na hora e mostre um erro amigável se falhar. O artigo como lidar com erros e limites da API de e-mail explica quais erros repetir e quais mostrar.
Checklist antes de publicar
- A chave de API vem de uma variável de ambiente ou de um gerenciador de segredos, e a chave tem apenas a permissão Send.
- Todo valor fornecido pelo usuário no HTML é escapado.
- As requisições têm um timeout de 10–15 segundos.
- Respostas diferentes de 200 são registradas em log com o corpo da resposta, para que as mensagens de
erroredetailnão se percam. - Seu domínio de envio tem SPF, DKIM e DMARC configurados, para que os e-mails cheguem à caixa de entrada.
Envie com a Inbixio
Conecte seu próprio servidor SMTP, crie uma chave de API com permissões restritas e envie de qualquer linguagem com uma única requisição HTTPS.