Sandbox
Every project has two isolated data planes: live and sandbox. Sandbox is a full copy of the product surface — tickets, emails, templates, articles, webhooks, API keys — where nothing ever reaches a real customer. Use it to build and test your integration before touching production data.
The credential is the environment
There is no environment parameter anywhere in the API. Which data plane you touch is decided entirely by the API key you authenticate with:
sk_live_…keys read and write live data only.sk_sandbox_…keys read and write sandbox data only — even when given the id of a live resource, they cannot see it.
Create a sandbox key by switching the dashboard to Sandbox mode (the toggle in the top bar) and creating a key on the API Keys page — keys inherit the mode you are in.
import { HelmdeskClient } from '@helmdesk/sdk'
// Point your staging/dev environment at sandbox — nothing else changes.
const helmdesk = new HelmdeskClient({
apiKey: process.env.HELMDESK_SANDBOX_API_KEY!, // sk_sandbox_...
})
// Works exactly like live, but the ticket lands in the sandbox plane.
await helmdesk.tickets.create({
subject: 'Test ticket',
body: 'Created from staging',
customerEmail: 'test@example.com',
})Emails are captured, never delivered
Sandbox email sends render fully — real template, real layout, real variables — but stop short of any provider. They appear in Email Logs with status sandboxed (Captured), where you can open the rendered HTML exactly as a customer would have received it. No email configuration or provider credentials are needed in sandbox, and captured sends never count against your plan quota.
Sandbox tickets behave the same way: status changes and staff replies never email the customer address on the ticket.
Logs in sandbox
Log events shipped with an sk_sandbox_… key land in the sandbox plane. They are quota-exempt (they never count against your monthly log event limit), retained for a fixed 3 days on every plan, and the Log Watch agent ignores them — sandbox errors never page anyone. Use sandbox keys to verify your log shipping integration without polluting real error groups.
The dashboard toggle
The Live/Sandbox toggle in the dashboard's top bar switches every page — tickets, email logs, templates, articles, webhooks, canned responses, suppressions, activity, analytics — to the selected plane. In Sandbox mode an amber banner reminds you where you are, and anything you create is sandbox content. Public portals (your knowledge base and support pages) always serve live content, and AI agents only run on live data.
Promote and pull
Content moves between planes deliberately, never automatically:
- Promote a template — publishes the sandbox template as a new live version behind the same key, so your production sends pick it up atomically.
- Promote an article — copies it to live (new slugs arrive as drafts; existing slugs update in place and keep their publish state).
- Pull from live — copies your live knowledge base or a live template into sandbox so you can iterate against real content.
Webhooks and the widget
Webhook endpoints are per-environment: endpoints created in Sandbox mode only receive sandbox events, so your staging receiver never sees production traffic. The embeddable widget's identity secret is split the same way — hd_widget_live_… and hd_widget_sandbox_…— and the secret that signed a user's identity hash decides which plane's conversations the widget shows.
What sandbox never does
Sandbox data never emails a real customer, never appears on your public portal, never triggers AI agents, never fires live webhooks, and never counts toward plan limits or analytics. It is also never purged automatically — your test data stays until you delete it.