Pular para o conteúdo principal

Envio de Notificações

📤 Entrega inteligente: Envie notificações multi-canal com tracking completo de entrega

Agora que você tem assinantes cadastrados, vamos enviar notificações. Este guia cobre:

  • Envio direto via API
  • Payloads específicos por canal (email, WhatsApp, SMS, in-app)
  • Tracking de status e tentativas de entrega
  • Boas práticas de retry

Endpoint principal

POST /v1/notifications

Todas as notificações passam por aqui. A API determina o canal automaticamente baseado no payload ou você pode forçar um canal específico.


Envio básico por email

curl -X POST https://app.usenotifica.com.br/v1/notifications \
-H "Authorization: Bearer nk_live_sua_chave" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"to": {
"email": "[email protected]"
},
"subject": "Seu pedido foi enviado! 🚚",
"content": "Oi Fernanda, seu pedido #12345 saiu para entrega."
}'

Resposta:

{
"id": "not_abc123",
"status": "pending",
"channel": "email",
"to": "[email protected]",
"subject": "Seu pedido foi enviado! 🚚",
"created_at": "2024-01-15T14:30:00Z",
"estimated_delivery": "2024-01-15T14:31:00Z"
}

Usando subscriber_id (recomendado)

Quando você já tem o assinante cadastrado:

curl -X POST https://app.usenotifica.com.br/v1/notifications \
-H "Authorization: Bearer nk_live_sua_chave" \
-H "Content-Type: application/json" \
-d '{
"subscriber_id": "sub_xyz789",
"subject": "Pagamento confirmado",
"content": "Seu pagamento de R$ 99,90 foi aprovado!"
}'

Vantagens:

  • ✅ Respeita preferências do assinante
  • ✅ Usa o email/telefone atual do cadastro
  • ✅ Registra no histórico do assinante

Envio multi-canal

WhatsApp (texto simples)

curl -X POST https://app.usenotifica.com.br/v1/notifications \
-H "Authorization: Bearer nk_live_sua_chave" \
-H "Content-Type: application/json" \
-d '{
"to": {
"phone": "+5511998765432"
},
"channel": "whatsapp",
"content": "Olá! Sua consulta está confirmada para amanhã às 14h."
}'

WhatsApp com template aprovado

curl -X POST https://app.usenotifica.com.br/v1/notifications \
-H "Authorization: Bearer nk_live_sua_chave" \
-H "Content-Type: application/json" \
-d '{
"to": {
"phone": "+5511998765432"
},
"channel": "whatsapp",
"template": "order_confirmation_v2",
"data": {
"order_id": "12345",
"customer_name": "Roberto",
"delivery_date": "15/01"
}
}'

SMS

curl -X POST https://app.usenotifica.com.br/v1/notifications \
-H "Authorization: Bearer nk_live_sua_chave" \
-H "Content-Type: application/json" \
-d '{
"to": {
"phone": "+5511998765432"
},
"channel": "sms",
"content": "Seu código de verificação é: 583921. Válido por 5 minutos."
}'

⚠️ Limite SMS: 160 caracteres. Use abreviações se necessário.

In-App (para Inbox)

curl -X POST https://app.usenotifica.com.br/v1/notifications \
-H "Authorization: Bearer nk_live_sua_chave" \
-H "Content-Type: application/json" \
-d '{
"subscriber_id": "sub_xyz789",
"channel": "in_app",
"title": "Novo comentário",
"content": "Maria comentou na sua tarefa #123",
"action_url": "https://app.empresa.com/tarefas/123"
}'

Código completo: Exemplos por linguagem

Node.js

class NotificaSender {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://app.usenotifica.com.br/v1';
}

async sendEmail(to, subject, content, options = {}) {
return this.send({
to: typeof to === 'string' ? { email: to } : null,
subscriber_id: typeof to === 'object' ? to.id : null,
subject,
content,
channel: 'email',
...options
});
}

async sendWhatsApp(to, content, templateData = null) {
const payload = {
to: { phone: to },
channel: 'whatsapp',
content: templateData ? null : content,
template: templateData?.template,
data: templateData?.data
};
return this.send(payload);
}

async sendSMS(to, content) {
return this.send({
to: { phone: to },
channel: 'sms',
content: content.slice(0, 160) // Garantir limite
});
}

async send(payload) {
const response = await fetch(`${this.baseUrl}/notifications`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID()
},
body: JSON.stringify(payload)
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.message || `HTTP ${response.status}`);
}

return response.json();
}
}

// Uso
const sender = new NotificaSender(process.env.NOTIFICA_API_KEY);

// Email
await sender.sendEmail(
'[email protected]',
'Bem-vindo!',
'Obrigado por se cadastrar.'
);

// WhatsApp com template
await sender.sendWhatsApp(
'+5511998765432',
null,
{
template: 'welcome_message',
data: { name: 'João', company: 'Acme' }
}
);

Python

import requests
import uuid
from typing import Optional, Dict, Any

class NotificaSender:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = 'https://app.usenotifica.com.br/v1'

def send_email(self, to: str, subject: str, content: str,
html: Optional[str] = None) -> Dict:
"""Envia email para um endereço específico."""
payload = {
'to': {'email': to},
'subject': subject,
'content': content,
'channel': 'email'
}
if html:
payload['html'] = html
return self._send(payload)

