Ir a la documentación
SDK

Envíos masivos

`broadcasts.preview`, `send`, `list`, `listAll`, `iterate`, `get` y `cancel`.

Todos los métodos

broadcasts.ts
const draft = {  audienceIds: ['aud_4c1b8e2a7d9f05c36b4e8a71'],  from: 'Acme <[email protected]>',  subject: '{{firstName|Hello}}, the September release is out',  html: '<p>Hi {{firstName|there}},</p><p>Here is what changed this month.</p>',  text: 'Hi {{firstName|there}}, here is what changed this month. Unsubscribe: {{unsubscribeUrl}}',  tags: { campaign: 'release-2026-09' },} const reach = await openemail.broadcasts.preview(draft)console.log(reach.recipients, reach.unsubscribed, reach.suppressed) const broadcast = await openemail.broadcasts.send(draft) let latest = await openemail.broadcasts.get(broadcast.id)while (['scheduled', 'queued', 'sending'].includes(latest.status)) {  await new Promise((resolve) => setTimeout(resolve, 5_000))  latest = await openemail.broadcasts.get(broadcast.id)} for await (const copy of openemail.emails.iterate({ broadcastId: broadcast.id })) {  console.log(copy.id, copy.status)} const later = await openemail.broadcasts.send({ ...draft, scheduledAt: 'P1D' })await openemail.broadcasts.cancel(later.id) const history = await openemail.broadcasts.list({ audienceId: draft.audienceIds[0] })console.log(latest.status, latest.counts.sent, history.items.length)

Un envío masivo manda un mensaje a todos los de una o más audiencias, como copia aparte para cada persona. Cada copia tiene exactamente un destinatario y ni cc ni bcc, así que nadie ve a quién más se envió, y cada copia es un correo normal con su propio id msg_, eventos, seguimiento y webhooks. emails.list({ broadcastId }) las lista. Las copias no se archivan en la carpeta Enviados, porque el envío masivo es el registro.

send se resuelve enseguida con el envío masivo en queued, o scheduled si pasas scheduledAt, y el envío sigue en segundo plano. send necesita emails:send y audiences:read, preview necesita audiences:read, list, listAll, iterate y get necesitan emails:read, y cancel necesita emails:send.

Cada send lleva una Idempotency-Key, la tuya mediante options.idempotencyKey o una que crea el SDK, así que un reintento tras un fallo de red responde con el envío masivo que creó el primer intento en lugar de enviar dos veces. preview, get y cancel se pueden repetir sin riesgo y se reintentan.

Campos de combinación

subject, html y text se rellenan para cada persona a partir de su contacto. {{firstName}} es la primera palabra del nombre del contacto, {{lastName}} el resto, {{name}} el nombre completo, {{email}} la dirección a la que va la copia y {{unsubscribeUrl}} el enlace que la da de baja.

Cada campo admite un valor de reserva tras una barra, que se usa cuando el contacto no tiene valor para él, así que {{firstName|there}} se convierte en "there" para un contacto guardado sin nombre. Los valores se escapan en html, y cualquier otro {{…}} se deja tal como está escrito.

Pasa template en lugar de html y text para enviar una plantilla guardada. Los mismos cinco valores le llegan como props, pero solo los props que declara la plantilla, así que una plantilla que declara firstName lo recibe y una que no lo declara nunca se rechaza por ello. Todo lo que hay en template.props va igual a todas las copias.

Darse de baja

Cada copia lleva las cabeceras de baja con un clic que permiten a un cliente de correo mostrar su propio botón de baja, algo que los grandes proveedores de buzones exigen al correo masivo. Un cuerpo html o text que no coloca {{unsubscribeUrl}} por sí mismo recibe un pie de una línea con el enlace. Una plantilla se envía exactamente como es, así que pon {{unsubscribeUrl}} en la plantilla.

Darse de baja marca a la persona como dada de baja en todas las audiencias a las que fue ese envío masivo, y AudienceContactResource.unsubscribedAt lo muestra en audiences.listContacts. Sigue en la audiencia y en la agenda, sus otras audiencias no se tocan y el correo que se le envía de uno en uno sigue saliendo. Sacarla de la audiencia y volver a añadirla la deja suscrita de nuevo.

