vendor/braze · vendor documented
Braze user track wants ISO 8601, not epoch
events[].time and purchases[].time are ISO 8601 datetimes. An epoch number fails the contract. Every event and purchase needs one of external_id, user_alias, braze_id, email, or phone. Sending two primary identifiers rejects the object.
A purchase also needs product_id, an ISO 4217 currency code, and a numeric price. Quantity, when sent, is 1 through 100. A symbol like $ is not a currency code. Custom properties must not reuse reserved names such as time.
What this pack matches
Rules
Codes are stable. A finding in CI, MCP, or the playground lands on the same id.
| Field | Required | What it checks | Rule ids | Source |
|---|---|---|---|---|
external_id |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.external_id.empty |
docs |
user_alias |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.user_alias.empty |
docs |
braze_id |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.braze_id.empty |
docs |
email |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.email.empty |
docs |
phone |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.phone.empty |
docs |
app_id |
optional | It is the App Identifier. Braze documents it as optional on events. Fix: Send `app_id` as the App Identifier from Braze, or drop the empty pair. | vendor.braze.body.app_id.empty |
docs |
user_alias.alias_name |
optional | It is the alias identifier. Braze documents it as required on a user alias object, at most 236 bytes. Fix: Set `user_alias.alias_name` to a non-empty identifier of at most 236 bytes. | vendor.braze.body.user_alias.alias_name.emptyvendor.braze.body.user_alias.alias_name.invalid |
docs |
user_alias.alias_label |
optional | It is the alias type. Braze documents it as required on a user alias object, at most 236 bytes. Fix: Set `user_alias.alias_label` to a non-empty label of at most 236 bytes. | vendor.braze.body.user_alias.alias_label.emptyvendor.braze.body.user_alias.alias_label.invalid |
docs |
name |
required | Braze documents the event name as required. Fix: Name the custom event. | vendor.braze.body.name.missingvendor.braze.body.name.empty |
docs |
time |
required | Braze documents the event time as an ISO 8601 datetime, such as `2026-07-26T06:00:00+00:00`. Fix: Send an ISO 8601 datetime rather than an epoch number. | vendor.braze.body.time.missingvendor.braze.body.time.emptyvendor.braze.body.time.invalid |
docs |
_update_existing_only |
optional | Braze documents this as a boolean. When true, the call updates an existing profile and does not create one. | vendor.braze.body._update_existing_only.emptyvendor.braze.body._update_existing_only.invalid |
docs |
properties.time |
forbidden | Braze reserves `time` as an event field, not as a custom property name. Fix: Rename the property. `time` is reserved. | vendor.braze.body.properties.time.forbidden |
docs |
properties.event_name |
forbidden | Braze reserves `event_name` and cannot use it as a custom property. Fix: Rename the property. `event_name` is reserved. | vendor.braze.body.properties.event_name.forbidden |
docs |
body.event_one_primary_identifier |
required | The event carries more than one primary identifier. Braze documents one of `external_id`, `user_alias`, or `braze_id` per object, and rejects the object when two are sent. Fix: Send one primary identifier. `email` and `phone` may ride alongside it as attributes. | vendor.braze.body.event_one_primary_identifier |
docs |
body.event_needs_an_identifier |
required | The object carries none of `external_id`, `user_alias`, `braze_id`, `email`, or `phone`. Braze documents one of them as required, and cannot attach the data to a user without one. Fix: Add one of the documented identifiers to the object. | vendor.braze.body.event_needs_an_identifier |
docs |
body.event_alias_requires_name_and_label |
required | A `user_alias` object is missing `alias_name` or `alias_label`. Braze documents both as required, each at most 236 bytes. Fix: Set `user_alias.alias_name` and `user_alias.alias_label`. | vendor.braze.body.event_alias_requires_name_and_label |
docs |
external_id |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.external_id.empty |
docs |
user_alias |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.user_alias.empty |
docs |
braze_id |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.braze_id.empty |
docs |
email |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.email.empty |
docs |
phone |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.phone.empty |
docs |
app_id |
optional | It is the App Identifier. Braze documents it as optional on purchases. Fix: Send `app_id` as the App Identifier from Braze, or drop the empty pair. | vendor.braze.body.app_id.empty |
docs |
user_alias.alias_name |
optional | It is the alias identifier. Braze documents it as required on a user alias object, at most 236 bytes. Fix: Set `user_alias.alias_name` to a non-empty identifier of at most 236 bytes. | vendor.braze.body.user_alias.alias_name.emptyvendor.braze.body.user_alias.alias_name.invalid |
docs |
user_alias.alias_label |
optional | It is the alias type. Braze documents it as required on a user alias object, at most 236 bytes. Fix: Set `user_alias.alias_label` to a non-empty label of at most 236 bytes. | vendor.braze.body.user_alias.alias_label.emptyvendor.braze.body.user_alias.alias_label.invalid |
docs |
product_id |
required | Braze documents the product id as required on a purchase, at most 255 characters. Fix: Send a product name or category of at most 255 characters. | vendor.braze.body.product_id.missingvendor.braze.body.product_id.emptyvendor.braze.body.product_id.invalid |
docs |
currency |
required | Braze documents the currency as required on a purchase, as an ISO 4217 code. Fix: Use the three-letter code, such as `USD`. | vendor.braze.body.currency.missingvendor.braze.body.currency.emptyvendor.braze.body.currency.invalid |
docs |
price |
required | Braze documents the price as a float in the currency's base unit, such as dollars for USD. Fix: Send a number such as `129.99`, with no currency symbol. | vendor.braze.body.price.missingvendor.braze.body.price.emptyvendor.braze.body.price.invalid |
docs |
quantity |
optional | Braze documents quantity as an integer from 1 through 100, defaulting to 1. Fix: Send an integer from 1 to 100. | vendor.braze.body.quantity.emptyvendor.braze.body.quantity.invalid |
docs |
time |
required | Braze documents the purchase time as an ISO 8601 datetime. Fix: Send an ISO 8601 datetime rather than an epoch number. | vendor.braze.body.time.missingvendor.braze.body.time.emptyvendor.braze.body.time.invalid |
docs |
_update_existing_only |
optional | Braze documents this as a boolean. When true, the call updates an existing profile and does not create one. | vendor.braze.body._update_existing_only.emptyvendor.braze.body._update_existing_only.invalid |
docs |
properties.time |
forbidden | Braze reserves `time` and cannot use it as a purchase property name. Fix: Rename the property. `time` is reserved. | vendor.braze.body.properties.time.forbidden |
docs |
properties.product_id |
forbidden | Braze reserves `product_id` and cannot use it as a purchase property name. Fix: Rename the property. `product_id` is reserved. | vendor.braze.body.properties.product_id.forbidden |
docs |
properties.quantity |
forbidden | Braze reserves `quantity` and cannot use it as a purchase property name. Fix: Rename the property. `quantity` is reserved. | vendor.braze.body.properties.quantity.forbidden |
docs |
properties.event_name |
forbidden | Braze reserves `event_name` and cannot use it as a purchase property name. Fix: Rename the property. `event_name` is reserved. | vendor.braze.body.properties.event_name.forbidden |
docs |
properties.price |
forbidden | Braze reserves `price` and cannot use it as a purchase property name. Fix: Rename the property. `price` is reserved. | vendor.braze.body.properties.price.forbidden |
docs |
properties.currency |
forbidden | Braze reserves `currency` and cannot use it as a purchase property name. Fix: Rename the property. `currency` is reserved. | vendor.braze.body.properties.currency.forbidden |
docs |
body.purchase_one_primary_identifier |
required | The purchase carries more than one primary identifier. Braze documents one of `external_id`, `user_alias`, or `braze_id` per object, and rejects the object when two are sent. Fix: Send one primary identifier. `email` and `phone` may ride alongside it as attributes. | vendor.braze.body.purchase_one_primary_identifier |
docs |
body.purchase_needs_an_identifier |
required | The object carries none of `external_id`, `user_alias`, `braze_id`, `email`, or `phone`. Braze documents one of them as required, and cannot attach the data to a user without one. Fix: Add one of the documented identifiers to the object. | vendor.braze.body.purchase_needs_an_identifier |
docs |
body.purchase_alias_requires_name_and_label |
required | A `user_alias` object is missing `alias_name` or `alias_label`. Braze documents both as required, each at most 236 bytes. Fix: Set `user_alias.alias_name` and `user_alias.alias_label`. | vendor.braze.body.purchase_alias_requires_name_and_label |
docs |
external_id |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.external_id.empty |
docs |
user_alias |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.user_alias.empty |
docs |
braze_id |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.braze_id.empty |
docs |
email |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.email.empty |
docs |
phone |
optional | Braze documents one of external_id, user_alias, braze_id, email, or phone as required on every object. | vendor.braze.body.phone.empty |
docs |
user_alias.alias_name |
optional | It is the alias identifier. Braze documents it as required on a user alias object, at most 236 bytes. Fix: Set `user_alias.alias_name` to a non-empty identifier of at most 236 bytes. | vendor.braze.body.user_alias.alias_name.emptyvendor.braze.body.user_alias.alias_name.invalid |
docs |
user_alias.alias_label |
optional | It is the alias type. Braze documents it as required on a user alias object, at most 236 bytes. Fix: Set `user_alias.alias_label` to a non-empty label of at most 236 bytes. | vendor.braze.body.user_alias.alias_label.emptyvendor.braze.body.user_alias.alias_label.invalid |
docs |
_update_existing_only |
optional | Braze documents this as a boolean. When true, the call updates an existing profile and does not create one. | vendor.braze.body._update_existing_only.emptyvendor.braze.body._update_existing_only.invalid |
docs |
push_token_import |
optional | Braze documents this as a boolean used when importing anonymous push tokens. | vendor.braze.body.push_token_import.emptyvendor.braze.body.push_token_import.invalid |
docs |
gender |
optional | Braze documents gender as `M`, `F`, `O`, `N`, `P`, or null. Fix: Send `M`, `F`, `O`, `N`, or `P`, or omit the field. | vendor.braze.body.gender.emptyvendor.braze.body.gender.invalid |
docs |
email_subscribe |
optional | Braze documents email subscription as `opted_in`, `unsubscribed`, or `subscribed`. Fix: Send `opted_in`, `unsubscribed`, or `subscribed`. | vendor.braze.body.email_subscribe.emptyvendor.braze.body.email_subscribe.invalid |
docs |
push_subscribe |
optional | Braze documents push subscription as `opted_in`, `unsubscribed`, or `subscribed`. Fix: Send `opted_in`, `unsubscribed`, or `subscribed`. | vendor.braze.body.push_subscribe.emptyvendor.braze.body.push_subscribe.invalid |
docs |
dob |
optional | Braze documents date of birth as `YYYY-MM-DD`. Fix: Send the date of birth as `YYYY-MM-DD`, such as `1980-12-21`. | vendor.braze.body.dob.emptyvendor.braze.body.dob.invalid |
docs |
body.attribute_one_primary_identifier |
required | The attribute object carries more than one primary identifier. Braze documents one of `external_id`, `user_alias`, or `braze_id` per object, and rejects the object when two are sent. Fix: Send one primary identifier. `email` and `phone` may ride alongside it as attributes. | vendor.braze.body.attribute_one_primary_identifier |
docs |
body.attribute_needs_an_identifier |
required | The object carries none of `external_id`, `user_alias`, `braze_id`, `email`, or `phone`. Braze documents one of them as required, and cannot attach the data to a user without one. Fix: Add one of the documented identifiers to the object. | vendor.braze.body.attribute_needs_an_identifier |
docs |
body.attribute_alias_requires_name_and_label |
required | A `user_alias` object is missing `alias_name` or `alias_label`. Braze documents both as required, each at most 236 bytes. Fix: Set `user_alias.alias_name` and `user_alias.alias_label`. | vendor.braze.body.attribute_alias_requires_name_and_label |
docs |
Validate a payload
pixellint validate json @payload.json --rulepack vendor/braze
Try this failing payload in the playground. Braze event with two primary identifiers.
{"events":[{"external_id":"user-10024","braze_id":"braze-77","name":"order_placed","time":"2026-07-26T06:00:00+00:00"}]}
cargo install pixellint
·
npm install pixellint