La API está en construcción y abre primero a equipos del programa de acceso anticipado. Esta documentación describe el contrato v1 con el que se está construyendo.

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_confirmation y espera las variables name y order_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_KEY

Enví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
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" }
  }'
Python
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
<?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'];
JavaScript (Node.js)
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
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

EstadoQué significa
acceptedAceptado y encolado; aún no sale.
processingUn worker lo está enviando al proveedor.
sentEl proveedor lo aceptó. Todavía no confirma que llegó.
deliveredEl proveedor confirmó la entrega al destinatario.
failedSe agotaron los reintentos. Revisa attempts para ver el motivo.
blockedNo 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.

Ir a la referencia de la API