A quién se omite

Un envío masivo llega a todo contacto de al menos una de las audienceIds, una vez aunque esté en varias. Omite al contacto que se dio de baja de todas esas audiencias en las que está, y a una dirección de la lista de supresión tras un rebote o una queja, o porque alguien la añadió. Un contacto añadido a una de las audiencias después de send, pero antes de que el envío le llegue, sí lo recibe.

preview devuelve las mismas cifras sin enviar: recipients, unsubscribed y suppressed. Un send que no llegaría a nadie lanza 422 no_recipients.

Todo el envío se compara con los envíos mensuales del plan antes de escribir nada, así que un envío masivo que la cuota no puede cubrir lanza 429 send_quota_exceeded y no deja nada atrás. Cada copia cuenta como un envío.

Estado y progreso

get lee counts en vivo de las copias, así que consúltalo mientras un envío masivo sale. status pasa de scheduled o queued a sending y se queda en sent cuando cada copia entregada ha salido o ha fallado. Sigue en sending mientras aún hay copias esperando, aunque completedAt ya diga que se alcanzó a la última persona. failed significa que todo el envío masivo se detuvo, y lastError dice por qué: ya no se puede enviar desde la dirección from, la plantilla dejó de resolverse, el plan se agotó a mitad, el propio envío falló una y otra vez, o no se pudo escribir ni una sola copia.

cancel detiene un envío masivo que está scheduled, queued o sending. No se añade a nadie más y se cancela cada copia que aún espera, mientras que las copias que salieron no se pueden recuperar. Cuando todas las copias han salido, cancel lanza 409 broadcast_not_cancellable, y cancelar uno ya cancelado se resuelve con él tal como está.

Respuesta: BroadcastResource

send, get y cancel se resuelven cada uno con uno de estos. list se resuelve con una página de ellos, { items, hasMore, nextCursor }, el más nuevo primero, y listAll e iterate recorren todas las páginas. preview se resuelve con un BroadcastPreviewResource con audienceIds, recipients, unsubscribed y suppressed.

idstring
El identificador duradero, `brd_` seguido de 24 caracteres hexadecimales.
statusBroadcastStatus
`scheduled`, `queued`, `sending`, `sent`, `cancelled` o `failed`. `BROADCAST_STATUSES` nombra cada uno.
modeApiKeyMode
`live` o `test`, según la clave que lo creó. Las copias de un envío masivo de prueba se marcan como enviadas y no se entregan a nadie.
sourceEmailSource
Dónde se inició: `api` para una clave, `oauth` para una app conectada, `composer` para la app, `mcp` para un asistente.
audienceIdsstring[]
Las audiencias a las que se envió, cada una una vez.
fromstring
La dirección desde la que se envía cada copia.
subjectstring
El asunto tal como se escribió, con sus campos de combinación. Vacío cuando una plantilla aporta el asunto.
countsBroadcastCounts
`recipients` es la estimación tomada en `send`. `created` cuenta las copias escritas, `skipped` las personas omitidas porque su dirección ya estaba suprimida, y `failedToQueue` las personas cuya copia no se pudo escribir. `queued`, `sending`, `sent`, `failed` y `cancelled` cuentan las copias según el estado en que está cada una ahora.
lastErrorstring | null
Por qué falló el envío masivo, o la copia más reciente que no se pudo escribir y por qué. Null mientras nada ha ido mal.
scheduledAtstring | null
ISO-8601 UTC, cuándo debe empezar el envío. Null para un envío masivo enviado al momento.
startedAtstring | null
ISO-8601 UTC, cuándo el envío llegó a las primeras personas.
completedAtstring | null
ISO-8601 UTC, cuándo se alcanzó a la última persona. Después aún puede haber copias esperando para salir.
cancelledAtstring | null
ISO-8601 UTC, cuándo lo detuvo `cancel`.
createdAtstring
ISO-8601 UTC, cuándo se llamó a `send`. Fija el orden de la lista.
updatedAtstring
ISO-8601 UTC, actualizado a medida que avanza el envío.