def send_whatsapp(self, phone: str, content: Optional[str] = None,
template: Optional[str] = None,
data: Optional[Dict] = None) -> Dict:
"""Envia mensagem WhatsApp (texto ou template)."""
payload = {
'to': {'phone': phone},
'channel': 'whatsapp',
'content': content,
'template': template,
'data': data
}
return self._send(payload)

def send_sms(self, phone: str, content: str) -> Dict:
"""Envia SMS (máx 160 caracteres)."""
payload = {
'to': {'phone': phone},
'channel': 'sms',
'content': content[:160]
}
return self._send(payload)

def send_to_subscriber(self, subscriber_id: str, **kwargs) -> Dict:
"""Envia notificação usando subscriber_id."""
payload = {'subscriber_id': subscriber_id, **kwargs}
return self._send(payload)

def _send(self, payload: Dict) -> Dict:
response = requests.post(
f'{self.base_url}/notifications',
headers={
'Authorization': f'Bearer {self.api_key}',
'Content-Type': 'application/json',
'Idempotency-Key': str(uuid.uuid4())
},
json={k: v for k, v in payload.items() if v is not None}
)
response.raise_for_status()
return response.json()

# Uso
sender = NotificaSender(os.getenv('NOTIFICA_API_KEY'))

# Email simples
result = sender.send_email(
to='[email protected]',
subject='Seu relatório está pronto',
content='Acesse sua conta para visualizar.',
html='<p>Acesse sua conta para <a href="...">visualizar</a>.</p>'
)
print(f"Notificação {result['id']} criada")

# SMS
sender.send_sms(
phone='+5511998765432',
content='Seu pedido saiu para entrega!'
)

Tracking de entrega

Ver status de uma notificação

curl https://app.usenotifica.com.br/v1/notifications/not_abc123 \
-H "Authorization: Bearer nk_live_sua_chave"

Resposta:

{
"id": "not_abc123",
"status": "delivered",
"channel": "email",
"to": "[email protected]",
"subject": "Seu pedido foi enviado!",
"sent_at": "2024-01-15T14:30:02Z",
"delivered_at": "2024-01-15T14:30:05Z",
"opened_at": "2024-01-15T14:45:00Z",
"provider": "sendgrid"
}

Status possíveis:

  • pending — Aguardando processamento
  • queued — Na fila do provedor
  • sent — Enviado ao provedor
  • delivered — Confirmado entregue
  • bounced — Email/telefone inválido
  • failed — Erro na entrega
  • complained — Usuário marcou como spam

Listar tentativas de entrega

curl https://app.usenotifica.com.br/v1/notifications/not_abc123/attempts \
-H "Authorization: Bearer nk_live_sua_chave"

Resposta:

{
"data": [
{
"id": "att_001",
"status": "failed",
"provider": "sendgrid",
"error": "421 Service unavailable",
"attempted_at": "2024-01-15T14:30:00Z"
},
{
"id": "att_002",
"status": "delivered",
"provider": "sendgrid",
"delivered_at": "2024-01-15T14:31:00Z"
}
]
}

Listando notificações

Todas as notificações

curl "https://app.usenotifica.com.br/v1/notifications?page=1&limit=50" \
-H "Authorization: Bearer nk_live_sua_chave"

Filtrando por status

curl "https://app.usenotifica.com.br/v1/notifications?status=failed&channel=email" \
-H "Authorization: Bearer nk_live_sua_chave"

Por assinante

curl "https://app.usenotifica.com.br/v1/notifications?subscriber_id=sub_xyz789" \
-H "Authorization: Bearer nk_live_sua_chave"

Boas práticas de retry

Quando retry automático acontece

A Notifica faz retry automático para:

  • Timeouts de provedor
  • Erros 5xx
  • Rate limits (com backoff)

Não faz retry para:

  • Emails inválidos (bounce)
  • Spam complaints
  • Erros de autenticação

Implementando retry no seu código

async function sendWithRetry(payload, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await sendNotification(payload);
} catch (error) {
if (error.status >= 500 || error.code === 'ETIMEDOUT') {
const delay = Math.pow(2, i) * 1000; // Exponential backoff
await sleep(delay);
continue;
}
throw error; // Não retry em erros 4xx
}
}
throw new Error('Max retries exceeded');
}

FAQ

Q: Posso enviar para múltiplos destinatários de uma vez?
A: Use Workflows para broadcast ou faça chamadas paralelas com idempotency keys únicos.

Q: E se o usuário não tiver o canal habilitado?
A: Retorna erro 400 com channel_not_enabled. Verifique preferências antes ou use fallback.

Q: Qual a taxa de envio máxima?
A: Depende do seu plano. Enterprise: ilimitado. Starter: 100/min. Verifique headers X-RateLimit-*.

Q: Posso anexar arquivos?
A: Em breve! Por enquanto, use URLs para arquivos hospedados.

Q: Como sei se o usuário abriu o email?
A: Configure Webhooks para receber eventos email.opened.


Próximo passo

Para notificações mais elaboradas, aprenda a criar Templates com variáveis dinâmicas.