vendor/linkedin-conversions-api · vendor documented
LinkedIn conversionHappenedAt is milliseconds
The inverse of Meta. LinkedIn documents milliseconds and rejects events older than 90 days. A 10-digit Unix timestamp is seconds, and as milliseconds it is 1970, which is older than 90 days.
Date.now() is already the right unit. conversion is urn:lla:llaPartnerConversion:ID. user.userIds is required even when you identify on lead, externalIds, or userInfo: send an empty list in those cases.
conversionHappenedAt is 13 digits
Milliseconds since epoch. Do not floor Date.now() / 1000 because the Meta CAPI snippet did.
Rule: vendor.linkedin-conversions-api.body.conversionHappenedAt.invalid
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 |
|---|---|---|---|---|
conversion |
required | It is the conversion rule URN the event is attributed to, in the form `urn:lla:llaPartnerConversion:ID`. Fix: Send the URN of a conversion rule created with `conversionMethod` set to `CONVERSIONS_API`. | vendor.linkedin-conversions-api.body.conversion.missingvendor.linkedin-conversions-api.body.conversion.emptyvendor.linkedin-conversions-api.body.conversion.invalid |
docs |
conversionHappenedAt |
required | LinkedIn documents it as an epoch timestamp in milliseconds, and rejects events older than 90 days. A 10-digit value is seconds and lands in 1970. Fix: Send milliseconds, not seconds: a JavaScript `Date.now()` is already in the right unit. | vendor.linkedin-conversions-api.body.conversionHappenedAt.missingvendor.linkedin-conversions-api.body.conversionHappenedAt.emptyvendor.linkedin-conversions-api.body.conversionHappenedAt.invalid |
docs |
user.userIds |
required | LinkedIn returns a 422 when `user.userIds` is absent. Identifying the person by `lead`, `externalIds`, or `userInfo` instead still requires it, sent as an empty list. Fix: Add `user.userIds`. If you match on something else, send it as an empty list: `"userIds": []`. | vendor.linkedin-conversions-api.body.user.userIds.missing |
docs |
user.userIds[].idType |
required | It names the kind of identifier carried in `idValue`. LinkedIn documents `SHA256_EMAIL`, `LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID`, `ACXIOM_ID`, `PLAINTEXT_IP_ADDRESS`, `SHA256_IP_ADDRESS`, and `GOOGLE_AID`. Fix: Use one of the documented identifier types. | vendor.linkedin-conversions-api.body.user.userIds[].idType.missingvendor.linkedin-conversions-api.body.user.userIds[].idType.emptyvendor.linkedin-conversions-api.body.user.userIds[].idType.invalid |
docs |
user.userIds[].idValue |
required | LinkedIn rejects the event when an identifier is present but empty. Fix: Populate `idValue`, or drop the entry entirely rather than sending it blank. | vendor.linkedin-conversions-api.body.user.userIds[].idValue.missingvendor.linkedin-conversions-api.body.user.userIds[].idValue.empty |
docs |
user.lead |
optional | LinkedIn rejects a `lead` that is not a valid URN. Fix: Send it as `urn:li:leadGenFormResponse:ID`. | vendor.linkedin-conversions-api.body.user.lead.emptyvendor.linkedin-conversions-api.body.user.lead.invalid |
docs |
user.externalIds[] |
optional | It is an advertiser-provided identifier for the converting user. LinkedIn documents at most one value in the list, and requires a standard identifier alongside the first send. Fix: Send `user.externalIds` as a one-item list, together with `userIds` or `userInfo` on the first match. | vendor.linkedin-conversions-api.body.user.externalIds[].empty |
docs |
user.userInfo.firstName |
optional | It is the contact first name in plain text. LinkedIn documents it with `lastName` for probabilistic matching. Fix: Send `user.userInfo.firstName` with `lastName`, or send the hashed pair instead. | vendor.linkedin-conversions-api.body.user.userInfo.firstName.empty |
docs |
user.userInfo.lastName |
optional | It is the contact last name in plain text. LinkedIn documents it with `firstName` for probabilistic matching. Fix: Send `user.userInfo.lastName` with `firstName`, or send the hashed pair instead. | vendor.linkedin-conversions-api.body.user.userInfo.lastName.empty |
docs |
user.userInfo.hashedFirstName |
optional | It is the SHA-256 hex digest of the first name. LinkedIn documents lowercase, no spaces or punctuation, UTF-8, then SHA-256. Fix: Send a 64-character lowercase hex digest in `user.userInfo.hashedFirstName` with `hashedLastName`. | vendor.linkedin-conversions-api.body.user.userInfo.hashedFirstName.emptyvendor.linkedin-conversions-api.body.user.userInfo.hashedFirstName.invalid |
docs |
user.userInfo.hashedLastName |
optional | It is the SHA-256 hex digest of the last name. LinkedIn documents lowercase, no spaces or punctuation, UTF-8, then SHA-256. Fix: Send a 64-character lowercase hex digest in `user.userInfo.hashedLastName` with `hashedFirstName`. | vendor.linkedin-conversions-api.body.user.userInfo.hashedLastName.emptyvendor.linkedin-conversions-api.body.user.userInfo.hashedLastName.invalid |
docs |
user.userInfo.companyName |
optional | It is the company name in plain text. LinkedIn documents it as an optional userInfo match field. Fix: Send `user.userInfo.companyName`, or drop the empty pair. | vendor.linkedin-conversions-api.body.user.userInfo.companyName.empty |
docs |
user.userInfo.title |
optional | It is the job title in plain text. LinkedIn documents it as an optional userInfo match field. Fix: Send `user.userInfo.title`, or drop the empty pair. | vendor.linkedin-conversions-api.body.user.userInfo.title.empty |
docs |
user.userInfo.countryCode |
optional | It is an ISO two-letter country or region code. LinkedIn documents `US` as the example. Fix: Send a two-letter code such as `US`. | vendor.linkedin-conversions-api.body.user.userInfo.countryCode.emptyvendor.linkedin-conversions-api.body.user.userInfo.countryCode.invalid |
docs |
conversionValue.currencyCode |
optional | It is the three-letter currency code of the conversion value. Fix: Use the ISO 4217 code, such as `USD`. | vendor.linkedin-conversions-api.body.conversionValue.currencyCode.emptyvendor.linkedin-conversions-api.body.conversionValue.currencyCode.invalid |
docs |
conversionValue.amount |
optional | LinkedIn documents the amount as a decimal string, as in `"50.0"`. Fix: Send the amount as a string holding a decimal number, without a currency symbol. | vendor.linkedin-conversions-api.body.conversionValue.amount.emptyvendor.linkedin-conversions-api.body.conversionValue.amount.invalid |
docs |
eventId |
optional | It identifies the event so repeated sends are not counted twice. | vendor.linkedin-conversions-api.body.eventId.empty |
docs |
body.value_needs_both_fields |
required | `conversionValue` carries an amount with no `currencyCode`. LinkedIn documents both fields together. Fix: Add `conversionValue.currencyCode` alongside the amount. | vendor.linkedin-conversions-api.body.value_needs_both_fields |
docs |
body.userinfo_first_needs_last |
required | `userInfo` has `firstName` without `lastName`. LinkedIn documents both names together for matching. Fix: Send `user.userInfo.lastName` with `firstName`, or send `hashedFirstName` and `hashedLastName` instead. | vendor.linkedin-conversions-api.body.userinfo_first_needs_last |
docs |
body.userinfo_last_needs_first |
required | `userInfo` has `lastName` without `firstName`. LinkedIn documents both names together for matching. Fix: Send `user.userInfo.firstName` with `lastName`, or send `hashedFirstName` and `hashedLastName` instead. | vendor.linkedin-conversions-api.body.userinfo_last_needs_first |
docs |
body.hashed_first_needs_last |
required | `userInfo` has `hashedFirstName` without `hashedLastName`. LinkedIn documents both hashed names together. Fix: Send `user.userInfo.hashedLastName` with `hashedFirstName`. | vendor.linkedin-conversions-api.body.hashed_first_needs_last |
docs |
body.hashed_last_needs_first |
required | `userInfo` has `hashedLastName` without `hashedFirstName`. LinkedIn documents both hashed names together. Fix: Send `user.userInfo.hashedFirstName` with `hashedLastName`. | vendor.linkedin-conversions-api.body.hashed_last_needs_first |
docs |
body.unhashed_email |
required | An identifier carries what looks like a raw email address. LinkedIn matches on `SHA256_EMAIL`, which is the SHA-256 digest rather than the address. Fix: Lowercase and trim the address, hash it with SHA-256, and send the hex digest with `idType` set to `SHA256_EMAIL`. | vendor.linkedin-conversions-api.body.unhashed_email |
docs |
Validate a payload
pixellint validate json @payload.json --rulepack vendor/linkedin-conversions-api
Try this failing payload in the playground. LinkedIn conversion with seconds instead of ms.
{"conversion":"urn:lla:llaPartnerConversion:1","conversionHappenedAt":1770000000,"user":{"userIds":[]}}
cargo install pixellint
·
npm install pixellint