Test mode#
Add "test": true to any write call and it becomes test data. Leave it out and it is real.
That is the whole feature. There is no separate key, no sandbox host, no second base URL to get wrong when you go live — the same endpoints, the same key, one flag.
What test data does and does not do#
| Test data | Real data | |
|---|---|---|
| Stored | yes, separately | yes |
| Visible in the dashboard | only with the Test mode switch on | always |
| Counts in trends, funnels, cohorts | yes, within test mode | yes |
| Advances a quest | never | yes |
| Grants a reward to a player | never | yes |
| Attributed when a player links | no | yes |
| Appears in the tag/trait pickers | no | yes |
| Kept for | 30 days by default | 180 days by default |
The two datasets never mix, in either direction. A studio watching its live dashboard cannot see your test traffic, and your test numbers are not diluted by real players.
Quests are the reason this exists
You can send ten thousand killed_boss events with test: true, watch them arrive, build
the chart, get the event name wrong, fix it, and send ten thousand more — and not one real
player will have gained a single quest completion or reward. Without a test mode the only way
to try the integration is to do it for real.
Where the flag goes#
{
"test": true,
"default": { "partner_user_id": "A1B2C3" },
"events": [
{ "id": "9a0e…", "name": "killed_boss" },
{ "id": "b1c2…", "name": "finished_chapter", "test": false }
]
}
Batch level sets it for the whole call. default carries it like any other default. An
individual event may override it — so one call can carry both, which is useful when a test
harness runs beside live traffic and you do not want to split your outbox.
It is accepted on every write endpoint: /events/track, /events/import,
/events/time/start, /events/time/stop, /events/identify, /players/update.
Reading test data back#
Every read endpoint takes the same flag: /events/trends, /events/counts, /events/user,
/events/users, /events/leaderboard, /events/list, /events/funnel, /players/get,
/players/search.
{ "names": ["killed_boss"], "period": "month", "test": true }
Omit it and you get live data — which means an integration written before test mode existed keeps returning exactly what it always did.
In the Gamearly dashboard the studio flips one Test mode switch and every chart, funnel, explorer and cohort on the page switches with it.
Suggested workflow#
- Integrate with
"test": trueeverywhere. Send real-looking traffic. - Open the dashboard, switch to Test mode, and check the events, the labels, the funnel and the cohorts all say what you expected.
- Wipe the test data so you start clean.
- Remove the flag, or set it from your build configuration, and ship.
Because the flag is the only difference, step 4 cannot change behaviour in any other way.