La Ingestion API: streaming vs bulk
Ingesta programática para cuando ningún conector empaquetado encaja: los dos patrones de la Ingestion API — Streaming (payloads chicos, near-real-time, asincrónicos) y Bulk (cargas de archivos/CSV grandes) — cuándo encaja cada uno, cuándo agarrar la API en vez de un conector, y el requisito previo de que haya una fuente y un schema definidos antes de mandar un solo registro.
La Ingestion API es cómo empujás datos hacia Data 360 (antes Data Cloud) desde un sistema que ningún conector empaquetado cubre. Un conector conoce la forma de su fuente — Salesforce CRM, Marketing Cloud, un bucket de S3 — y te la aterriza en un schedule. La Ingestion API no sabe nada hasta que vos se lo decís: definís primero la fuente y su schema, y después tu propio código manda registros contra ese contrato. Es la salida de emergencia programática para apps custom, servicios internos y streams de eventos que no tienen un conector propio.
Esta página es la referencia de qué es la API y cómo difieren sus dos patrones. Los dos patrones son Streaming y Bulk, y elegir entre ellos es la primera decisión que tomás — comparten el setup pero no se comportan en nada parecido al momento de enviar. Los dos aterrizan sus datos como un Data Lake Object (__dll), exactamente como cualquier otro Data Stream; el modelado que convierte un DLO en algo que el resto de la plataforma lee es trabajo de Data Architecture, no de esta página (ver mapear el DLO a un DMO).
El requisito previo: una fuente y un schema definidos antes de enviar
A diferencia de un conector, la API no tiene idea de cómo lucen tus datos hasta que se los describís. Antes de que fluya un solo registro tenés que registrar una fuente de ingesta y definir el schema de cada objeto que vas a mandar — los nombres de campo y los tipos a los que el payload tiene que conformarse. Ese schema es el contrato: un registro que no matchea es rechazado o descartado en silencio, no forzado a la forma.
Es la misma disciplina que el principio 1 pide en todos lados — modelá las keys y la forma antes de que fluyan los datos — aplicada en el borde de la API. El schema que registrás acá se vuelve un DLO, y cada decisión downstream lo hereda. Equivocá los tipos de campo en el registro y vas a re-aterrizar la fuente entera más tarde, después de que los segmentos ya la estén leyendo.
Streaming: chico, near-real-time, asincrónico
El patrón Streaming es para mandar registros a medida que pasan, en payloads chicos, cerca del tiempo real. Tu aplicación hace una llamada que carga un puñado de registros — una orden colocada, un carrito abandonado, un perfil actualizado — y la API los acepta de forma asincrónica: acusa recibo y procesa los datos hacia el DLO poco después, en vez de hacerte esperar a que el aterrizaje se complete en la misma llamada.
Esa forma asincrónica e incremental es justo el punto. Streaming es cómo la ingesta compra la freshness que el principio 6 llama una feature: cuando una decisión downstream necesita reflejar lo que acaba de pasar — una activación en tiempo real, un agente respondiendo sobre un cliente en plena sesión — los datos tienen que llegar de forma continua, no en un batch nocturno. Streaming alimenta esa necesidad en la fuente. (Freshness es una propiedad que tenés que diseñar de punta a punta; hacer streaming de la ingesta es necesario, no suficiente — la cadencia de todo lo de abajo también tiene que matchear. Ver refresh modes.)
Streaming es la elección correcta cuando:
- Los registros se generan de forma continua e individual, no ensamblados en archivos.
- Un consumidor downstream genuinamente necesita datos near-real-time — no "más fresco es lindo", sino una decisión que está mal con datos viejos.
- Cada payload es chico. Streaming está hecho para muchas llamadas chicas, no para despachar un millón de filas en un solo request.
Bulk: archivos grandes, menos llamadas, cargas programadas
El patrón Bulk es para la forma opuesta: grandes volúmenes de datos entregados como archivos — cargas de CSV — en vez de un stream de registros individuales. Stageás un archivo (o un conjunto de archivos) y la API lo ingiere como un job. Es el patrón para un backfill inicial, un export periódico desde otro sistema, o cualquier carga donde los datos ya existen como un batch y no hay ningún valor en irlos goteando de a un registro por vez.
Bulk cambia latencia por throughput. No es near-real-time — un job de bulk aterriza en su propio schedule — y eso es justo lo correcto cuando la fuente misma es batch. Cargar el export completo de ayer cada mañana no tiene por qué ser un stream de millones de llamadas de streaming; eso costaría más y no ganaría nada, porque los datos no están más frescos que el export diario del que vinieron (principio 11 — el costo escala con lo que procesás).
Bulk es la elección correcta cuando:
- Los datos llegan como archivos, o se producen naturalmente en batches.
- El volumen es alto — un backfill o una carga grande recurrente, donde un job le gana a millones de llamadas chicas.
- No se requiere near-real-time: la decisión más fresca que alimentan los datos está bien con una cadencia de batch.
Los dos patrones no son un ranking — ninguno es "mejor". Matchean dos formas distintas de fuente. Una fuente custom que emite tanto eventos en vivo como un archivo de reconciliación nocturno legítimamente usa los dos: streaming para los eventos, bulk para el archivo.
Cuándo agarrar la API vs un conector
La API es la salida de emergencia, no el default. Si un conector empaquetado cubre tu fuente, usalo: un conector se configura, no se codea, te maneja la auth y el descubrimiento de schema, y hay menos código propio que mantener y debuguear. La decisión es directa:
- Usá un conector cuando existe uno para tu fuente — CRM, Marketing Cloud, S3, Google Cloud Storage, Azure Storage, el Web/Mobile SDK, o un warehouse zero-copy. Ver conectores para el conjunto común y para qué sirve cada uno.
- Usá la Ingestion API cuando ningún conector encaja: una aplicación custom, un servicio interno, un pipeline de eventos casero, o cualquier sistema cuyos datos controlás en código y querés empujar bajo tus propios términos.
No agarres la API para tener "más control" sobre una fuente que un conector ya maneja bien — eso es código custom que ahora poseés para siempre, en lugar de configuración que la plataforma mantiene. Agarrala cuando genuinamente no hay un camino con forma de conector para entrar.
Una nota sobre los específicos
Los dos patrones — Streaming para payloads chicos, asincrónicos, near-real-time, y Bulk para cargas de archivos grandes — son estables y vale la pena fijarlos en la memoria. Los paths exactos de endpoint, los formatos de request, los límites de tamaño de payload y el flujo de autenticación son específicos de la versión y cambian; esta página deliberadamente no los clava. Antes de construir, verificá la referencia actual de la API para el contrato concreto. Tratá cualquier forma de payload de abajo como ilustrativa de la idea, no como un spec literal:
// SOLO ILUSTRATIVO — verificá la referencia actual de la Ingestion API para
// el endpoint, el formato de payload y los límites reales. La forma se muestra
// para transmitir la idea: un payload chico de streaming que carga unos pocos
// registros que matchean el schema registrado.
{
"data": [
{
"external_id": "cust-10293",
"email": "person@example.com",
"event_type": "cart_abandoned",
"event_timestamp": "2026-06-01T14:32:00Z"
}
]
}Los campos del registro matchean el schema que registraste para la fuente; event_timestamp es el tipo de campo de event-time que un stream de Engagement requiere (ver data streams para las categorías de stream). Aterrizalo bien acá y el resto del lifecycle — modelado, identidad, query, activación — hereda datos limpios. Aterrizalo mal, y el bug aparece tres capas más abajo donde es más difícil de rastrear (ver debugging ingestion).
Relacionado
- Conectores — las fuentes empaquetadas a preferir antes de agarrar la API, y para qué sirve cada una
- Data streams — la unidad de ingesta que la API alimenta: fuente → DLO, categorías de stream, y schedule
- Refresh modes — full refresh vs upsert, la primary key, y cómo se actualiza una fuente streameada o cargada por bulk
- Debugging ingestion — cuando una fuente custom aterriza mal: registros faltantes, schemas que no matchean, un stream que no refresca
Referencia: