API Pública v1

Envía emails individuales, con plantilla y en lote con POST /v1/send-email, /v1/send-template-email y /v1/send-batch.

La API pública v1 de ReallyQuickEmails (RQE) expone endpoints autenticados mediante Bearer token para integraciones externas.

Base URL: https://api.reallyquickemails.com


Autenticacion

Todos los endpoints de la API pública requieren autenticación mediante Bearer token con una clave del proyecto:

text
Authorization: Bearer sk_proj_xxxxxxxxxxxx

Se aceptan tres prefijos de clave:

PrefijoModo
sk_proj_...Producción (live)
sk_live_...Producción (live)
sk_test_...Modo de prueba

Las claves se generan desde el panel de administración del proyecto. Si la clave es inválida o no se proporciona, el servidor responde con 401 Unauthorized. Todos los requests con body requieren además el header Content-Type: application/json.

Respuesta de error de autenticacion

json
{
  "error": "Missing or invalid API key. Use: Authorization: Bearer sk_proj_..."
}

Si la clave tiene un prefijo válido pero no corresponde a ningún proyecto, la respuesta es:

json
{
  "error": "Invalid API key"
}

POST /v1/send-email

Envía un email individual a hasta 50 destinatarios.

Request Body

CampoTipoRequeridoDescripción
recipient_emailstring | string[]SiDirección(es) del destinatario. Acepta string (1 destinatario) o array (máx 50). Para volúmenes mayores usa /v1/send-batch.
sender_emailstringSiDirección del remitente (dominio verificado).
sender_namestringNoNombre visible del remitente. Si se omite, el inbox muestra solo sender_email.
html_bodystringSiContenido HTML del correo.
text_bodystringNoVersión plain text del correo (multipart fallback). Recomendado para mejorar deliverability y accessibility.
subjectstringNoAsunto del correo. Si se omite, se usa "Email from ReallyQuickEmails".
ccstring | string[]NoDirección(es) en copia. Máx 10.
bccstring | string[]NoDirección(es) en copia oculta. Máx 10.
attachmentsarrayNoLista de adjuntos (máx 10; máx 10 MB por adjunto y 10 MB en total). Estructura: { filename, url | content (base64), contentType? }.
environmentstringNoEnruta los webhooks de este envío al environment configurado en el proyecto. Formato [a-zA-Z0-9_.-], máx 64 caracteres. Si la key no está pre-configurada en el dashboard, retorna 400 ENVIRONMENT_NOT_CONFIGURED. Ver Webhook environments.

El tracking de aperturas y clics se aplica en segundo plano (los remitentes en modo transaccional omiten el tracking). Este endpoint no agrega footer de unsubscribe ni headers List-Unsubscribe — esos se agregan automáticamente en campañas y en /v1/send-template-email; en /v1/send-batch puedes pasarlos mediante custom_headers.

Ejemplo simple

bash
curl -X POST https://api.reallyquickemails.com/v1/send-email \
  -H "Authorization: Bearer sk_proj_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient_email": "usuario@ejemplo.com",
    "sender_email": "hola@miapp.com",
    "sender_name": "Mi Empresa",
    "subject": "Bienvenido a nuestra plataforma",
    "html_body": "<h1>Bienvenido!</h1><p>Gracias por registrarte.</p>"
  }'

Ejemplo con múltiples destinatarios + cc + adjunto

bash
curl -X POST https://api.reallyquickemails.com/v1/send-email \
  -H "Authorization: Bearer sk_proj_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient_email": ["a@empresa.com", "b@empresa.com"],
    "cc": "supervisor@empresa.com",
    "sender_email": "notificaciones@miapp.com",
    "sender_name": "Mi Empresa",
    "subject": "Reporte diario",
    "html_body": "<h1>Reporte</h1><p>Adjunto encontrarás el detalle.</p>",
    "attachments": [
      {
        "filename": "reporte.pdf",
        "url": "https://storage.miapp.com/reportes/2026-04-28.pdf",
        "contentType": "application/pdf"
      }
    ]
  }'

Respuesta exitosa (200)

json
{
  "message": "Email sent successfully",
  "email_id": "550e8400-e29b-41d4-a716-446655440000",
  "project_id": "123e4567-e89b-12d3-a456-426614174000"
}

email_id es el ID de actividad del envío — úsalo para correlacionar los eventos que llegan a tus webhooks. Puede ser null si el registro de actividad no pudo crearse.

