Patron de integracion B2B SaaS
Sync de contactos, API de campanas y webhooks bidireccionales para newsletter embebida.
Esta pagina describe una arquitectura de referencia para un producto B2B SaaS que integra newsletter con MailingCore: tu app sigue siendo la fuente de verdad del consentimiento, mientras MailingCore mantiene una replica operativa para envio, baja hospedada y entregabilidad.
El patron se valido en integraciones tipo produccion (apps multi-tenant, add-ons CRM, SaaS verticales). Adapta nombres e IDs a tu dominio.
Vision general
Scopes de API key (minimos)
| Scope | Uso |
|---|---|
contacts:read | Reconciliacion (updatedSince) |
contacts:write | Upsert, bulk, erasure |
campaigns:read | Poll de estado y stats |
campaigns:write | Crear, test, programar, enviar |
webhooks:manage | Registrar URL receptora |
Opcional: suppressions:write si empujas bajas desde tu panel ademas de webhooks.
1. Sincronizacion de contactos
Objetivo: Mantener audiencia opted-in en MailingCore sin pasar listas de destinatarios en cada envio.
| Aspecto | Recomendacion |
|---|---|
| Identidad | externalId = ID estable de usuario/cuenta en tu sistema (opaco) |
| Upsert | PUT /contacts al otorgar consentimiento |
| Carga inicial | POST /contacts/bulk en chunks (≤ 1000 por peticion) |
| Incremental | Job periodico + hooks on-change en email, locale o consentimiento |
| Campos | email, locale, optIn: true, consentVersion, tag source |
| Revocar en tu app | DELETE /contacts/:externalId o PATCH con optIn: false |
| Erasure RGPD | DELETE /contacts/:externalId — MailingCore propaga suppression |
Reconciliacion: GET /contacts?updatedSince=<ISO>&cursor= para alinear bajas hospedadas a tu almacen de consentimiento.
Cadencia sugerida: cada 15–60 min mas hooks en tiempo real en eventos de consentimiento.
2. Receptor webhook (tu servidor)
Registra con Crear endpoint:
{
"url": "https://tu-saas.com/webhooks/mailingcore",
"events": [
"contact.unsubscribed",
"email.bounced",
"email.complained"
],
"secret": "<tu-secreto-en-env>"
}
| Evento | Accion tipica en tu SaaS |
|---|---|
contact.unsubscribed | Revocar consentimiento newsletter por externalId o email; auditar |
email.bounced (hard) | Marcar email invalido; sync suppression opcional |
email.complained | Revocar consentimiento; alerta operador |
Verifica X-MailingCore-Signature (HMAC SHA-256, tolerancia replay ±5 min). Responde 200 de inmediato; procesa async. Ver Entregas y reintentos.
3. Flujo de campana (sustituye relay batch)
Deja de usar fan-out POST /emails/batch con arrays de destinatarios. Usa la API de campanas:
Pre-sync audiencia
Ejecuta sync de contactos con
optIn: trueactualizados.Crear borrador
POST /campaignscontemplateVersionId,subject,audienceFilter: { optIn: true }.Revisar cobertura locale
GET /campaigns/:id/locale-coverage— variantes por Cobertura de idiomas.Envio de prueba
POST /campaigns/:id/testa 1–5 emails QA internos.Programar o enviar
POST /campaigns/:id/scheduleoPOST /campaigns/:id/send(fan-out async).Poll de estado
GET /campaigns/:idhastaSENT,FAILEDoCANCELLED. PersistemailingcoreCampaignIden tu entidad de campana.
Paso a paso completo: Crear y enviar campana.
4. Feature flag y rollback
Mantén un switch de configuracion (p. ej. NEWSLETTER_MODE=legacy_relay | mailingcore_api) para volver al camino de envio anterior sin redeploy. Ejecuta smoke tests en staging antes de cambiar trafico de produccion.
5. Checklist smoke test
| # | Escenario | Criterio pass |
|---|---|---|
| 1 | Upsert contactos test con locales distintos | Listados en GET /contacts; optIn: true |
| 2 | Test send de campana | Email recibido; {{unsubscribeUrl}} presente |
| 3 | Audiencia multi-idioma | Warnings de locale-coverage coherentes |
| 4 | Envio pequeno | status: SENT; stats sent > 0 |
| 5 | Clic baja hospedada | contact.unsubscribed recibido; consentimiento revocado en tu app |
| 6 | Revocar consentimiento en tu app | Contacto eliminado u opt-out en MailingCore |
| 7 | Reintento sync idempotente | Sin duplicados de externalId |