Every programme has a sandbox: a second, invisible programme that mirrors the live one. A sticky_test_… key writes there and nowhere else.
What the sandbox mirrors
| Copied from live | Not copied |
|---|---|
| Earning rules, tiers, campaigns, redemption settings, expiry policy, branding | Members, orders, ledgers, balances |
| The programme's currency name and value | Webhook endpoints (register test ones separately) |
| Plan limits | Portal links and the hosted rewards page |
So an order.paid that earns 250 points in test will earn 250 in live, provided the rules have not changed since the last wipe.
Wiping it
Developers → Test mode → Wipe test data in the admin deletes every sandbox member, event, ledger entry and redemption, and re-copies the current live rules. Use it before a test run so you start from a known state — and after you change rules in live, so the sandbox matches again. It is one atomic operation; nothing partial is ever left behind.
Writing integration tests against it
- Keep a
sticky_test_…key in your CI secrets, never a live one. - Give each test run a unique customer namespace —
email: "ci-<run id>-<n>@example.test"— so parallel runs never collide and you never need to wipe mid-run. - Send the event, then poll
GET /v1/events/{id}untilstatusiscompletedrather than sleeping: processing is asynchronous. - Assert on
GET /v1/members/{id}balances, not on the202response. - A test endpoint receiving webhooks from the sandbox is the only reliable way to test your handler end to end;
POST /v1/webhook_endpoints/{id}/testsends awebhook.testdelivery on demand.
ID=$(curl -s https://stickytier.com/v1/events -H "Authorization: Bearer $TEST_KEY" \
-H "Content-Type: application/json" -d @order.json | jq -r .data.id)
until [ "$(curl -s https://stickytier.com/v1/events/$ID -H "Authorization: Bearer $TEST_KEY" | jq -r .data.status)" = completed ]; do sleep 0.5; doneThings that behave differently in test
POST /v1/members/{id}/portal-linksanswers409 reason: test_mode— there is no sandbox rewards page.- There is no sandbox rewards page, so member sign-in cannot be tested there; drive members through the API.
- Plan limits apply in the sandbox as they do in live.