Modos Live y Test
Modos Live (sk_proj_/sk_live_) y Test (sk_test_) por prefijo de API key — flag is_test en webhooks, routing a webhook_url vs webhook_url_dev, cuota mensual, suppression list compartida y regeneración independiente de keys.
ReallyQuickEmails separa tráfico productivo y de desarrollo a través del prefijo de la API key, no de un parámetro del request. Esto evita errores típicos donde un dev olvida un flag y manda tráfico de pruebas como si fuera producción.
El modelo
| Live | Test | |
|---|---|---|
| Prefijo de key | sk_proj_* o sk_live_* | sk_test_* |
| Cuota mensual | cuenta | también cuenta — el envío es real |
Payload is_test | false | true |
| Métricas del dashboard | producción | separadas (filtro Live/Test) |
| Webhook outbound | webhook_url | webhook_url_dev |
| Webhook inbound (replies) | inbound_webhook_url | inbound_webhook_url_dev |
| Envío real al inbox | sí | sí, también |
| Rate limit y suppression list | compartidos | compartidos |
Test mode SÍ envía emails reales
El email sale de verdad y llega al inbox del destinatario: puedes probar deliverability, render visual y comportamiento de los clientes de email igual que en producción. La diferencia está en métricas y routing de webhooks, no en el envío en sí. Por lo mismo, los envíos test también consumen cuota mensual.
Cómo se decide el modo
El modo viaja en la key. No hay parámetro mode en el body, ni headers especiales, ni flag por endpoint:
curl -X POST https://api.reallyquickemails.com/v1/send-email \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"recipient_email": "cliente@empresa.com",
"sender_email": "noreply@tudominio.com",
"subject": "Confirmación de pedido",
"html_body": "<p>Tu pedido fue confirmado.</p>"
}'→ webhook a webhook_url
→ payload con is_test: false
→ actividad visible en las métricas de producción
curl -X POST https://api.reallyquickemails.com/v1/send-email \
-H "Authorization: Bearer sk_test_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"recipient_email": "qa@empresa.com",
"sender_email": "noreply@tudominio.com",
"subject": "QA — confirmación",
"html_body": "<p>Test desde staging.</p>"
}'→ webhook a webhook_url_dev
→ payload con is_test: true
→ actividad marcada como test, separada de tus métricas live
Webhook routing
Cada proyecto tiene cuatro URLs configurables (en pares outbound/inbound, una para cada modo):
project
outbound (delivered, bounced, opened, clicked)
inbound (replies con adjuntos)
Si la URL _dev está vacía
Fallback a la URL de live
Si tu proyecto no tiene webhook_url_dev configurada y envías con sk_test_*, los eventos caen a webhook_url — el payload llega con is_test: true para que puedas distinguirlos. Si ambas URLs están vacías, el evento no se entrega. El email sigue saliendo al inbox real. Ver el detalle del routing en Webhooks.
is_test en el payload
Todos los webhooks (outbound e inbound) incluyen is_test: boolean en el body. Eso te permite, si quieres, recibir todo en una sola URL (webhook_url) y filtrar lado-cliente, dejando webhook_url_dev vacío:
{
"event": "email.delivery",
"is_test": true,
"data": { "...": "..." }
}Pero mantenerlas separadas es lo recomendado para evitar accidentes operativos.
Caso de uso: setup multi-environment
# .env.local
RQE_API_KEY=sk_test_xxxxxxxxxxxxTu app local usa sk_test_. Los emails que mandes durante desarrollo:
- Llegan al inbox real (pruebas render, deliverability)
- Quedan marcados con
is_test: true— no mezclan métricas con prod - Webhooks (si configuras
webhook_url_devapuntando a un ngrok o servicio de testing) funcionan idéntico
# Variables del ambiente staging
RQE_API_KEY=sk_test_xxxxxxxxxxxxMismo sk_test_* que local. Tu staging environment manda emails reales marcados como test. Si tienes webhook listener en tu staging, configura webhook_url_dev apuntando a esa URL.
# Variables del ambiente prod
RQE_API_KEY=sk_live_xxxxxxxxxxxxProducción usa sk_live_* (o sk_proj_*). Webhooks a webhook_url (production listener).
Tu código no necesita saber el modo
La elección de modo es solo cuestión de qué env var lees. Los call sites a la API son idénticos. Esto deja el switch en las variables de entorno de tu hosting y no en código, donde es más fácil olvidar un flag.
Casos extremos
Suppression list
Es compartida entre live y test. Si un destinatario se dio de baja por un envío live, los envíos test al mismo recipient también se omiten: en /v1/send-template-email recibes 200 con skipped: true; en /v1/send-email la supresión se aplica en segundo plano y la actividad queda con estado suppressed. Esto previene que tests de QA reactiven la entrega a usuarios que ya no quieren tus emails.
Rate limit
Live y test comparten el rate limit y la cuota mensual de tu proyecto. Un spike de tests consume cuota real y afecta tu envío productivo.
Regenerar keys
Live y test se regeneran independientemente desde el dashboard. Regenerar la live no afecta la test, y viceversa. La key anterior queda invalidada al instante.
Próximos pasos
- API Keys — referencia completa con ejemplos de idempotency y dry-run.
- Webhooks — formato de payload y verificación HMAC.
- Quickstart — primer envío end-to-end con
sk_test_*.