Developer portal
Sandbox tenants
Every paid plan comes with one sandbox tenant (Enterprise: unlimited). Safe to break, reset on demand.
Create a sandbox
- Sign in to your production tenant.
- Open
https://app.qehsethos.com/settings/sandbox. - Click "Create sandbox". Pick a slug (defaults to
<tenant>-sb). - Choose "Copy configuration from production" to seed modules, users, branding.
- Within ~60 seconds the sandbox URL is ready —
https://app.qehsethos.com/s/<slug>.
What is isolated
- Database namespace, zero overlap with production data.
- Background workers, separate queue names and retry policies.
- API keys, fresh set, never valid in production.
- Webhooks, disabled by default; switch on per-sandbox to test your receivers.
- Billing, sandboxes do not accrue charges or count against seat limits.
Reset, clone, destroy
- Reset, wipe records and re-seed from the last snapshot. Takes under a minute.
- Clone, point-in-time clone from production, useful for reproducing a customer issue.
- Destroy, permanent. Audit log entry records who destroyed which sandbox.
OAuth 2.0 sandbox credentials
Build and test OAuth integrations without touching production. Sandbox OAuth clients use a sandbox_ prefix so the server short-circuits validation without DB lookups, and tokens are never accepted by production API routes.
- Open your sandbox tenant at
https://app.qehsethos.com/s/<slug>/settings/oauth-apps. - Click "Create OAuth app". The resulting client ID starts with
sandbox_. - Use standard OAuth 2.0 flows (authorization code + PKCE, or client credentials) against the sandbox base URL:
https://app.qehsethos.com/s/<slug>. - Sandbox tokens carry
x_sandbox: truein the token response, branch on this in your integration tests to assert you are running in safe mode. - Swap the base URL and replace credentials with production values when you are ready to ship. No other code change required.
POST https://app.qehsethos.com/s/<slug>/api/v1/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=sandbox_a1b2c3d4e5f6
&client_secret=sandbox_secret_...
&scope=records:read
200 OK
{
"access_token": "sandbox_sandbox_a1b2..._<random>",
"token_type": "bearer",
"expires_in": 3600,
"scope": "records:read",
"x_sandbox": true
}