Supresión: la verificación de supresión ocurre al procesar el envío en segundo plano. Si el destinatario está suprimido (rebote, queja o baja), el email no se envía y la actividad queda con estado suppressed. Este endpoint no devuelve una respuesta skipped síncrona — /v1/send-template-email sí verifica la supresión antes de responder.

Codigos de Error

CódigoDescripción
400Missing required fields: recipient_email, sender_email, html_body
400recipient_email must be a non-empty string or array of strings
400Too many recipients in recipient_email (N). Maximum is 50. For larger sends use /v1/send-batch.
400cc accepts at most 10 addresses / bcc accepts at most 10 addresses
400attachments must be an array / attachments accepts at most 10 items
400ENVIRONMENT_NOT_CONFIGURED — el environment no está configurado en el proyecto.
401API Key inválida o no proporcionada.
500Error interno del servidor.
502Failed to process request — error al procesar la solicitud internamente.

¿Necesitas envío programado, dry_run o plantillas en envíos individuales? Ver más en API avanzada de envío.


POST /v1/send-template-email

Envía un correo utilizando una plantilla pre-configurada con sustitución de variables (soporta loops {{#each}}).

Request Body

CampoTipoRequeridoDescripción
template_idstringSi*UUID de la plantilla.
template_internal_idnumberSi*ID interno de la plantilla (alternativa a template_id).
html_bodystringSi*Contenido HTML directo con variables (modo sin plantilla). Requerido si no envías template_id ni template_internal_id.
recipient_emailstringSiDirección de correo del destinatario.
sender_emailstringSiDirección de correo del remitente (dominio verificado).
sender_namestringNoNombre visible del remitente.
subjectstringNoAsunto del correo. Admite variables. Si se omite con plantilla, se usa el de la plantilla.
variablesobjectNoVariables para sustitución en la plantilla.
environmentstringNoIgual que en /v1/send-email: enruta los webhooks al environment configurado.

*Debes enviar template_id O template_internal_id. Si no envías ninguno, html_body (junto con recipient_email y sender_email) es requerido.

Este endpoint agrega automáticamente:

  • Un footer de cancelación de suscripción si el HTML no incluye la URL de unsubscribe.
  • Los headers List-Unsubscribe y List-Unsubscribe-Post (RFC 8058).
  • Las variables view_in_browser_url y unsubscribe_url (si no las envías tú).

Las respuestas del destinatario se enrutan a la bandeja del remitente — ver Reply-To Automático.

Ejemplo con template UUID

bash
curl -X POST https://api.reallyquickemails.com/v1/send-template-email \
  -H "Authorization: Bearer sk_proj_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "550e8400-e29b-41d4-a716-446655440000",
    "recipient_email": "nuevo.usuario@ejemplo.com",
    "sender_email": "onboarding@miapp.com",
    "variables": {
      "nombre": "Carlos",
      "plan": "Pro",
      "trial_days": 14,
      "dashboard_url": "https://miapp.com/dashboard"
    }
  }'

Ejemplo con template internal ID

Cada template tiene un ID interno auto-incrementado dentro del proyecto. Útil para integraciones que prefieren IDs numéricos:

bash
curl -X POST https://api.reallyquickemails.com/v1/send-template-email \
  -H "Authorization: Bearer sk_proj_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "template_internal_id": 5,
    "recipient_email": "cliente@ejemplo.com",
    "sender_email": "noreply@miapp.com",
    "variables": {
      "nombre": "Maria"
    }
  }'

Respuesta exitosa (200)

json
{
  "message": "Email sent successfully",
  "email_id": "550e8400-e29b-41d4-a716-446655440000",
  "project_id": "123e4567-e89b-12d3-a456-426614174000",
  "template_id": "550e8400-e29b-41d4-a716-446655440000",
  "template_internal_id": null,
  "variables_used": ["nombre", "plan", "trial_days", "dashboard_url", "view_in_browser_url", "unsubscribe_url"],
  "used_cached_html": true
}

variables_used incluye también las variables inyectadas automáticamente (view_in_browser_url, unsubscribe_url). used_cached_html es true cuando se usó el HTML pre-renderizado de la plantilla.

Respuesta cuando el destinatario esta suprimido (200)

Si el destinatario se ha dado de baja o ha rebotado, el email se omite automáticamente:

json
{
  "message": "Email skipped — recipient is suppressed",
  "skipped": true,
  "suppression_reason": "unsubscribed",
  "recipient": "cliente@ejemplo.com"
}

Codigos de Error

CódigoDescripción
400Missing required fields: template_id/template_internal_id, OR recipient_email + sender_email + html_body
400Missing required fields: recipient_email, sender_email
400template_internal_id requires valid project context
400ENVIRONMENT_NOT_CONFIGURED — el environment no está configurado en el proyecto.
401API Key inválida o no proporcionada.
404Template not found with ID ... — plantilla no encontrada para el proyecto asociado a la API Key.
422TEMPLATE_EMPTY — la plantilla renderiza a contenido vacío. Vuelve a guardar la plantilla en el editor para regenerar el HTML.
500Error interno del servidor.

Ver más en Plantillas.


POST /v1/send-batch

Envía correos masivos en un solo request — hasta 10,000 destinatarios por llamada.

Request Body

CampoTipoRequeridoDescripción
senderstringSiDirección de correo del remitente (dominio verificado).
senderNamestringNoNombre visible del remitente.
subjectstringSi*Asunto del correo. Requerido si no se usa templateId.
htmlstringSi*Contenido HTML. Requerido si no se usa templateId.
templateIdstringSi*UUID del template. Alternativa a subject + html.
email_typestringNoTipo de correo. Default: "marketing".
scheduled_atstringNoFecha ISO 8601 para envío programado.
custom_headersobjectNoHeaders a nivel batch. Solo se aplican List-Unsubscribe y List-Unsubscribe-Post.
environmentstringNoEnruta los webhooks al environment configurado. Formato [a-zA-Z0-9_.-], máx 64 caracteres.
dry_runbooleanNoPrevisualiza el batch sin encolar emails ni crear registros de actividad. Ver Dry run.
recipientsarraySiLista de destinatarios (máximo 10,000).

*Debes enviar templateId O ambos subject + html.

Estructura de cada recipient:

CampoTipoRequeridoDescripción
emailstringSiDirección de correo del destinatario.
dataobjectNoVariables personalizadas (Handlebars).
custom_headersobjectNoHeaders por destinatario. Sobrescriben los del batch.

Headers

HeaderTipoRequeridoDescripción
Idempotency-KeystringNoClave de idempotencia (1–256 caracteres). Ver Idempotencia.

Ejemplo con HTML directo

bash
curl -X POST https://api.reallyquickemails.com/v1/send-batch \
  -H "Authorization: Bearer sk_proj_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "sender": "noreply@tudominio.com",
    "senderName": "Mi Empresa",
    "subject": "Oferta especial para ti, {nombre}",
    "html": "<h1>Hola {nombre}!</h1><p>Tenemos una oferta especial en {producto}.</p>",
    "recipients": [
      {
        "email": "juan@ejemplo.com",
        "data": { "nombre": "Juan", "producto": "Plan Pro" }
      },
      {
        "email": "maria@ejemplo.com",
        "data": { "nombre": "Maria", "producto": "Plan Business" }
      }
    ]
  }'

