Skip to main content
Si integras RQE como plataforma para tus propios clientes (patrón partner/reseller), estos endpoints te dejan crear y configurar un proyecto-cliente completo por API: su dominio de envío con el pack DNS, su remitente, su API key y su webhook. Todo con tu partner-key, sin pedirle nada a la key del cliente. Base URL: 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):
La partner-key está asociada a tu organización y solo puede operar proyectos dentro de ella. Es dedicada y revocable sin afectar tus envíos. Se emite desde RQE al habilitar tu cuenta de partner. Una key ausente o inválida responde 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.
La partner-key no envía correo. Sirve para provisionar y configurar. Para enviar, gestionar contactos o consultar actividad de un cliente, usa la api_key (sk_proj_...) de su proyecto.

Alta completa en una llamada

Es el camino recomendado. Un solo POST 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.
4

Opera en su nombre

Con la api_key del cliente, envía, gestiona contactos y lee actividad — todo aislado a ese proyecto.

POST /v1/partner/projects

Crea un proyecto-cliente dentro de tu organización de partner. El slug 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

domain y sender viajan juntos o no viajan. SES no registra un dominio sin una dirección From, así que no hay forma de dar de alta uno sin el otro. Si mandas solo uno, la respuesta es 400 antes de crear nada: SENDER_REQUIRED_FOR_DOMAIN o DOMAIN_REQUIRED_FOR_SENDER. Y si el correo no termina en el dominio, 400 SENDER_DOMAIN_MISMATCH.

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.
Respuesta 201 Created

Ejemplo — alta completa

Con domain 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.
Respuesta 201 Created
La api_key se devuelve una sola vez, al crear. Guárdala de forma segura — es la credencial con la que operas ese proyecto-cliente. Si la pierdes, rótala con POST /v1/partner/projects/{projectId}/api-key/rotate.
Esa forma del objeto 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.
El cliente publica fqdn, no name. Los registros que genera SES son relativos al dominio (_amazonses, @, _dmarc, send), mientras que los de reply y tracking son absolutos. fqdn es siempre el nombre listo para pegar en el DNS, sin pensar; name está para que coincida con lo que muestran los endpoints de /domains/*.
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í.
El pack completo se arma cuando el dominio es nuevo. Reply y tracking son best effort: si alguno falla, el dominio queda registrado igual y el motivo viaja en 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

Con external_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 enviaste domain 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.
Respuesta 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.
Respuesta 200 OK

El bloque health

Es por proyecto, no la forma de GET /domains/health: acá no hay summary ni data.
can_send: true con status: critical es el caso que más cuesta. El correo sale con 200 y nada parece roto, pero va sin DKIM del dominio del cliente. Ver Antes de enviar volumen.

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.
webhook_url e inbound_webhook_url son dos campos independientes. Escribir uno no toca al otro. El alta los deja iguales solo porque nacen vacíos y hereda el mismo valor para los dos; a partir de ahí viven separados. Si tu integración tiene el saliente en null y el entrante apuntando a tu endpoint de respuestas, mandar webhook_url en un PATCH no te va a desviar el ruteo de respuestas.
Respuesta 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 con disabled_at.
Respuesta 200 OK

POST /v1/partner/projects/{projectId}/reactivate

Deshace el soft-disable: limpia disabled_at y el proyecto vuelve a poder enviar. Es idempotente — reactivar uno que ya está activo responde 200, nunca 409.
Respuesta 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.
El remitente es obligatorio y va anidado en sender, no como sender_name y sender_email sueltos. SES no registra un dominio sin una dirección From, así que no hay alta de dominio “pelada”.
Respuesta 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.
Por qué no se pisa un reply domain que ya funciona. Registrar uno reescribe su estado a pending, y sobre un cliente que ya tenía las respuestas branded andando eso se las apaga hasta que alguien re-verifique. Preferimos omitir el paso y decírtelo antes que romperle el reply a un cliente en producción.
skipped[] solo se llena en este POST. GET /v1/partner/projects/{projectId}/domains/{domain} devuelve siempre skipped: [].
El verification_url es lo que le mandas al cliente final. Es una página pública que muestra sus registros con botón de copiar y un botón de verificar. No expone nada del proyecto: solo el dominio y sus registros, que son públicos por definición. No hace falta que tu cliente tenga cuenta RQE.

GET /v1/partner/projects/{projectId}/domains

Lista los dominios del cliente con su estado.
Respuesta 200 OK
verification_url puede venir en null. Los GET nunca crean el token: solo lo devuelven si ya existe. El que lo crea es POST /v1/partner/projects/{projectId}/domains y, como esa alta es idempotente, re-postear un dominio viejo es la forma de conseguirle el link. Si integraste antes de que existiera esta página, tus dominios anteriores van a mostrar null hasta que lo hagas.

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.
Respuesta 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.
Respuesta 200 OK
La respuesta también trae reply_domain y tracking_domain, pero de solo lectura: son el estado actual de cada uno, no algo que esta llamada haya verificado.
El verify a propósito no toca el tracking. Verificarlo escribe pending en cuanto un lookup de DNS no resuelve, y el envío exige verified para usar el dominio del cliente. Un DNS lento habría devuelto los links de todos sus correos al dominio compartido sin que nadie lo pidiera. Lo mismo vale para el reply. Para forzar esos dos hay endpoints propios, que se llaman con la API key del tenant: ver reply domain y tracking domain.
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.
Respuesta 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.
Respuesta 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.
El magic link es la excepción, no el atajo. Verifica la casilla, no el dominio: SES firma con d=amazonses.com, así que el DKIM nunca queda alineado con el dominio del cliente. Úsalo solo cuando el cliente no controla su DNS, y nunca para volumen. Ver Antes de enviar volumen.

POST /v1/partner/projects/{projectId}/api-key/rotate

Rota la API key del proyecto-cliente.
Respuesta 200 OK
No hay periodo de gracia: la key anterior deja de autenticar en la misma transacción. El proyecto no guarda la key previa, así que no hay ventana de solapamiento. Despliega la nueva antes de que ese cliente vuelva a llamar, o sus requests van a fallar con 401 hasta que lo hagas.

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 bloque partner que trae tu cupo de proyectos. Es la forma de saber cuántos tenants te quedan antes de chocar con MAX_PROJECTS_REACHED.
Respuesta 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. Ve SPF=Pass, DKIM=Pass, DMARC=Fail porque nada está alineado con el dominio del From, 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.
Nada de esto aparece como error en tu integración: la API responde 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.
Mira el hard bounce, no el total de rebotes. Los proveedores calculan el umbral de suspensión (~5%) sobre los rebotes permanentes; los temporales no cuentan. Un dominio puede mostrar 12% de rebote total y estar por debajo del 1% de hard bounce.

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.verified y eventos de email.
  • API pública — envío con la key del cliente.