Event Ingestion
This reference describes the CDP ingest API for server-to-server customer events.
For the product overview, see CDP → Event Ingestion. For integration guidance, see Developers → CDP Integration.
1. Authentication
Use a CDP API key:
Authorization: Bearer <api_key>2. Endpoints
2.1 POST /v1/cdp/events
Accepts one customer event.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
source | string | ✅ | Source system identifier such as brand.pos or brand.crm. |
externalEventId | string | ✅ | Stable idempotency key for the business fact. |
eventType | string | ✅ | Registered CDP event type. |
occurredAt | ISO 8601 timestamp | ❌ | Time when the business fact happened. Defaults to receipt time when omitted. |
identity | object | ✅ | Inbound identity object used for profile resolution. |
identity.externalUserId | string | ❌ | External upstream user ID mapped to canonical EXTERNAL identity handling. |
identity.email | string | ❌ | Email identifier before normalization. |
identity.phone | string | ❌ | Phone identifier before normalization. |
identity.deviceKey | string | ❌ | Device-bound identifier when available. |
properties | object | ❌ | Registered event properties. |
At least one supported field inside identity must be present.
Example request
{
"source": "brand.pos",
"externalEventId": "txn_987654321",
"eventType": "purchase_completed",
"occurredAt": "2026-05-20T12:45:00Z",
"identity": {
"externalUserId": "L-123456789",
"email": "customer@example.com"
},
"properties": {
"order_id": "order_42",
"amount": 120.50,
"currency": "USD",
"store_id": "store_42"
}
}Accepted response
{
"status": "accepted",
"event_id": "evt_74d63a"
}Duplicate response
{
"status": "duplicate",
"original_event_id": "evt_74d63a"
}2.2 POST /v1/cdp/events/batch
Accepts multiple events in one request.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
items | array | ✅ | Array of event payloads matching POST /v1/cdp/events. |
Example response
{
"results": [
{ "status": "accepted", "event_id": "evt_a" },
{ "status": "duplicate", "original_event_id": "evt_b" },
{
"status": "error",
"error_code": "validation_failed",
"message": "identity.externalUserId, identity.email, identity.phone, or identity.deviceKey is required"
}
]
}Each item is evaluated independently.
3. Validation Rules
eventTypemust be registered in the CDP contract.- Required properties for that event type must be present.
- Unknown or unsupported property shapes may be rejected.
- At least one supported
identityfield must be provided. externalEventIdmust stay stable across retries of the same business fact.
4. Deduplication
ResultFly deduplicates by:
(tenant, source, externalEventId)This allows safe retries after transport failures.
5. Error Semantics
401 Unauthorizedif the API key is invalid.403 Forbiddenif the key lacks permission for the operation.409 Conflictif the request collides with existing protected state in a non-retryable way.422 Unprocessable Entityif validation fails.5xx Server Errorfor transient issues. Retry with the sameexternalEventId.
6. Notes for Integrators
- Send identifiers that are stable in your source systems.
- Treat
externalEventIdas a business idempotency key, not as a request UUID. - Keep event schemas governed. If marketing teams need to segment on a property, that property should be registered and marked accordingly.