Quickstart: tu primera notificación
En esta guía envías un mensaje, entiendes la respuesta y consultas si llegó. Los ejemplos usan email, pero la petición es idéntica para SMS y WhatsApp: solo cambia channel.
Antes de empezar
Necesitas:
- Una API key de tu cuenta de Notify, guardada en la variable de entorno
NOTIFY_API_KEY. - Una plantilla creada en tu cuenta. En los ejemplos se llama
order_confirmationy espera las variablesnameyorder_id.
Autenticación
Cada petición lleva tu API key en el header Authorization como token Bearer. La key identifica a tu cuenta: nunca envíes el identificador de cliente en el cuerpo.
No uses la API key en el navegador ni en apps móviles: llama a Notify desde tu backend.
Authorization: Bearer $NOTIFY_API_KEYEnvía un mensaje
Haz un POST /v1/messages con el canal, el destinatario y la clave de la plantilla. Si indicas locale, Notify usa la versión de la plantilla en ese idioma.
curl https://api.notify.com.mx/v1/messages \
-H "Authorization: Bearer $NOTIFY_API_KEY" \
-H "Idempotency-Key: order-1042-confirmation" \
-H "Content-Type: application/json" \
-d '{
"channel": "email",
"recipient": { "address": "ana@example.com", "locale": "es" },
"template_key": "order_confirmation",
"variables": { "name": "Ana", "order_id": "1042" }
}'import os
import requests
response = requests.post(
"https://api.notify.com.mx/v1/messages",
headers={
"Authorization": f"Bearer {os.environ['NOTIFY_API_KEY']}",
"Idempotency-Key": "order-1042-confirmation",
},
json={
"channel": "email",
"recipient": {"address": "ana@example.com", "locale": "es"},
"template_key": "order_confirmation",
"variables": {"name": "Ana", "order_id": "1042"},
},
timeout=10,
)
response.raise_for_status() # 202 Accepted
message = response.json()
print(message["id"], message["status"])<?php
$ch = curl_init('https://api.notify.com.mx/v1/messages');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('NOTIFY_API_KEY'),
'Idempotency-Key: order-1042-confirmation',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'channel' => 'email',
'recipient' => ['address' => 'ana@example.com', 'locale' => 'es'],
'template_key' => 'order_confirmation',
'variables' => ['name' => 'Ana', 'order_id' => '1042'],
]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 202
$message = json_decode($body, true);
echo $message['id'] . ' ' . $message['status'];const response = await fetch('https://api.notify.com.mx/v1/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NOTIFY_API_KEY}`,
'Idempotency-Key': 'order-1042-confirmation',
'Content-Type': 'application/json',
},
body: JSON.stringify({
channel: 'email',
recipient: { address: 'ana@example.com', locale: 'es' },
template_key: 'order_confirmation',
variables: { name: 'Ana', order_id: '1042' },
}),
});
if (response.status !== 202) throw new Error(await response.text());
const message = await response.json();
console.log(message.id, message.status);Entiende la respuesta: 202, no 200
Notify responde 202 Accepted en cuanto valida y encola la petición. Eso significa que el mensaje fue aceptado, no que ya se entregó: la entrega ocurre en segundo plano, con reintentos si el proveedor falla.
Guarda el id de la respuesta: con él consultas el estado real.
HTTP/1.1 202 Accepted
{
"id": "6f1c2a4e-9b7d-4c1e-8a35-2d0f5b9e7c11",
"status": "accepted",
"channel": "email",
"template_key": "order_confirmation",
"resolved_locale": "es",
"created_at": "2026-10-05T17:42:08Z"
}Consulta si llegó
Con GET /v1/messages/{id} obtienes el estado actual y el historial de intentos por proveedor.
curl https://api.notify.com.mx/v1/messages/6f1c2a4e-9b7d-4c1e-8a35-2d0f5b9e7c11 \
-H "Authorization: Bearer $NOTIFY_API_KEY"{
"id": "6f1c2a4e-9b7d-4c1e-8a35-2d0f5b9e7c11",
"status": "delivered",
"channel": "email",
"template_key": "order_confirmation",
"resolved_locale": "es",
"created_at": "2026-10-05T17:42:08Z",
"delivered_at": "2026-10-05T17:42:11Z",
"attempts": [
{
"attempt_number": 1,
"provider": "ses",
"status": "sent",
"attempted_at": "2026-10-05T17:42:09Z"
}
]
}Estados de un mensaje
| Estado | Qué significa |
|---|---|
accepted | Aceptado y encolado; aún no sale. |
processing | Un worker lo está enviando al proveedor. |
sent | El proveedor lo aceptó. Todavía no confirma que llegó. |
delivered | El proveedor confirmó la entrega al destinatario. |
failed | Se agotaron los reintentos. Revisa attempts para ver el motivo. |
blocked | No se envió porque el destinatario se dio de baja de ese canal. |
Reintenta sin duplicar
Las redes fallan. Si no recibes respuesta, reintenta la petición con el mismo header Idempotency-Key: Notify devuelve el mensaje original y nunca envía dos veces.
Usa una clave que identifique el evento de negocio, por ejemplo order-1042-confirmation, no un valor aleatorio por intento.
Errores
Los errores siempre traen un code estable, pensado para tu código, y un message legible, pensado para tus logs. Un 422 indica que la petición está bien formada pero no se puede procesar, por ejemplo porque falta una variable de la plantilla. Ante un 429, espera los segundos que indica el header Retry-After.
HTTP/1.1 422 Unprocessable Entity
{
"code": "missing_required_variable",
"message": "La plantilla order_confirmation requiere la variable order_id.",
"details": { "variable": "order_id" }
}Siguientes pasos
Consulta la referencia completa para crear plantillas multiidioma, listar mensajes y ver cada campo de la API.