vendor/singular · vendor documented
Singular EVENT is form fields, not JSON
v1 and v2 /evt take query or form parameters. p is a documented platform string, case-sensitive. n is 1 to 32 ASCII characters. Exactly one of ip or use_ip.
Platform spelling is case-sensitive
Singular documents iOS, Android, Web, and the rest with that capitalization. ios is not iOS. The call can still return 200.
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 |
|---|---|---|---|---|
a |
required | It is the Singular SDK Key, not the Reporting API Key, and every EVENT request requires it. Fix: Send the SDK Key as `a`. | vendor.singular.param.a.missingvendor.singular.param.a.empty |
docs |
p |
required | It is the platform, case-sensitive. Singular documents the values Android, iOS, Web, PC, Xbox, Playstation, Nintendo, MetaQuest, and CTV. Fix: Set `p` to the documented platform spelling, such as `iOS`. | vendor.singular.param.p.missingvendor.singular.param.p.emptyvendor.singular.param.p.invalid |
docs |
i |
required | It is the app identifier, case-sensitive, and every EVENT request requires it. Fix: Send the app ID as `i`. | vendor.singular.param.i.missingvendor.singular.param.i.empty |
docs |
n |
required | It is the event name, at most 32 ASCII characters, and every EVENT request requires it. Fix: Set `n` to an event name of 32 ASCII characters or fewer. | vendor.singular.param.n.missingvendor.singular.param.n.emptyvendor.singular.param.n.invalid |
docs |
ip |
optional | It is the public device IP. Singular requires `ip` or `use_ip`, and they are mutually exclusive. Fix: Send the device IPv4 as `ip`, or send `use_ip` instead. | vendor.singular.param.ip.empty |
docs |
use_ip |
optional | It tells Singular to use the request IP. Mutually exclusive with `ip`. | vendor.singular.param.use_ip.empty |
docs |
sdid |
optional | It is the Singular device ID, a UUIDv4. V2 requires it. New accounts as of 15 July 2026 must use V2. Fix: On `/api/v2/evt`, send `sdid` as a UUIDv4. | vendor.singular.param.sdid.emptyvendor.singular.param.sdid.invalid |
docs |
cur |
optional | It is an ISO 4217 currency code, uppercase, used with `amt` on revenue events. Fix: Send `cur` as `USD` together with `amt`. | vendor.singular.param.cur.emptyvendor.singular.param.cur.invalid |
docs |
amt |
optional | It is the revenue amount. Sending it makes the call a revenue event. | vendor.singular.param.amt.empty |
docs |
ip_required |
required | The request has neither `ip` nor `use_ip`. Singular requires one of them on every EVENT. Fix: Send the device IP as `ip`, or send `use_ip` to use the request address. | vendor.singular.ip_required |
docs |
ip_ambiguous |
required | The request sends both `ip` and `use_ip`. Singular documents them as mutually exclusive. Fix: Send only `ip` or only `use_ip`. | vendor.singular.ip_ambiguous |
docs |
hashed_plaintext_field |
required | `ip` looks like a SHA-256 digest, but Singular documents it as the public device IP, unhashed. Fix: Send the raw IP address. | vendor.singular.hashed_plaintext_field |
docs |
Validate a payload
pixellint validate url "$ARTIFACT" --rulepack vendor/singular
Or paste it into the playground. Same engine, in the browser, nothing sent anywhere.
cargo install pixellint
·
npm install pixellint