[USER_ID] in your data: unfilled offerwall macros and what they break
An offerwall link or postback is built from macros: placeholders such as {userID} or [USER_ID] that are replaced with real values when the link is used. When one is not replaced, the placeholder itself arrives as the value. For a user id that means every person a publisher sends becomes the same account, and the fraud checks that compare accounts start comparing strangers.
Short answer
Search your account ids for values that are still a placeholder: anything in square or curly brackets or between percent signs, USER_ID_HERE, undefined, null or 0. Each one is a publisher or offerwall that did not fill its user id macro. Keep those accounts out of device and IP linking, never block them as one person, and ask the publisher to fix the macro name in its link.
- Placeholder accounts in one week
- 17 accounts on three offerwalls, among them [USER_ID], {clickid}, {user}, USER_ID_HERE and undefined.
- The busiest one
- One {clickid} account took 427 calls from many different people and was blocked as one user.
- Real users dragged in
- One [USER_ID] account shared a device with 90 real accounts and hardware with 318.
- Not only user ids
- One wall received 30 conversions whose transaction id was the text {transaction_id}.
What an unfilled macro does to your data
On an offerwall network, a publisher opens the wall with its user id in the link, and the network passes that id on to every click and postback. If the publisher's link says user=[USER_ID] and its own system never replaces it, the network receives the literal text [USER_ID] for every visitor. With a publisher prefix, as networks usually store ids, it becomes one account such as 1886:[USER_ID].
That account is not one person. It is everyone that publisher sent, on every device and every IP. In the week to 2 November 2026 we found 17 such accounts across three offerwalls:
| Account id as received | What it means | What it did |
|---|---|---|
| 1696:{clickid} | The publisher put a click id macro where the user id goes | 427 calls, blocked as one user |
| 1886:[USER_ID] | The macro name was never replaced | A device shared with 90 real accounts |
| 1093:USER_ID_HERE | A template value left in the link | 88 stored links to devices and networks |
| 1117:undefined | A script read a variable that did not exist | Tied to 152 accounts by network |
What it breaks in fraud checks
Fraud checks on a rewards site compare accounts: two accounts on one device, one payout address or one IP are worth a look. A placeholder account touches every device its publisher's users bring, so it ties strangers together. A real user who once came through that publisher now shares a device with "another account", and an honest account can be held because of a link to an account that does not exist.
- Shared-device and shared-IP checks count the placeholder as one more account on the user's phone.
- Fraud rings grow around it: one placeholder can sit at the centre of a group of unrelated users.
- Blocking it blocks everyone the publisher sends, honest users included, without anyone noticing why.
- Reports count one active user where there were hundreds, and offer speed or earnings checks see one account doing the work of a crowd.
The same happens with other fields. An unfilled transaction id such as {transaction_id} makes every conversion look like a duplicate of the first one, and an unfilled offer id groups every offer under one name.
How to find them in your data
Placeholders have a recognisable shape. Look for ids, after any publisher prefix, that are a word in square or curly brackets or between percent signs, the words USER_ID or SUBID on their own, or the values a script produces when a variable is missing: undefined, null, none, 0.
-- Account ids that are still a macro, with how many events each received
SELECT external_id, COUNT(*) AS events
FROM accounts a JOIN events e ON e.account_id = a.id
WHERE SUBSTRING_INDEX(external_id, ':', -1) REGEXP '^(\\[[A-Za-z_]+\\]|\\{[A-Za-z_]+\\}|%[A-Za-z_]+%)$'
OR LOWER(SUBSTRING_INDEX(external_id, ':', -1)) IN ('user_id', 'user_id_here', 'subid', 'undefined', 'null', 'none', '0')
GROUP BY external_id
ORDER BY events DESC;Keep the check strict. An id like [user_id]44 is a publisher that left a macro in front of a real number: those are distinct users with an ugly prefix, not one shared account. A username such as Ro[bert is a typo, not a macro.
Before a link or postback goes live, the free postback checker catches most of these: paste the URL and it flags every macro Lootably, AdGate Media, CPX Research or BitLabs would send back as text.
Why it happens
Every offerwall names its macros differently. The user is {userID} on Lootably, {s1} on AdGate Media, {user_id} on CPX Research and [%USER:UID%] on BitLabs (our postback parameters guide lists them side by side). A publisher who copies a link from one network to another, or from a template, keeps a macro the new network does not know, and it arrives unreplaced.
- The macro name is from another offerwall, or misspelt: {userid} where the network expects {userID}.
- The link template was copied with its example value, such as USER_ID_HERE.
- The publisher's own page builds the link with JavaScript and the variable is empty: undefined or null.
- The braces were URL-encoded on the way (%7BuserID%7D), so the network no longer recognises the macro.
Fixing it
The fix is on the side that built the link. On an offerwall network that is usually one publisher's integration: the account id carries its prefix, so you know which publisher to write to. Send them the exact value you receive and the macro your network expects in that position.
- Open the publisher's wall link in a browser with a test user and check the id that reaches your server.
- Compare the macro name with your network's documentation, letter case included.
- Make sure the link is not URL-encoded twice by the publisher's site builder.
- After the fix, the placeholder account stops receiving events; new users appear under their real ids.
How CashoutGuard handles it
Since 2 November 2026 CashoutGuard recognises an account id that is an unfilled macro. Its calls are still scored on their own evidence, a VPN is still a VPN, but the account is kept apart like an unverified one: it writes no device or IP links, builds no reputation, never blocks as one person and never counts against your real users. Links such accounts made before that day are ignored by scoring, the account page and fraud rings.
The value is shown on the Install page and in the weekly report, with how many calls it arrived in, so the publisher can be asked to fix it. Unfilled offer, transaction and click ids are dropped from those fields in the same way and kept with the event as received.