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

CampoTipoDescrição
eventstring reqNome do template (ex: welcome, order_created)
toobject req{ "email": "...", "name": "..." }
dataobjectVariáveis pra preencher o template. Pode conter html_content + subject pra envio raw sem template.
metadataobject{ external_id, source } — pra rastreio interno
send_atstring ISO8601Agenda envio futuro (ver Scheduled)
test_modebooleanSe 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):

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

BucketO que éRecuperável?
deliverableVai tentar envio normal—
invalid_or_bouncedEmail marcado invalid/undeliverable/bounced (já bouncou antes)Não (lista podre)
blacklistedContato em blacklist manualManualmente
unsubscribedContato deu opt-outNão (LGPD)
suppressed_workspaceSuprimido no seu workspace específicoManualmente
suppressed_globalSuprimido cross-tenant (hard bounce histórico em outra conta)Não
risky_catch_allDomínio catch-all/grey listing (alta chance de spam trap)Sim, com Validator Plus
staleSem engagement > 90 diasSim, com reactivation campaign
role_addressinfo@, contato@, admin@ — endereços de funçãoNã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

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

HTTPerror_codeSignificado
400event_requiredFalta campo event
400invalid_emailEmail destino malformado
400invalid_send_atsend_at no passado ou formato inválido
400email_invalidEmail previamente bouncing
400email_blacklistedContato blacklisted no workspace
400workspace_pausedWorkspace pausou envios (auto ou manual)
400rate_limit_exceededExcedeu emails/min do workspace
400daily_limit_exceededExcedeu limit diário do workspace
401—API key inválida ou expirada
404template_not_foundEvent não tem template configurado
503system_unhealthyInfra degradada (ver /status)

SDKs Oficiais

LinguagemRepoInstall
PHP 8.1+github.com/sendforge/sendforge-phpcomposer require sendforge/sendforge-php
Node 18+github.com/sendforge/sendforge-nodenpm install sendforge

Rate Limits

PlanoPor minutoPor dia
Default6050.000
Customconfigurableconfigurable

Workspaces com bounce rate > 5% em 1h são auto-pausados.

Webhooks de Eventos

Configure URLs em app.sendforge.com.br/webhooks pra receber:


SendForge © 2026 · Status: app.sendforge.com.br/status · Support: support@sendforge.com.br