Why separation matters
Isolation prevents sandbox traffic from polluting production usage, logs, billing signals, campaign audiences, webhook consumers, and audit reviews. A customer can test auth, webhooks, campaign flows, and loyalty logic without accidentally affecting production members.
Recommended setup
Use dedicated credentials, redirect URIs, webhook endpoints, custom-domain bindings, and growth workflow settings per environment.
| Environment | Purpose | Typical behavior |
|---|---|---|
| Local integration | App callback and UI validation | Uses local redirect URIs and test credentials |
| Sandbox | Integration and QA | Can exercise auth, webhooks, campaigns, loyalty, and notifications without production usage |
| Production | Real customer traffic | Drives billing, enforcement, audit, and operational reporting |
Implementation steps
1) Create environment-specific applications
OIDC/OAuth2 client IDs, client secrets, and redirect URIs should be environment-specific. Do not reuse production credentials in local or sandbox builds.
2) Separate event consumers
Webhook endpoints should point to environment-specific receivers. Sandbox webhook traffic should never hit the production fulfillment or campaign system.
3) Separate growth experiments
Campaign, loyalty, notification, and segment tests should run against sandbox audiences. Production audiences should be created from production Project membership and lifecycle context only.
4) Keep observability labels explicit
Every log, audit event, webhook delivery, and analytics row should carry environment context when it can cross support or reporting tools.
Security and operational notes
- Production traffic drives billing and enforcement.
- Sandbox audit logs should be visibly separate from production audit logs.
- Custom domains should preserve issuer and host separation.
- Rate limit and plan-limit behavior should be tested before launch.
Operational tips
Document the promotion flow from local to sandbox to production. Keep Workspace and Project identity stable where needed, but never rely on a synthetic default environment when a request already identifies the target.
Related docs
- OIDC Integration:
/docs/quickstart/oidc - Webhooks Integration:
/docs/quickstart/webhooks - Campaigns:
/docs/growth/campaigns - Plan Limits:
/docs/pricing/limits