Ejemplo con template

bash
curl -X POST https://api.reallyquickemails.com/v1/send-batch \
  -H "Authorization: Bearer sk_proj_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "sender": "noreply@tudominio.com",
    "senderName": "Mi Empresa",
    "templateId": "550e8400-e29b-41d4-a716-446655440000",
    "recipients": [
      { "email": "juan@ejemplo.com", "data": { "nombre": "Juan" } },
      { "email": "maria@ejemplo.com", "data": { "nombre": "Maria" } }
    ]
  }'

Ejemplo con envio programado

bash
curl -X POST https://api.reallyquickemails.com/v1/send-batch \
  -H "Authorization: Bearer sk_proj_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "sender": "noreply@tudominio.com",
    "subject": "Newsletter semanal",
    "html": "<h1>Newsletter</h1><p>Las noticias de esta semana...</p>",
    "scheduled_at": "2026-03-25T10:00:00Z",
    "recipients": [
      { "email": "sub1@ejemplo.com" },
      { "email": "sub2@ejemplo.com" }
    ]
  }'

Respuesta exitosa (200)

json
{
  "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "total": 2,
  "queued": 2,
  "scheduled": false,
  "scheduled_for": null,
  "activities": [
    { "email": "juan@ejemplo.com", "activity_id": "uuid-1" },
    { "email": "maria@ejemplo.com", "activity_id": "uuid-2" }
  ]
}
CampoTipoDescripción
batch_idstringUUID único del batch para referencia.
totalnumberCantidad total de destinatarios.
queuednumberCantidad de emails encolados para envío.
scheduledbooleantrue si scheduled_at está en el futuro.
scheduled_forstring | nullEl valor de scheduled_at enviado, o null si es inmediato.
activitiesarrayLista con email y activity_id por destinatario para rastreo.

