SendForge — Transactional Email API
Email transacional rápido, com tracking nativo, idempotency keys e batch sends. Compatible com workflows tipo Resend/SES.
Autenticação
Toda chamada precisa do header X-API-Key com a chave gerada em app.sendforge.com.br/api-keys.
X-API-Key: sf_trans_xxxxxxxxxxxxxxxxxxxxxxxx
Quick Start
PHP
composer require sendforge/sendforge-php
use SendForge\SendForge;
$sf = new SendForge('sf_trans_xxx');
$r = $sf->emails->send([
'event' => 'welcome',
'to' => ['email' => 'user@example.com', 'name' => 'João'],
'data' => ['order_number' => '#12345'],
]);
echo $r['message_id'];
Node.js / TypeScript
npm install sendforge
import { SendForge } from 'sendforge';
const sf = new SendForge('sf_trans_xxx');
const r = await sf.emails.send({
event: 'welcome',
to: { email: 'user@example.com', name: 'João' },
data: { order_number: '#12345' }
});
console.log(r.message_id);
curl
curl -X POST https://app.sendforge.com.br/api/v1/transactional/send.php \
-H "X-API-Key: sf_trans_xxx" \
-H "Content-Type: application/json" \
-d '{
"event": "welcome",
"to": {"email": "user@example.com", "name": "João"},
"data": {"order_number": "#12345"}
}'
POST /api/v1/transactional/send POST
Envia 1 email transacional.
Request body
| Campo | Tipo | Descrição |
|---|---|---|
event | string req | Nome do template (ex: welcome, order_created) |
to | object req | { "email": "...", "name": "..." } |
data | object | Variáveis pra preencher o template. Pode conter html_content + subject pra envio raw sem template. |
metadata | object | { external_id, source } — pra rastreio interno |
send_at | string ISO8601 | Agenda envio futuro (ver Scheduled) |
test_mode | boolean | Se true, valida payload mas não envia (ver Test Mode) |
Response 200
{
"success": true,
"message_id": "msg_abc123",
"event": "welcome",
"to": "user@example.com",
"latency_ms": 240
}
POST /api/v1/transactional/batch POST
Envia até 100 emails numa única chamada. Cada item pode ter idempotency_key individual.
{
"messages": [
{ "event": "welcome", "to": {"email": "a@example.com"}, "idempotency_key": "abc-1" },
{ "event": "welcome", "to": {"email": "b@example.com"}, "idempotency_key": "abc-2" }
]
}
Response 200
{
"success": true,
"total": 2,
"succeeded": 2,
"failed": 0,
"results": [
{ "index": 0, "success": true, "message_id": "msg_aaa", ... },
{ "index": 1, "success": true, "message_id": "msg_bbb", ... }
]
}
POST /api/v1/audience/audit POST
Audita uma lista de destinatários ANTES de enviar. Retorna quantos vão ser efetivamente entregues, quantos vão ser bloqueados pelos guards (invalid/bounced/suprimidos/stale/etc) e a capacidade disponível por provider. Use pra prever entregabilidade e evitar surpresas.
Por que existe
O endpoint /send aplica vários filtros de segurança antes de tocar Postal/Mailgun (proteção de reputação de IP). Quando vc envia uma lista, parte pode ser bloqueada silenciosamente. Esse endpoint dá visibilidade upfront: "do que vou mandar, X vai entregar, Y vai ser bloqueado e por quê".
Request
curl -X POST https://app.sendforge.com.br/api/v1/audience/audit.php \
-H "X-API-Key: sf_trans_xxx" \
-H "Content-Type: application/json" \
-d '{
"emails": ["cliente1@gmail.com", "cliente2@hotmail.com", ...]
}'
Aceita 3 formatos de entrada (escolha um):
"emails": [...]— array de até 5000 emails"contact_ids": [...]— array de até 5000 UUIDs (mais rápido se já tem)"segment_id": "uuid"— segmento estático do workspace
Response
{
"success": true,
"audit": {
"submitted": 100,
"matched_in_db": 98,
"not_in_db": 2,
"buckets": {
"deliverable": 35,
"invalid_or_bounced": 50,
"blacklisted": 5,
"unsubscribed": 0,
"suppressed_workspace": 0,
"suppressed_global": 8,
"risky_catch_all": 0,
"stale": 0,
"role_address": 0
},
"by_provider": {
"gmail": {"total": 60, "deliverable": 25},
"microsoft": {"total": 30, "deliverable": 6},
"yahoo": {"total": 5, "deliverable": 3},
"other": {"total": 3, "deliverable": 1}
},
"deliverable_rate_pct": 35.7,
"recommendation": "ATENCAO: base com 35.7% entregavel. 64.3% sera bloqueado antes do envio (protecao de IP). Considere segmentar pra compradores mais recentes.",
"capacity_warnings": [
"microsoft: 6 entregaveis vs 590 disponiveis hoje"
]
}
}
Buckets explicados
| Bucket | O que é | Recuperável? |
|---|---|---|
deliverable | Vai tentar envio normal | — |
invalid_or_bounced | Email marcado invalid/undeliverable/bounced (já bouncou antes) | Não (lista podre) |
blacklisted | Contato em blacklist manual | Manualmente |
unsubscribed | Contato deu opt-out | Não (LGPD) |
suppressed_workspace | Suprimido no seu workspace específico | Manualmente |
suppressed_global | Suprimido cross-tenant (hard bounce histórico em outra conta) | Não |
risky_catch_all | Domínio catch-all/grey listing (alta chance de spam trap) | Sim, com Validator Plus |
stale | Sem engagement > 90 dias | Sim, com reactivation campaign |
role_address | info@, contato@, admin@ — endereços de função | Não (padrão indústria) |
capacity_warnings
Avisa quando a parte deliverable excede a capacidade disponível hoje pra um provider (Gmail/Microsoft/etc). O excedente vai pra fila e sai amanhã automaticamente (smart throttling). Você não perde envios — só não saem todos no mesmo dia.
Limites
- Máximo 5000 itens por request
- Sem rate limit explícito (é só leitura)
- Cache: stateless, sempre lê DB atual
Use case típico
# 1. Audita ANTES de disparar
curl -X POST .../audit -d '{"emails": [...]}'
# resposta diz: 35% deliverable
# 2. Decide: vale a pena disparar?
# Se sim, faz o send normal
curl -X POST .../send -d '{"event": "...", "to": {...}, ...}'
# 3. Os 65% bloqueados retornam skipped=true no /send sem queimar IP
Idempotency Keys
Evita duplicar envio em caso de retry. Envie header Idempotency-Key com qualquer string única (ex: UUID4).
curl -X POST https://app.sendforge.com.br/api/v1/transactional/send.php \
-H "X-API-Key: sf_trans_xxx" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
...
Se a mesma chave for usada de novo nas próximas 24h, retornamos a response anterior com "idempotent_replay": true. Sem reenvio.
Test Mode
Pra validar integração sem disparar email real. Cobrado como request normal mas não conta como envio.
{
"event": "welcome",
"to": {"email": "user@example.com"},
"test_mode": true
}
// Response:
{
"success": true,
"message_id": "test_a1b2c3d4...",
"test_mode": true
}
Scheduled Sends
Agenda envio em horário futuro com send_at em ISO 8601 UTC:
{
"event": "reminder",
"to": {"email": "user@example.com"},
"send_at": "2026-06-15T10:00:00Z"
}
// Response:
{
"success": true,
"scheduled": true,
"job_id": "abc123def456...",
"send_at": "2026-06-15T10:00:00+00:00"
}
Job é processado pelo worker scheduled (30s precision).
Códigos de Erro
| HTTP | error_code | Significado |
|---|---|---|
| 400 | event_required | Falta campo event |
| 400 | invalid_email | Email destino malformado |
| 400 | invalid_send_at | send_at no passado ou formato inválido |
| 400 | email_invalid | Email previamente bouncing |
| 400 | email_blacklisted | Contato blacklisted no workspace |
| 400 | workspace_paused | Workspace pausou envios (auto ou manual) |
| 400 | rate_limit_exceeded | Excedeu emails/min do workspace |
| 400 | daily_limit_exceeded | Excedeu limit diário do workspace |
| 401 | — | API key inválida ou expirada |
| 404 | template_not_found | Event não tem template configurado |
| 503 | system_unhealthy | Infra degradada (ver /status) |
SDKs Oficiais
| Linguagem | Repo | Install |
|---|---|---|
| PHP 8.1+ | github.com/sendforge/sendforge-php | composer require sendforge/sendforge-php |
| Node 18+ | github.com/sendforge/sendforge-node | npm install sendforge |
Rate Limits
| Plano | Por minuto | Por dia |
|---|---|---|
| Default | 60 | 50.000 |
| Custom | configurable | configurable |
Workspaces com bounce rate > 5% em 1h são auto-pausados.
Webhooks de Eventos
Configure URLs em app.sendforge.com.br/webhooks pra receber:
email.delivered— entregue ao inboxemail.opened— abriu (pixel)email.clicked— clicou linkemail.bounced— hard ou soft bounceemail.complained— marcou spam
SendForge © 2026 · Status: app.sendforge.com.br/status · Support: support@sendforge.com.br