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. Singular documents a number used with `cur`. Sending it makes the call a revenue event. Fix: Send `amt` as a number such as `2.51`, together with `cur`. | vendor.singular.param.amt.emptyvendor.singular.param.amt.invalid |
docs |
idfa |
optional | It is the iOS Identifier for Advertisers. Singular documents a UUIDv4 on EVENT V1. Omit it when unavailable. Never send an empty string. Fix: Send `idfa` as a UUID, or omit the pair. | vendor.singular.param.idfa.emptyvendor.singular.param.idfa.invalid |
docs |
idfv |
optional | It is the iOS Identifier for Vendor. Singular documents a UUIDv4, required on iOS V1 regardless of ATT. Fix: Send `idfv` as a UUID on iOS V1. | vendor.singular.param.idfv.emptyvendor.singular.param.idfv.invalid |
docs |
aifa |
optional | It is the Google advertising ID. Singular documents a UUIDv4 on Google Play V1. Fix: Send `aifa` as a UUID, or omit the pair off Google Play. | vendor.singular.param.aifa.emptyvendor.singular.param.aifa.invalid |
docs |
asid |
optional | It is the Android App Set ID. Singular documents a UUIDv4 on Google Play V1. Fix: Send `asid` as a UUID on Google Play V1. | vendor.singular.param.asid.emptyvendor.singular.param.asid.invalid |
docs |
amid |
optional | It is the Amazon advertising ID. Singular documents a UUIDv4 for Fire devices. Fix: Send `amid` as a UUID on Amazon devices, or omit the pair. | vendor.singular.param.amid.emptyvendor.singular.param.amid.invalid |
docs |
oaid |
optional | It is the Open Advertising Identifier on Chinese OEM Android. Singular documents a UUID, but the published example is not a valid UUID, so only emptiness is checked. Fix: Send `oaid` when the device has no Google Play, or omit the pair. | vendor.singular.param.oaid.empty |
docs |
andi |
optional | It is the Android ID. Singular documents it only when no other identifier is available and the app is not on Google Play. Fix: Send `andi` only off Google Play when AIFA and ASID are unavailable. | vendor.singular.param.andi.empty |
docs |
ve |
optional | It is the OS version at event time. Singular documents it on EVENT requests. Fix: Send `ve` as the OS version, such as `9.2`. | vendor.singular.param.ve.empty |
docs |
ua |
optional | It is the device user agent. Singular documents it URL-encoded and unhashed. Fix: Send the raw user agent as `ua`. | vendor.singular.param.ua.empty |
docs |
lc |
optional | It is the IETF locale as `ll_CC`. Singular documents the plain form, with no Unicode extensions. Fix: Send `lc` as `en_US`. | vendor.singular.param.lc.emptyvendor.singular.param.lc.invalid |
docs |
country |
optional | It is an ISO 3166-1 alpha-2 country code. Singular documents it when `use_ip=true` or no IP is available. Fix: Send a two-letter code such as `US`. | vendor.singular.param.country.emptyvendor.singular.param.country.invalid |
docs |
c |
optional | It is the network connection type. Singular documents `wifi` or `carrier`. Fix: Send `c` as `wifi` or `carrier`. | vendor.singular.param.c.emptyvendor.singular.param.c.invalid |
docs |
att_authorization_status |
optional | It is the iOS ATT status. Singular documents 0 undetermined, 1 restricted, 2 denied, 3 authorized. Fix: Send `0`, `1`, `2`, or `3`. Pass `0` when ATT is not implemented. | vendor.singular.param.att_authorization_status.emptyvendor.singular.param.att_authorization_status.invalid |
docs |
utime |
optional | It is the event time as a 10-digit Unix timestamp. Fix: Send `utime` as 10-digit Unix seconds, such as `1483228800`. | vendor.singular.param.utime.emptyvendor.singular.param.utime.invalid |
docs |
umilisec |
optional | It is the event time as a 13-digit Unix timestamp in milliseconds. Fix: Send `umilisec` as 13-digit Unix milliseconds, such as `1483228800000`. | vendor.singular.param.umilisec.emptyvendor.singular.param.umilisec.invalid |
docs |
is_revenue_event |
optional | It marks a revenue event. Singular still treats the event as revenue when `amt` is present. Fix: Send `true` or `false`. Omit `amt` if the event is not revenue. | vendor.singular.param.is_revenue_event.emptyvendor.singular.param.is_revenue_event.invalid |
docs |
ma |
optional | It is the device make. Singular documents it together with `mo`. Fix: Send `ma` and `mo` together, such as `Apple` and `iPhone 4S`. | vendor.singular.param.ma.empty |
docs |
mo |
optional | It is the device model. Singular documents it together with `ma`. Fix: Send `ma` and `mo` together. | vendor.singular.param.mo.empty |
docs |
e |
optional | It is a JSON object of custom event attributes, URL-encoded. Singular documents a JSON object. Fix: Send a JSON object such as `{"sng_attr_content_id":5581}`, URL-encoded. | vendor.singular.param.e.emptyvendor.singular.param.e.invalid |
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 | This field looks like a SHA-256 digest, but Singular documents `ip` and `ua` as unhashed device values. Fix: Send the raw IP address or user agent. | vendor.singular.hashed_plaintext_field |
docs |
device_id_required |
required | The request has no device identifier. EVENT V2 requires `sdid`. V1 requires at least one of `idfa`, `idfv`, `aifa`, `asid`, `amid`, `oaid`, or `andi`. Fix: On `/api/v2/evt` send `sdid`. On `/api/v1/evt` send a platform advertising ID. | vendor.singular.device_id_required |
docs |
amt_requires_currency |
required | The event sends `amt` without `cur`. Singular documents the ISO 4217 code together with the amount. Fix: Add `cur` as a three-letter uppercase code such as `USD`. | vendor.singular.amt_requires_currency |
docs |
make_requires_model |
required | The request sends `ma` without `mo`. Singular documents make and model together. Fix: Send `mo` with `ma`. | vendor.singular.make_requires_model |
docs |
model_requires_make |
required | The request sends `mo` without `ma`. Singular documents make and model together. Fix: Send `ma` with `mo`. | vendor.singular.model_requires_make |
docs |
use_ip_requires_country |
required | `use_ip=true` is missing `country`. Singular documents a two-letter country code when it cannot geolocate from `ip`. Fix: Send `country` as a two-letter code such as `US`. | vendor.singular.use_ip_requires_country |
docs |
Validate a payload
pixellint validate url "$ARTIFACT" --rulepack vendor/singular
Try this failing payload in the playground. Singular EVENT missing a.
https://s2s.singular.net/api/v1/evt?n=purchase
cargo install pixellint
·
npm install pixellint