Sandbox and test mode
Send test emails and sign watermarked documents without billing.
Updated
On this page
Test mode exists so you can build and run a full integration — send, sign, complete, webhook, download — without usage charges. Recipients receive real emails explicitly marked as test documents. Use addresses you control.
How a request becomes a test request
Two ways, and they agree:
- The key. Any request with an
sk_test_key is a test request, and nothing the caller sends can turn that off. - The flag.
test_mode: trueon a create makes that document a test document even with a live key.
There is nothing else to configure. If your code has an if (env === 'staging') branch deciding whether to set a flag, delete it and use a sandbox key instead.
Both routes need the plan entitlement that sandbox keys come with: Light and above. On Free, test_mode: true is refused.
What test mode does
| Test mode | |
|---|---|
| Billing | Never counted. A test document never touches the monthly counters and can never be refused for being over them. |
Delivered to recipients with “This is a test document” in the message and [TEST] in the subject. |
|
| Signing | Works normally. Open the signing URL and sign. |
| Artifacts | Every page is watermarked “Not legally binding – test mode,” including the completed PDF. |
| Webhooks | Delivered only to endpoints with include_test_mode: true. |
| Rate limit | The same buckets and the same numbers as live keys: 120/min general, 10/min for POST, PUT and PATCH, 120/min for POST /files. |
| Document limits | Unlimited. |
Real delivery in test mode
Invitations, reminders, passcodes, and completed copies go to the intended recipients. Test emails include an explicit notice, and test documents are not legally binding. Invalid recipient addresses can bounce just as they do in live mode.
What a sandbox key cannot reach
A sandbox key is not merely filtered to test rows; it is confined to a list of route families, and everything else answers 403 sandbox_key_not_allowed. Documents, templates, files, bulk sends, webhook endpoint configuration, the event catalog, its own API keys and /me are allowed. The address book, the suppression list, webhook delivery logs and replay, the debug inbox, data exports, members, billing, workspace settings and OAuth applications are not — they hold live data with no test-mode column to filter on.
Webhook endpoints are allowed but partitioned: a sandbox key sees and can change only the endpoints a sandbox key registered, so the production callback is a 404 to a staging credential. Delivery is not partitioned — an endpoint a sandbox key registered still receives the live events it subscribed to.
A sandbox key also creates only sandbox keys. Asking it for a live key is a 422 on mode, and a live key reached by id is a 404.
Sending test events
Every webhook endpoint has a “send test event” action for each event type: POST /webhook_endpoints/{id}/ping with an event_type sends a realistic sample of that event, synchronously, and never counts towards the endpoint’s health. Creating an endpoint with verify: true sends a plain ping first and activates the endpoint only if your receiver answers 2xx. Both let you exercise a receiver before there is a real document to exercise it with.
Moving to live
- Create a live key — from the app or with another live key, since a sandbox key cannot mint one — and put it wherever your sandbox key was.
- Register your production webhook endpoint with the live key. A sandbox key’s endpoints stay visible only to sandbox keys.
- Check
include_test_modeon your webhook endpoints — most production endpoints should have it off. - Nothing else changes. The paths, bodies, statuses, and event names are identical.