Microsoft CAPI events need eventType, seconds, and a match key
POST JSON to /v1/{tagId}/events. eventType is pageLoad or custom. eventTime is Unix seconds, a 10-digit value. userData needs anonymousId, externalId, em, ph, msclkid, idfa, or gaid. pageLoad needs eventSourceUrl. pageLoadId is a UUID. adStorageConsent is G or D. em is SHA-256 hex. IP and user agent stay unhashed. Browser UET on bat.bing.com is vendor/microsoft-uet.
customData.value needs a currency code
Microsoft documents the ISO 4217 code together with the revenue value. A number without currency is incomplete.
Rule: vendor.microsoft-conversions-api.body.value_requires_currency
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 |
|---|---|---|---|---|
tag_id |
required | It is the numeric UET tag ID, and it travels in the path as /v1/{tagId}/events. Fix: Put the UET tag ID from Microsoft Advertising in the path as /v1/{tagId}/events. | vendor.microsoft-conversions-api.param.tag_id.missingvendor.microsoft-conversions-api.param.tag_id.emptyvendor.microsoft-conversions-api.param.tag_id.invalid |
docs |
data |
required | Microsoft documents `data` as the list of events. An empty list sends nothing. Native JSON type: array. Minimum array items: 1. Maximum array items: 1000. Fix: Send at least one event in `data`. | vendor.microsoft-conversions-api.body.data.missingvendor.microsoft-conversions-api.body.data.invalid |
docs |
continueOnValidationError |
optional | It is whether a batch should skip invalid events. Microsoft documents `true` to skip them and `false` (the default) to reject the whole request. Native JSON type: boolean. Fix: Send `true` or `false` in `continueOnValidationError`. | vendor.microsoft-conversions-api.body.continueOnValidationError.emptyvendor.microsoft-conversions-api.body.continueOnValidationError.invalid |
docs |
root |
optional | Each event is a JSON object, rather than a scalar or list. Native JSON type: object. | vendor.microsoft-conversions-api.body.root.invalid |
docs |
data[] |
optional | The vendor documents the JSON shape or value type of this field. Native JSON type: object. | vendor.microsoft-conversions-api.body.data[].invalid |
docs |
dataProvider |
optional | Third-party senders identify themselves with this request-level string. Native JSON type: string. | vendor.microsoft-conversions-api.body.dataProvider.invalid |
docs |
eventType |
required | It is the event type. Microsoft documents `pageLoad` or `custom`. Body scope: data[]. Native JSON type: string. Fix: Set `eventType` to `pageLoad` or `custom`. | vendor.microsoft-conversions-api.body.eventType.missingvendor.microsoft-conversions-api.body.eventType.emptyvendor.microsoft-conversions-api.body.eventType.invalid |
docs |
eventTime |
required | It is Unix epoch time in seconds UTC. Microsoft documents seconds, so a 13-digit value is milliseconds and the wrong unit. Body scope: data[]. Native JSON type: integer. Fix: Send seconds, a 10-digit Unix timestamp, not milliseconds. | vendor.microsoft-conversions-api.body.eventTime.missingvendor.microsoft-conversions-api.body.eventTime.emptyvendor.microsoft-conversions-api.body.eventTime.invalid |
docs |
eventId |
recommended | It identifies the event so UET JavaScript and CAPI can deduplicate. Microsoft documents it as required for deduplication. Body scope: data[]. Native JSON type: string. Fix: Set `eventId` to the same value the UET tag sent. | vendor.microsoft-conversions-api.body.eventId.missingvendor.microsoft-conversions-api.body.eventId.emptyvendor.microsoft-conversions-api.body.eventId.invalid |
docs |
eventName |
optional | It is the custom conversion action. Microsoft documents it for custom conversion goals. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.eventName.emptyvendor.microsoft-conversions-api.body.eventName.invalid |
docs |
eventSourceUrl |
optional | It is the page URL. Microsoft documents it as required on `pageLoad` events. Body scope: data[]. Native JSON type: string. Fix: Set `eventSourceUrl` to the absolute page URL. | vendor.microsoft-conversions-api.body.eventSourceUrl.emptyvendor.microsoft-conversions-api.body.eventSourceUrl.invalid |
docs |
referrerUrl |
optional | It is the page referrer, used for referral remarketing lists. Microsoft documents a URL. Body scope: data[]. Native JSON type: string. Fix: Send an absolute URL in `referrerUrl`, or omit the field. | vendor.microsoft-conversions-api.body.referrerUrl.emptyvendor.microsoft-conversions-api.body.referrerUrl.invalid |
docs |
pageLoadId |
optional | It links custom events to a page load. Microsoft documents a v4 UUID. Body scope: data[]. Fix: Send a UUID such as `bcf3000b-65fa-4cd2-808a-8a6cf2b1d0a5`. | vendor.microsoft-conversions-api.body.pageLoadId.emptyvendor.microsoft-conversions-api.body.pageLoadId.invalid |
docs |
adStorageConsent |
optional | It is the advertising-storage consent signal. Microsoft documents `G` for granted and `D` for denied. Body scope: data[]. Native JSON type: string. Fix: Set `adStorageConsent` to `G` or `D`. | vendor.microsoft-conversions-api.body.adStorageConsent.emptyvendor.microsoft-conversions-api.body.adStorageConsent.invalid |
docs |
userData |
required | Microsoft documents `userData` as required, with at least one supported identifier. Body scope: data[]. Native JSON type: object. Fix: Add a `userData` object with at least one of `anonymousId`, `externalId`, `em`, `ph`, `msclkid`, `idfa`, or `gaid`. | vendor.microsoft-conversions-api.body.userData.missingvendor.microsoft-conversions-api.body.userData.invalid |
docs |
userData.anonymousId |
optional | It is the guest visitor ID, also used for ID Sync. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.userData.anonymousId.emptyvendor.microsoft-conversions-api.body.userData.anonymousId.invalid |
docs |
userData.externalId |
optional | It is an anonymized signed-in user ID. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.userData.externalId.emptyvendor.microsoft-conversions-api.body.userData.externalId.invalid |
docs |
userData.em |
optional | It is the SHA-256 hex digest of the email. Microsoft documents lowercase hex after trim and lowercase. Body scope: data[]. Value diagnostic severity: warning. Native JSON type: string. Fix: Trim, lowercase, SHA-256, and send 64 lowercase hex characters. | vendor.microsoft-conversions-api.body.userData.em.emptyvendor.microsoft-conversions-api.body.userData.em.invalid |
docs |
userData.ph |
optional | It is the SHA-256 hex digest of the phone number. Body scope: data[]. Value diagnostic severity: warning. Native JSON type: string. Fix: Normalize the phone, SHA-256, and send 64 lowercase hex characters. | vendor.microsoft-conversions-api.body.userData.ph.emptyvendor.microsoft-conversions-api.body.userData.ph.invalid |
docs |
userData.msclkid |
optional | It is the Microsoft Click ID. Microsoft documents it as a UUID. Body scope: data[]. Fix: Send the `msclkid` captured from the landing URL as a UUID. | vendor.microsoft-conversions-api.body.userData.msclkid.emptyvendor.microsoft-conversions-api.body.userData.msclkid.invalid |
docs |
userData.idfa |
optional | It is the iOS Identifier for Advertisers. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.userData.idfa.emptyvendor.microsoft-conversions-api.body.userData.idfa.invalid |
docs |
userData.gaid |
optional | It is the Android advertising ID. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.userData.gaid.emptyvendor.microsoft-conversions-api.body.userData.gaid.invalid |
docs |
userData.clientIpAddress |
optional | It is the visitor IP, IPv4 or IPv6, sent unhashed. Microsoft documents it as preferred. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.userData.clientIpAddress.emptyvendor.microsoft-conversions-api.body.userData.clientIpAddress.invalid |
docs |
userData.clientUserAgent |
optional | It is the visitor user agent, sent unhashed. Microsoft documents it as preferred. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.userData.clientUserAgent.emptyvendor.microsoft-conversions-api.body.userData.clientUserAgent.invalid |
docs |
customData.currency |
optional | It is the ISO 4217 currency of `customData.value`. Body scope: data[]. Fix: Use a three-letter code such as `USD`. | vendor.microsoft-conversions-api.body.customData.currency.emptyvendor.microsoft-conversions-api.body.customData.currency.invalid |
docs |
customData.value |
optional | It is the revenue value for variable-revenue goals. Microsoft documents a decimal number together with `currency`. Body scope: data[]. Native JSON type: number. Fix: Send a number such as `123.45`, with no currency symbol. | vendor.microsoft-conversions-api.body.customData.value.invalid |
docs |
customData.eventValue |
optional | It is the event value for custom conversion goals. Microsoft documents a float. Body scope: data[]. Native JSON type: number. | vendor.microsoft-conversions-api.body.customData.eventValue.invalid |
docs |
customData.transactionId |
optional | It is a unique id for singular events such as a purchase. Microsoft documents it as optional but recommended. Body scope: data[]. Native JSON type: string. Fix: Send `customData.transactionId`, or drop the empty pair. | vendor.microsoft-conversions-api.body.customData.transactionId.emptyvendor.microsoft-conversions-api.body.customData.transactionId.invalid |
docs |
customData.pageType |
optional | It is the ecommerce page type for dynamic remarketing. Microsoft documents a closed set. Body scope: data[]. Native JSON type: string. Fix: Set `customData.pageType` to `cart`, `category`, `home`, `other`, `product`, `purchase`, or `searchresults`. | vendor.microsoft-conversions-api.body.customData.pageType.emptyvendor.microsoft-conversions-api.body.customData.pageType.invalid |
docs |
customData.ecommTotalValue |
optional | It is the total value of the cart or purchase. Microsoft documents a decimal. Body scope: data[]. Native JSON type: number. Fix: Send a number such as `123.45`, with no currency symbol. | vendor.microsoft-conversions-api.body.customData.ecommTotalValue.invalid |
docs |
customData.items[].id |
optional | It is the item id on an `items` row. Microsoft documents `id` as preferred on each product object. Body scope: data[]. Native JSON type: string. Fix: Set `customData.items[].id` to the catalog item ID, or drop the empty pair. | vendor.microsoft-conversions-api.body.customData.items[].id.emptyvendor.microsoft-conversions-api.body.customData.items[].id.invalid |
docs |
customData.items[].quantity |
optional | It is the item quantity on an `items` row. Microsoft documents an integer. Body scope: data[]. Native JSON type: integer. Fix: Send `customData.items[].quantity` as an integer, such as `2`. | vendor.microsoft-conversions-api.body.customData.items[].quantity.emptyvendor.microsoft-conversions-api.body.customData.items[].quantity.invalid |
docs |
customData.items[].price |
optional | It is the item price after discounts. Microsoft documents a decimal. Body scope: data[]. Native JSON type: number. Fix: Send `customData.items[].price` as a number, such as `25.1`. | vendor.microsoft-conversions-api.body.customData.items[].price.invalid |
docs |
customData.hotelData.checkinDate |
optional | It is the hotel check-in date. Microsoft documents `YYYY-MM-DD`. Body scope: data[]. Fix: Send `customData.hotelData.checkinDate` as `YYYY-MM-DD`, such as `2018-10-27`. | vendor.microsoft-conversions-api.body.customData.hotelData.checkinDate.emptyvendor.microsoft-conversions-api.body.customData.hotelData.checkinDate.invalid |
docs |
customData.hotelData.checkoutDate |
optional | It is the hotel check-out date. Microsoft documents `YYYY-MM-DD`. Body scope: data[]. Fix: Send `customData.hotelData.checkoutDate` as `YYYY-MM-DD`, such as `2018-10-31`. | vendor.microsoft-conversions-api.body.customData.hotelData.checkoutDate.emptyvendor.microsoft-conversions-api.body.customData.hotelData.checkoutDate.invalid |
docs |
customData.hotelData.totalPrice |
optional | It is the total booking price including taxes and fees. Microsoft documents a decimal. Body scope: data[]. Native JSON type: number. Fix: Send a number such as `188.23`, with no currency symbol. | vendor.microsoft-conversions-api.body.customData.hotelData.totalPrice.invalid |
docs |
customData.hotelData.basePrice |
optional | It is the booking price excluding taxes and fees. Microsoft documents a decimal. Body scope: data[]. Native JSON type: number. Fix: Send a number such as `165.76`, with no currency symbol. | vendor.microsoft-conversions-api.body.customData.hotelData.basePrice.invalid |
docs |
customData.hotelData.lengthOfStay |
optional | It is the number of nights. Microsoft documents an integer, and it is not required when `checkoutDate` is sent. Body scope: data[]. Native JSON type: integer. Fix: Send `customData.hotelData.lengthOfStay` as an integer, such as `4`. | vendor.microsoft-conversions-api.body.customData.hotelData.lengthOfStay.emptyvendor.microsoft-conversions-api.body.customData.hotelData.lengthOfStay.invalid |
docs |
root |
optional | Each event is a JSON object, rather than a scalar or list. Body scope: data[]. Native JSON type: object. | vendor.microsoft-conversions-api.body.root.invalid |
docs |
customData |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: object. | vendor.microsoft-conversions-api.body.customData.invalid |
docs |
customData.hotelData |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: object. | vendor.microsoft-conversions-api.body.customData.hotelData.invalid |
docs |
customData.items |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: array. Minimum array items: 1. | vendor.microsoft-conversions-api.body.customData.items.invalid |
docs |
customData.items[] |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: object. | vendor.microsoft-conversions-api.body.customData.items[].invalid |
docs |
pageTitle |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.pageTitle.invalid |
docs |
keywords |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.keywords.invalid |
docs |
customData.searchTerm |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.customData.searchTerm.invalid |
docs |
customData.eventCategory |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.customData.eventCategory.invalid |
docs |
customData.eventLabel |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.customData.eventLabel.invalid |
docs |
customData.itemIds |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: array. | vendor.microsoft-conversions-api.body.customData.itemIds.invalid |
docs |
customData.itemIds[] |
optional | The vendor documents the JSON shape or value type of this field. Body scope: data[]. Native JSON type: string. | vendor.microsoft-conversions-api.body.customData.itemIds[].invalid |
docs |
body.user_needs_an_identifier |
required | `userData` carries none of the identifiers Microsoft requires. Send `anonymousId`, `externalId`, `em`, `ph`, `msclkid`, `idfa`, or `gaid`. Body scope: data[]. Fix: Add at least one supported identifier inside `userData`. | vendor.microsoft-conversions-api.body.user_needs_an_identifier |
docs |
body.page_load_requires_url |
required | The event is `pageLoad` but carries no `eventSourceUrl`. Microsoft documents the page URL as required on page load events. Body scope: data[]. Fix: Set `eventSourceUrl` to the absolute page URL. | vendor.microsoft-conversions-api.body.page_load_requires_url |
docs |
body.value_requires_currency |
required | The event sends `customData.value` without `customData.currency`. Microsoft documents the ISO 4217 code together with the revenue value. Body scope: data[]. Fix: Add `customData.currency`, such as `USD`. | vendor.microsoft-conversions-api.body.value_requires_currency |
docs |
body.currency_requires_value |
required | The event sends `customData.currency` without `customData.value`. Microsoft documents both together. Body scope: data[]. Fix: Add `customData.value` as a number, with no currency symbol. | vendor.microsoft-conversions-api.body.currency_requires_value |
docs |
body.unhashed_email |
required | `userData.em` carries what looks like a raw email address. Microsoft documents SHA-256 lowercase hex. Body scope: data[]. Fix: Trim, lowercase, hash with SHA-256, and send the 64-character hex digest. | vendor.microsoft-conversions-api.body.unhashed_email |
docs |
body.hashed_plaintext_field |
required | This field looks like a SHA-256 digest, but Microsoft documents `clientIpAddress` and `clientUserAgent` as unhashed. Body scope: data[]. Fix: Send the raw IP address or user agent. | vendor.microsoft-conversions-api.body.hashed_plaintext_field |
docs |
body.eventTime_time_window |
required | The timestamp is outside the documented processing window. Body scope: data[]. | vendor.microsoft-conversions-api.body.eventTime_time_window |
docs |
method |
required | This endpoint documents POST requests. Complete HTTP capture contract. Native JSON type: string. | vendor.microsoft-conversions-api.http.method.missingvendor.microsoft-conversions-api.http.method.emptyvendor.microsoft-conversions-api.http.method.invalid |
docs |
path |
required | Use the documented event endpoint route. Complete HTTP capture contract. Native JSON type: string. | vendor.microsoft-conversions-api.http.path.missingvendor.microsoft-conversions-api.http.path.emptyvendor.microsoft-conversions-api.http.path.invalid |
docs |
content_type |
required | The request carries an application/json body. Complete HTTP capture contract. Native JSON type: string. | vendor.microsoft-conversions-api.http.content_type.missingvendor.microsoft-conversions-api.http.content_type.emptyvendor.microsoft-conversions-api.http.content_type.invalid |
docs |
body_encoding |
required | The event request is encoded as JSON. Complete HTTP capture contract. Native JSON type: string. | vendor.microsoft-conversions-api.http.body_encoding.missingvendor.microsoft-conversions-api.http.body_encoding.emptyvendor.microsoft-conversions-api.http.body_encoding.invalid |
docs |
headers.authorization |
required | Authenticate with a populated Bearer token. Complete HTTP capture contract. Native JSON type: string. | vendor.microsoft-conversions-api.http.headers.authorization.missingvendor.microsoft-conversions-api.http.headers.authorization.emptyvendor.microsoft-conversions-api.http.headers.authorization.invalid |
docs |
url |
required | The published request endpoint uses HTTPS. Complete HTTP capture contract. Native JSON type: string. | vendor.microsoft-conversions-api.http.url.missingvendor.microsoft-conversions-api.http.url.emptyvendor.microsoft-conversions-api.http.url.invalid |
docs |
Validate a payload
pixellint validate json @payload.json --rulepack vendor/microsoft-conversions-api
Try this failing payload in the playground. Microsoft CAPI with a hashed client IP.
{"data":[{"eventType":"custom","eventId":"evt-1","eventTime":1710438591,"userData":{"anonymousId":"b171a9b06ce011ecafcd1b209be8601b","clientIpAddress":"a85e9ca18f34935ab9b0381b25bfad2455444112b0149270fd88e3da172fe196"}}]}
cargo install pixellint
·
npm install pixellint