Eventos
Envía eventos de espacio de trabajo y personalizados, y consulta el flujo de eventos que hay detrás de los webhooks: entregas, rebotes, aperturas y más.
Enviar un evento
Registra un evento de espacio de trabajo (w:<name>) o un evento personalizado (c:<name>). Funciona con claves de API que tienen el permiso full o el permiso events. Para saber cuándo usar cada uno, consulta Seguimiento de eventos. Los eventos están incluidos en los planes Pro, Business y Custom, con hasta 100 tipos de eventos en Pro y 1000 en Business.
- Un evento de espacio de trabajo tiene que estar definido antes. Sus
propertiesse comprueban con la definición. - Un evento personalizado no necesita definición. Sus
propertiespueden ser cualquier objeto JSON.
Los eventos del sistema, como email.delivered, los registra Emailit y no se pueden enviar. Para registrar muchos eventos en una sola llamada, usa Enviar eventos por lotes.
/eventsParámetros del cuerpo
typestringobligatoriow:<name> para un evento de espacio de trabajo o c:<name> para un evento personalizado, por ejemplo c:order.completed. El nombre tiene de 1 a 100 letras, dígitos, ., - o _, y empieza por una letra o un dígito.propertiesobjectLos datos del evento. Por defecto, {}.
- Eventos de espacio de trabajo: solo las propiedades de la definición, cada una con su tipo. Las propiedades obligatorias tienen que estar presentes,
nulldeja vacía una propiedad opcional y las fechas se guardan en formato ISO 8601 en UTC. Consulta Tipos de propiedades. - Eventos personalizados: cualquier objeto JSON, de hasta 32 KB y 8 niveles de profundidad.
emailstringcontact_idstringcon_…). Tiene prioridad sobre email. Un ID que no corresponde a ningún contacto del espacio de trabajo devuelve 422.anonymous_idstringoccurred_atstring | integercontextobjectpage (url, path, title, referrer, search), campaign (source, medium, name, term, content), locale y timezone. Las claves desconocidas se descartan y los valores largos se acortan.Los contactos solo se buscan, nunca se crean. Emailit no guarda direcciones IP con los eventos.
Devuelve
Devuelve 201 Created con el evento: object, id, type, created_at y data. data.object contiene lo que se ha guardado:
objectstringworkspace_event o custom_event.namestringpropertiesobjectcontactobject | nullid y el email del contacto al que pertenece el evento. id es null cuando solo se conoce el email. null si no enviaste ninguno de los dos.anonymous_idstring | nullanonymous_id que enviaste.occurred_atstringsourcestringapi en este endpoint. Los eventos del script de seguimiento tienen js, y los eventos de prueba enviados desde el panel tienen dashboard.contextobjectUna clave de API con el permiso events no puede leer datos, así que recibe el evento sin data, que incluye el contacto que coincide con el email.
| Código | Cuándo |
|---|---|
400 |
El cuerpo no es un objeto JSON. |
403 |
El permiso de la clave de API no es full ni events, o el plan no incluye los eventos de espacio de trabajo y personalizados: en Pay as you go, error es plan_required y required_plan es pro. No se guarda nada. |
422 |
El evento no es válido. errors usa el campo como clave, por ejemplo type o properties.total, y message repite el primer problema. También se devuelve para un evento w: que no está definido, para un contact_id que no corresponde a ningún contacto y para un tipo que el espacio de trabajo no ha enviado antes cuando ya usa el número de tipos de eventos de su plan (100 en Pro, 1000 en Business). |
429 |
Demasiadas peticiones en un minuto, o el espacio de trabajo alcanzó su límite diario de uso razonable de eventos de espacio de trabajo y personalizados (code: events_daily_limit). No se guarda nada. Vuelve a intentarlo cuando pasen los segundos que indica la cabecera retry-after. |
{
"object": "event",
"id": "evt_2yJm3Rk8VbN1sQ5tLwX7eZhD4cF",
"type": "c:order.completed",
"created_at": "2026-10-19T09:30:02.114000+00:00",
"data": {
"object": {
"object": "custom_event",
"name": "order.completed",
"properties": { "order_id": "1001", "total": 59.9, "currency": "EUR" },
"contact": { "id": "con_2wPq7Lm3XcN8bV1zKd4RtY6sHf9", "email": "jane@example.com" },
"anonymous_id": null,
"occurred_at": "2026-10-19T09:30:00.000Z",
"source": "api"
}
}
}{
"object": "event",
"id": "evt_2yJm3Rk8VbN1sQ5tLwX7eZhD4cF",
"type": "c:order.completed",
"created_at": "2026-10-19T09:30:02.114000+00:00"
}{
"error": "plan_required",
"required_plan": "pro",
"message": "Workspace and custom events are included with Pro and Business."
}{
"error": "properties.segment must be a string",
"message": "properties.segment must be a string",
"errors": {
"properties.segment": ["must be a string"]
}
}{
"error": "type w:customer.tier is not defined in this workspace. Create it under /v2/workspace/events first, or send it as a custom event (c:customer.tier).",
"message": "type w:customer.tier is not defined in this workspace. Create it under /v2/workspace/events first, or send it as a custom event (c:customer.tier).",
"errors": {
"type": ["w:customer.tier is not defined in this workspace. Create it under /v2/workspace/events first, or send it as a custom event (c:customer.tier)."]
}
}Enviar eventos por lotes
Registra hasta 100 eventos de espacio de trabajo y personalizados en una sola petición, por ejemplo cuando tu backend sincroniza pedidos de forma periódica. Funciona con claves de API que tienen el permiso full o el permiso events, en los planes Pro, Business y Custom.
El lote es todo o nada. Si algún evento no es válido, no se guarda ninguno, y la respuesta enumera todos los problemas según la posición del evento en la lista.
/events/batchParámetros del cuerpo
eventsobject[]obligatoriotype, properties, email, contact_id, anonymous_id, occurred_at y context.Devuelve
Devuelve 201 Created con los eventos guardados en data, en el orden en que los enviaste. Cada elemento tiene object (event), id, type y created_at. Usa Obtener un evento para leer uno con su data.
| Código | Cuándo |
|---|---|
400 |
Falta events, está vacío o tiene más de 100 elementos. |
403 |
El permiso de la clave de API no es full ni events, o el plan no incluye los eventos de espacio de trabajo y personalizados: en Pay as you go, error es plan_required y required_plan es pro. No se guarda nada. |
422 |
Al menos un evento no es válido. No se guarda nada. errors usa events.<index>.<field> como clave, por ejemplo events.3.properties.total, contando desde 0, y message repite el primer problema. Un evento de un tipo que el espacio de trabajo no ha enviado antes no es válido cuando el espacio de trabajo ya usa el número de tipos de eventos de su plan (100 en Pro, 1000 en Business). |
429 |
Demasiadas peticiones en un minuto, o el lote haría que el espacio de trabajo superara su límite diario de uso razonable de eventos de espacio de trabajo y personalizados (code: events_daily_limit). No se guarda nada. Vuelve a intentarlo cuando pasen los segundos que indica la cabecera retry-after. |
{
"data": [
{ "object": "event", "id": "evt_2yJm3Rk8VbN1sQ5tLwX7eZhD4cF", "type": "c:order.completed", "created_at": "2026-10-19T09:30:02.114000+00:00" },
{ "object": "event", "id": "evt_2yJm3Sa1XcP4uW8rMyB6fGjK0nT", "type": "c:order.completed", "created_at": "2026-10-19T09:30:02.114000+00:00" },
{ "object": "event", "id": "evt_2yJm3Td5ZeQ7vX2sNzC9hHkL3pU", "type": "w:customer.type", "created_at": "2026-10-19T09:30:02.114000+00:00" }
]
}{
"error": "events.1.email must be a valid email address",
"message": "events.1.email must be a valid email address",
"errors": {
"events.1.email": ["must be a valid email address"],
"events.2.properties.segment": ["must be a string"]
}
}Listar eventos
Devuelve los eventos de tu espacio de trabajo, del más reciente al más antiguo. Cada entrega de webhook se construye a partir de uno de estos eventos, así que puedes usar este endpoint para recuperar los eventos que tu endpoint no recibió. Requiere una clave de API con el permiso full.
/eventsParámetros de consulta
pageintegerEl número de página, empezando por 1. Por defecto, 1. Las páginas que van más allá de 2500 eventos ((page - 1) × limit > 2500) devuelven 422.
limitintegerEventos por página, de 1 a 100. Por defecto, 100.
typestringEl tipo de evento, o una lista de tipos separados por comas, por ejemplo email.delivered,email.bounced. Los eventos de espacio de trabajo y personalizados conservan su prefijo, por ejemplo c:order.completed. Consulta Tipos de eventos.
scopestringSolo los eventos de estos ámbitos, separados por comas: system (los eventos que registra Emailit, como email.delivered), workspace (eventos definidos por el espacio de trabajo, w:<name>) y custom (eventos personalizados, c:<name>). Por ejemplo, scope=workspace,custom. Por defecto, todos los ámbitos. Un ámbito desconocido devuelve 400.
include_databooleanAsígnale true para incluir el payload data de cada evento. Por defecto es false, que devuelve solo object, id, type y created_at.
matchstringall (por defecto) exige que se cumplan todos los filtros. or coincide con cualquier filtro. Consulta Filtrado.
orderstringClave de ordenación de esta lista. Consulta las claves de ordenación más abajo.
directionstringasc o desc.
Filtros y ordenación
Los filtros de listado son un único nivel de parámetros de consulta key.condition=value. Consulta Filtrado para ver match, order, direction y la lista de condiciones de cada tipo.
Claves de filtro
| Clave | Tipo | Condiciones | Notas |
|---|---|---|---|
type | string | exact, not_exact, contains, not_contains, starts_with, ends_with, empty, not_empty | |
created_at | date | exact, before, after, empty, not_empty |
Claves de ordenación
Pasa en order una de estas claves y en direction el valor asc o desc: type, created_at
Sin un filtro created_at, la lista solo abarca los últimos 2 días. Para buscar más atrás, añade uno, por ejemplo created_at.after=2026-09-01T00:00:00Z. Los eventos más antiguos están disponibles mientras la retención de datos de tu plan los conserve.
Devuelve
Devuelve 200 OK con los eventos en data, además de next_page_url y previous_page_url (null en los extremos). Las URL de página conservan type, scope, limit e include_data.
Devuelve 422 con code: "events_offset_too_large" cuando la página es demasiado profunda. En lugar de seguir paginando, acota el rango de fechas o los tipos.
{
"data": [
{
"object": "event",
"id": "evt_2xLc9Rr4Tn6Wb1Qm8Ks3Vf0Hd7a",
"type": "email.delivered",
"created_at": "2026-10-01T10:02:15.912000+00:00"
}
],
"next_page_url": "/v2/events?page=2&limit=100&type=email.delivered",
"previous_page_url": null
}{
"data": [
{
"object": "event",
"id": "evt_2xLc9Rr4Tn6Wb1Qm8Ks3Vf0Hd7a",
"type": "email.delivered",
"data": {
"object": {
"id": "em_2xLc8Mm3Pq5Vn0Ra7Jt2Wd9Fb4e",
"object": "email",
"from": "hello@acme.com",
"to": "ada@example.com",
"subject": "Your order has shipped",
"status": "delivered",
"meta": { "order_id": "1042" },
"updated_at": "2026-10-01T10:02:14.307000+00:00",
"created_at": "2026-10-01T10:02:11.583000+00:00"
}
},
"created_at": "2026-10-01T10:02:15.912000+00:00"
}
],
"next_page_url": "/v2/events?page=2&limit=100&type=email.delivered&include_data=true",
"previous_page_url": null
}{
"error": "Page is too deep. Narrow the type or date filter, or open an earlier page.",
"code": "events_offset_too_large"
}Obtener un evento
Devuelve un evento con su payload data completo. El id es el mismo valor que los webhooks envían como event_id, así que puedes consultar cualquier evento que hayas recibido. Requiere una clave de API con el permiso full.
/events/:idParámetros de ruta
idstringObligatorioEl ID del evento, por ejemplo evt_2xLc9Rr4Tn6Wb1Qm8Ks3Vf0Hd7a.
Devuelve
Devuelve 200 OK con el evento: object (event), id, type, data y created_at. data.object tiene la misma forma que en el payload del webhook de ese tipo; consulta la referencia de eventos de webhook.
En los eventos de espacio de trabajo (w:) y personalizados (c:), data.object contiene object (workspace_event o custom_event), name, properties, contact, anonymous_id, occurred_at, source, identity_verified en los eventos del script de seguimiento que identifican a un contacto y, si lo hay, context. Consulta Enviar un evento.
Devuelve 404 con error: "Event not found" si el ID no existe en tu espacio de trabajo.
{
"object": "event",
"id": "evt_2xLc9Rr4Tn6Wb1Qm8Ks3Vf0Hd7a",
"type": "email.delivered",
"data": {
"object": {
"id": "em_2xLc8Mm3Pq5Vn0Ra7Jt2Wd9Fb4e",
"object": "email",
"from": "hello@acme.com",
"to": "ada@example.com",
"subject": "Your order has shipped",
"status": "delivered",
"meta": { "order_id": "1042" },
"updated_at": "2026-10-01T10:02:14.307000+00:00",
"created_at": "2026-10-01T10:02:11.583000+00:00"
}
},
"created_at": "2026-10-01T10:02:15.912000+00:00"
}{
"error": "Event not found"
}