https://api.reallyquickemails.com
Cada cliente = un proyecto. El dominio, el reply domain, los límites y las estadísticas son por proyecto, así que cada cliente tuyo es un proyecto RQE independiente con su propia API key. Estos endpoints crean, configuran y listan esos proyectos dentro de tu organización de partner.
Autenticación
Los endpoints de partner usan una partner-key dedicada (distinta de las API keys de proyecto):401. Un projectId que no pertenece a tu organización responde 404, nunca 403: desde afuera, un proyecto ajeno es indistinguible de uno que no existe.
Alta completa en una llamada
Es el camino recomendado. Un soloPOST crea el proyecto, registra el dominio de envío con el pack DNS completo y deja el remitente creado sobre ese dominio.
1
Crea el cliente entero
POST /v1/partner/projects con name, domain y sender. Recibes project_id, slug, la api_key del cliente, los registros DNS y el link público de verificación.2
Reenvía el link de verificación
domain.verification_url es una página pública que muestra los registros y verifica con un botón. La abre el cliente final sin cuenta RQE: es lo único que necesitas mandarle.3
Espera el webhook domain.verified
No poleas. RQE reintenta la verificación sola y avisa por webhook cuando el DNS propaga. Ver Webhooks.
POST /v1/partner/projects
Crea un proyecto-cliente dentro de tu organización de partner. Elslug y la api_key se generan automáticamente.
El único campo obligatorio es name. domain y sender son opcionales y nuevos: si los envías, el alta queda completa en esta misma llamada. Si no, el endpoint responde igual que siempre.
Compatibilidad: si ya integraste el flujo anterior, no necesitas cambiar nada. La llamada con solo
{ "name": "..." } sigue siendo válida y su respuesta no cambió. Los campos nuevos se agregan, no reemplazan.Request Body
Ejemplo mínimo — solo el proyecto
El flujo de siempre, sin cambios. Crea el proyecto y devuelve su API key; el dominio y el remitente los configuras después con los endpoints de abajo.- cURL
- Python
201 Created
Ejemplo — alta completa
Condomain y sender, la misma llamada registra el dominio y crea el remitente. La respuesta suma las claves domain y sender a las tres de arriba.
- cURL
- Python
201 Created
sender —con id, sender_source, can_send y created_at— es la misma en los cuatro lugares donde aparece un remitente: el alta, el alta de dominio, la creación de remitentes y el detalle del proyecto.
El pack DNS
domain.records trae el pack completo, no solo DKIM. Se deriva entero en una sola llamada.
status por registro: not_set, propagating, mismatch o verified. El campo priority aparece solo en el MX de reply; el de send lleva la prioridad dentro de value. Detalle de cada registro en Dominios.
El nombre
records es solo de los endpoints bajo /v1/partner. Los de /domains/*, que se llaman con la API key del cliente, siguen devolviendo el array como dns_records. No cambió nada ahí.warnings[]. Y si el proyecto ya tenía uno de los dos, ese paso se omite y se reporta en skipped[] — ver Pasos omitidos.
Idempotencia
Conexternal_key, reintentar la llamada devuelve el mismo proyecto en vez de duplicarlo. Es el campo con el que amarras el cliente de tu sistema al proyecto RQE: úsalo siempre.
Si el external_key corresponde a un cliente deshabilitado, la respuesta es 409 PROJECT_DISABLED con el project_id en el cuerpo, para que sepas cuál reactivar.
Alta parcial
Solo aplica si enviastedomain y sender. Si el proyecto se crea pero el registro del dominio falla, la respuesta llega con partial: true y el detalle en errors[]. El proyecto y su api_key son válidos: reintenta el dominio con POST /v1/partner/projects/{projectId}/domains.
Cada entrada de errors[] y de warnings[] es { step, error_code, error }. En errors[], step solo toma el valor domain: el remitente se crea dentro del registro del dominio, así que no hay un paso suyo que pueda fallar por separado. En warnings[], step toma reply_domain, tracking_domain o verification_link — los pasos best effort que no tumban el alta.
Nunca descartamos un paso en silencio. Si no ves
partial ni warnings en la respuesta, todo salió bien.GET /v1/partner/projects
Lista los proyectos-cliente de tu organización.- cURL
200 OK
GET /v1/partner/projects/{projectId}
Detalle de un proyecto-cliente. La respuesta tiene cuatro bloques:project, domains, senders y health.
Es la llamada para construir tu propio panel de clientes: dice de un vistazo quién puede enviar bien y quién no.
- cURL
200 OK
El bloque health
Es por proyecto, no la forma de GET /domains/health: acá no hay summary ni data.
PATCH /v1/partner/projects/{projectId}
Actualiza los datos del proyecto-cliente. Solo se tocan los campos que envías.Request Body
Un
PATCH sin ningún campo reconocido responde 400 EMPTY_PATCH.
- cURL
200 OK — el proyecto actualizado, envuelto en project.
El
PATCH funciona sobre un cliente deshabilitado, a propósito. Así puedes arreglarle el webhook_url antes de reactivarlo, en vez de reactivarlo roto. El slug, en cambio, es estable de por vida: los links de tracking de los emails ya enviados dependen de él, y cambiar el name no lo mueve.DELETE /v1/partner/projects/{projectId}
Deshabilita un proyecto-cliente (soft-disable). No se borra: los links de los emails ya enviados dependen de que el proyecto siga existiendo. Deja de enviar y queda condisabled_at.
- cURL
200 OK
POST /v1/partner/projects/{projectId}/reactivate
Deshace el soft-disable: limpiadisabled_at y el proyecto vuelve a poder enviar. Es idempotente — reactivar uno que ya está activo responde 200, nunca 409.
- cURL
200 OK — trae el proyecto completo, con la misma forma que el PATCH.
Dominios del cliente
Los mismos dominios que/domains/*, pero con tu partner-key y el projectId del cliente en la ruta: no necesitas tener a mano la api_key de cada uno.
POST /v1/partner/projects/{projectId}/domains
Registra el dominio de envío del cliente, deriva el pack DNS completo y crea el link público de verificación.- cURL
201 Created — o 200 OK con reused: true si el dominio ya estaba registrado. El pack sale al nivel de arriba, sin envolver.
El alta de dominio es idempotente. Repetirla sobre un dominio ya registrado responde
200 con reused: true y sus registros existentes, en vez de fallar. Reintentar un alta que quedó a medias es seguro.Pasos omitidos
skipped[] es hermano de warnings[] y dice qué no se hizo y por qué. La diferencia importa: warnings[] es un paso que se intentó y falló; skipped[] es un paso que no se intentó, a propósito, porque hacerlo habría roto algo que ya funcionaba.
skipped[] solo se llena en este POST. GET /v1/partner/projects/{projectId}/domains/{domain} devuelve siempre skipped: [].
GET /v1/partner/projects/{projectId}/domains
Lista los dominios del cliente con su estado.200 OK
GET /v1/partner/projects/{projectId}/domains/{domain}
Estado registro por registro, sin consultas externas. Es lo que muestras en tu panel mientras el cliente publica el DNS.200 OK
skipped viene siempre vacío acá: solo el POST de alta lo llena. Un dominio que no existe en el proyecto responde 404 DOMAIN_NOT_FOUND.
POST /v1/partner/projects/{projectId}/domains/{domain}/verify
Fuerza la verificación del dominio de envío: consulta SES, actualiza el estado de los registros y responde si el dominio ya puede enviar. Llámalo cuando el cliente te diga “ya lo configuré”. Cubre identidad, DKIM y MAIL FROM. No verifica el reply domain ni el tracking domain.200 OK
reply_domain y tracking_domain, pero de solo lectura: son el estado actual de cada uno, no algo que esta llamada haya verificado.
No hace falta pollear. Los dominios en
pending se re-verifican solos —seguido el primer día, más espaciado después— y cuando quedan verificados RQE emite el webhook domain.verified al webhook_url del proyecto. verify sirve para respuesta inmediata, no para reemplazar el webhook.Remitentes del cliente
GET /v1/partner/projects/{projectId}/senders
Lista los remitentes del cliente y cómo se verificó cada uno.200 OK
sender_source dice de dónde salió el remitente: manual (creado sobre un dominio registrado), magic_link (verificado por correo, sin DKIM), auto-own-email o admin. Un remitente con domain_authenticated: false y volumen es el patrón que rompe la entregabilidad.
POST /v1/partner/projects/{projectId}/senders
Crea un remitente. Por defecto exige un dominio verificado: es la regla que evita que un cliente nazca enviando sin autenticar.name y email se aceptan sueltos en el cuerpo o anidados en sender: las dos formas funcionan.
- cURL
201 Created
path dice por dónde salió el remitente: domain (sobre el dominio verificado) o magic_link. En el camino del magic link la respuesta suma un warning avisando que ese remitente no tiene DKIM.
Si el dominio del correo no está verificado y no enviaste el flag:
Respuesta 422 Unprocessable Entity
verification_status viene en null cuando el dominio ni siquiera está registrado.
Con allow_unauthenticated: true se envía un correo de verificación a la dirección y el remitente nace con sender_source: "magic_link", domain_authenticated: false y email_verified: false hasta que el destinatario hace clic.
La exigencia del dominio verificado es solo de este endpoint.
POST /domains/verify-email y el resto de /domains/*, que se llaman con la API key del cliente, funcionan igual que siempre: no piden el flag ni devuelven DOMAIN_NOT_VERIFIED.POST /v1/partner/projects/{projectId}/api-key/rotate
Rota la API key del proyecto-cliente.- cURL
200 OK
GET /v1/partner/projects/{projectId}/stats
Métricas de envío del cliente: entregas, rebotes, aperturas y clicks.GET /v1/partner/whoami
Datos de la organización asociada a tu partner-key, con un bloquepartner que trae tu cupo de proyectos. Es la forma de saber cuántos tenants te quedan antes de chocar con MAX_PROJECTS_REACHED.
200 OK
max_projects en null significa sin límite. El conteo son los clientes activos, sin contar tu proyecto raíz.
Antes de enviar volumen
Registra el dominio del cliente antes del primer envío grande. No es una recomendación de higiene: es la diferencia entre llegar a la bandeja y no llegar. Un remitente verificado solo por correo (magic link) sale firmado con el dominio compartido de la plataforma. El resultado, medido en clientes reales:- Microsoft rechaza con
5.7.515. VeSPF=Pass, DKIM=Pass, DMARC=Failporque nada está alineado con el dominio delFrom, y a remitentes con volumen los corta ahí mismo. - Gmail responde
550-5.7.1 "likely unsolicited mail". Sin DKIM propio, la reputación del cliente se mezcla con la de todos los demás que envían sin autenticar. - No hay reply domain ni tracking domain. Ambos cuelgan del dominio verificado.
200, el correo “se envía” y el problema se ve semanas después en la tasa de rebote.
1
Crea el cliente con su dominio
POST /v1/partner/projects con domain y sender. El pack DNS viene en la respuesta.2
Reenvía el verification_url
Es una página pública con los registros y un botón de verificar. Es lo único que tu cliente final necesita abrir, sin cuenta RQE. Si su proveedor de DNS soporta Domain Connect, la publicación es de un clic.
3
Espera domain.verified
Llega por webhook. Recién ahí habilita el envío de volumen de ese cliente.
4
Vigila la salud
GET /v1/partner/projects/{projectId} trae health. Un cliente en critical con can_send: true está quemando reputación en silencio.Errores
Todas las respuestas de error tienen la misma forma:code y error_code llevan siempre el mismo valor. error_code es el canónico; code está por compatibilidad con integraciones existentes. Algunos errores suman campos extra al cuerpo, planos, para que no tengas que parsear el texto.
Códigos de error
PROJECT_DISABLED sale únicamente en el alta, cuando reutilizas el external_key de un cliente deshabilitado. Trae el project_id para que sepas a cuál llamar /reactivate. Un PATCH sobre un cliente deshabilitado sí funciona, a propósito: así puedes dejarle bien el webhook antes de reactivarlo.Siguiente
- Partner quickstart — los dos modelos de integración y cuándo conviene cada uno.
- Dominios — la misma gestión con la API key del cliente.
- Webhooks —
domain.verified,sender.verifiedy eventos de email. - API pública — envío con la key del cliente.