Server-side events
Send batches of events from your own servers to VYG with an API key.
POST https://cdp.vyg.app/cdp/eventsSend events from your servers to update customer profiles, such as shipments or closed support
tickets. Use a vyg_ API key.
An accepted request returns 202. Events may take time to appear on a customer profile. The legacy ?sync=true parameter has no effect.
Request
POST /cdp/events
Content-Type: application/json
Authorization: Bearer vyg_your_api_keyThis route accepts vyg_ API keys only. Sign-in (OAuth) access tokens are rejected with
401 here. See API keys.
- Batch limit: at most 50 events per request. A larger batch is rejected
400and no events are accepted. - Request size: 256 KB. A larger body is rejected with
413. - Omit
scope,shopDomain, andsourcethroughout the batch. These fields are not accepted by this endpoint. Including one returns400with the field's JSON path.
Event fields
| Field | Type | Required | Notes |
|---|---|---|---|
eventType | string | yes | A letter followed by letters/digits/underscores (max 64 chars). |
profileId | string | yes | Max 60 chars, no : characters. |
sessionId | string | no | Max 60 chars, no : characters. Generated automatically if omitted. |
properties | object | no | Event properties. Must not contain scope/shopDomain. |
flattenedProperties | object | no | Flattened properties. Must not contain scope/shopDomain. |
timeStamp | string | no | ISO-8601. Defaults to the time VYG receives the event. |
target | object | no | { itemId, itemType, properties? } — no scope. |
Unknown event fields produce a validation error for that event.
Body (example)
{
"events": [
{
"eventType": "orderShipped",
"profileId": "shopify_your-shop_1234567890",
"properties": { "orderId": "5678", "carrier": "ups" }
},
{
"eventType": "supportTicketClosed",
"profileId": "shopify_your-shop_1234567890",
"sessionId": "support-20260611-0001",
"properties": { "ticketId": "T-991" }
}
]
}Response
202 Accepted reports the accepted count and any validation errors. Valid events
in a batch can be accepted even when other events are rejected:
{
"accepted": 1,
"rejected": [
{
"index": 1,
"errors": [
{
"path": "$.events[1].profileId",
"message": "profileId must not contain \":\""
}
]
}
],
"scope": "your-shop.myshopify.com"
}accepted— number of events accepted for processing.rejected[]— one entry per invalid event: itsindexin youreventsarray and the validationerrorswith JSON paths into your request body.
Example
curl -s -X POST "https://cdp.vyg.app/cdp/events" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer vyg_your_api_key" \
-d '{
"events": [
{ "eventType": "orderShipped", "profileId": "shopify_your-shop_123", "properties": { "orderId": "5678" } }
]
}'Errors
Errors may contain {"error": {"code", "message"}} or {"message": "..."}.
Check the HTTP status first, and read error.code when present.
| Status | code | When |
|---|---|---|
400 | bad_request | Body is not valid JSON, has no events array, the array is empty, or it holds more than 50 events. |
400 | bad_request | Any event carries scope, shopDomain, or source. The body also has rejected, with the per-event JSON paths. |
401 | unauthorized | Missing or invalid API key. Sign-in tokens are not accepted. |
403 | insufficient_scope | Customer data features are not enabled, or no store is connected. |
404 | none | Method other than POST / OPTIONS. The response contains {"message":"Not Found"}. |
413 | bad_request | Body exceeds the 256 KB cap. |
500 | internal | An unexpected error on VYG's side. |
503 | unavailable | The service was unavailable. Without failed, no events were accepted: retry the batch. |
503 | unavailable | Some events were accepted. accepted counts them and failed lists the indexes to resend; resend only those. |
An example of a disallowed field:
{
"error": {
"code": "bad_request",
"message": "Events must not carry scope, shopDomain or source. The scope is set server-side from your API credential."
},
"rejected": [
{
"index": 0,
"errors": [
{
"path": "$.events[0].properties.scope",
"message": "scope is bound server-side from your API credential and must not be supplied"
}
]
}
]
}See Collect errors for details.
Identifier limits
profileId and sessionId are identifiers of at most 60 characters with no :
characters. Use underscores to combine values, for example
shopify_your-shop_1234567890.
Metering
Each batch counts as one API request.