El activity_id de cada destinatario permite rastrear el estado de entrega mediante webhooks.

Supresión: igual que en /v1/send-email, la supresión se aplica al procesar cada envío en segundo plano — los destinatarios suprimidos se omiten y su actividad queda con estado suppressed.

Idempotencia

Envía el header opcional Idempotency-Key (1–256 caracteres) para evitar envíos duplicados ante reintentos. Las respuestas con status 2xx o 4xx se cachean por 24 horas, con alcance por proyecto. Si repites la misma clave dentro de ese plazo, recibes la respuesta cacheada sin re-procesar el batch, junto con el header Idempotency-Replayed: true.

En el SDK de Node.js, pasa { idempotencyKey } como segundo argumento de rqe.emails.sendBatch(params, { idempotencyKey }). Ver más en SDK de Node.js.

Dry run

Con "dry_run": true la API devuelve una previsualización sin encolar emails ni crear registros de actividad:

json
{
  "dry_run": true,
  "test_mode": false,
  "recipients_count": 2,
  "would_send": {
    "template_id": null,
    "subject": "Oferta especial para ti, {nombre}",
    "from": "Mi Empresa <noreply@tudominio.com>",
    "first_recipient": "juan@ejemplo.com"
  }
}

Limites

LímiteValor
Destinatarios por request10,000
Cache de idempotencia24 horas

Tip: Para envíos superiores a 10,000 destinatarios, usa múltiples llamadas o crea una campaña desde el Dashboard de RQE, que maneja automáticamente lotes y reintentos. Ver más en Campañas.

Codigos de Error

CódigoDescripción
400sender is required
400subject or templateId is required
400html or templateId is required
400recipients array is required and must not be empty
400Too many recipients: X. Maximum is 10,000 per batch.
400recipients[N].email is required
400environment must be a string of [a-zA-Z0-9_.-] up to 64 chars
400ENVIRONMENT_NOT_CONFIGURED — el environment no está configurado en el proyecto.
401API Key inválida o no proporcionada.
500Failed to create activity records / Failed to process batch

Reply-To Automatico (Inbound Email)

Los correos enviados vía /v1/send-email y /v1/send-batch incluyen automáticamente un header Reply-To con el nombre del remitente:

text
Reply-To: "Mi Empresa" <r-x7K9mP2q@rqe.inbound.reallyquickemails.com>

Los clientes de correo (Gmail, Outlook, Apple Mail) muestran el nombre del remitente, no la dirección técnica. Cuando el destinatario responde, la respuesta se enruta automáticamente a RQE y se asocia al hilo de conversación original.

Este comportamiento es automático y no requiere configuración. Para recibir notificaciones de respuestas entrantes, configura un webhook de inbound email.

En /v1/send-template-email las respuestas van directo a la bandeja del remitente: el Reply-To usa la dirección de respuesta configurada en el perfil del remitente, o el propio sender_email si no hay una.


APIs de Gestion de Datos

Además de los endpoints de envío, la API v1 incluye endpoints para gestionar leads, eventos, tags y atributos. Consulta la documentación completa en:

  • Leads API — CRUD de leads, segmentos, tags y atributos
  • Events API — Tracking de eventos custom desde tus apps

Resumen rapido

CategoríaEndpointDescripción
LeadsPOST /v1/leadsCrear/actualizar leads (single o bulk hasta 1,000)
GET /v1/leadsListar con paginación y filtros
GET /v1/leads/:idDetalle de un lead con segmentos
PUT /v1/leads/:idActualizar lead
DELETE /v1/leads/:idEliminar lead
SegmentosPOST /v1/leads/:id/segmentsAgregar lead a segmentos
DELETE /v1/leads/:id/segments/:segmentIdQuitar de segmento
TagsPOST /v1/leads/:email/tagsAgregar tags
DELETE /v1/leads/:email/tagsQuitar tags
GET /v1/leads/:email/tagsListar tags
AtributosPOST /v1/leads/:email/attributesSet/merge atributos custom
GET /v1/leads/:email/attributesObtener atributos
EventosPOST /v1/eventsTrackear un evento
POST /v1/events/bulkTrackear hasta 1,000 eventos
GET /v1/eventsListar eventos con filtros