Skip to content

Sandbox mode

Validate and store submissions without sending any email or webhook.

Sandbox submissions are validated and stored like any other, but no email or webhook is sent. You see what would have been sent instead.

Sandbox submissions run against the form’s draft when it has one, so they are also how you test changes before you publish them. A form that has never been published accepts sandbox submissions only.

Four ways in

How Scope
X-Quickforms-Sandbox: qf_sandbox_... header or a _sandbox field One submission. The key must match the form.
"mode": "sandbox" Every submission to that form.
QUICKFORMS_FORCE_SANDBOX=true Every submission in the environment. Useful for local and preview environments.
Test submissions Always sandbox: the dashboard test button, the API test-submissions endpoint and the MCP send-test-submission tool.

Rotate a form’s sandbox key with Rotate beside it under Share, then API or endpoint, on the form page, POST /api/v1/forms/{form}/sandbox-key/rotate, or the rotate-sandbox-key MCP tool. The old key stops working straight away.

What you get back

Deliveries are created with status simulated and hold the full payload that would have been sent: the email with its recipients and subject, or the webhook request including the Quickforms-Signature header computed with your real secret. Use that to test your verification code, with the timestamp check relaxed.

curl -X POST https://YOUR-QUICKFORMS-HOST/api/v1/forms/FORM_ID/test-submissions \
  -H "Authorization: Bearer $QUICKFORMS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"data": {"name": "Ada Lovelace", "email": "ada@example.com"}}'
{
  "data": {
    "id": "01jca9qf3tz5b8m2k7w4r6x0hn",
    "form_id": "01jc8xk2m5t9qw3e7r4y6u8v0p",
    "sandbox": true,
    "spam": false,
    "failed_rules": false,
    "held": false,
    "classification": null,
    "reviewed_at": null,
    "confirmation_status": null,
    "confirmed_at": null,
    "source": "api",
    "data": { "name": "Ada Lovelace", "email": "ada@example.com" },
    "meta": [],
    "deliveries": [
      {
        "id": "01jca9qf4b...",
        "channel": "webhook",
        "status": "simulated",
        "target": "https://example.com/hooks",
        "attempts_count": 0,
        "payload": {
          "method": "POST",
          "headers": {
            "Content-Type": "application/json",
            "User-Agent": "quickforms-webhooks/1.0",
            "Quickforms-Event": "submission.created",
            "Quickforms-Submission": "01jca9qf3tz5b8m2k7w4r6x0hn",
            "Quickforms-Signature": "t=1762424640,v1=4b1e0c7d9a..."
          },
          "body": "{\"id\":\"evt_01jca9qf3tz5b8m2k7w4r6x0hn\",\"type\":\"submission.created\",...}"
        }
      }
    ],
    "created_at": "2026-11-06T10:24:00.000000Z"
  }
}

List only sandbox or only live traffic with ?sandbox=true or ?sandbox=false on the submissions endpoint.

Double opt-in

On a form with double opt-in, a sandbox submission gets a simulated confirmation email and nothing else at first. Its payload holds the confirmation link in button.url. Open that link to simulate the person confirming: the submission becomes confirmed and its notification email, autoresponder and webhook are created as simulated deliveries.

Sandbox submit response (illustrative)json
{
  "message": "Thanks! Your submission has been received.",
  "id": "01jca9qf3tz5b8m2k7w4r6x0hn",
  "sandbox": true,
  "spam": { "flagged": false, "spam": false, "failed_rules": false, "reasons": [] },
  "deliveries": [
    { "channel": "confirmation", "status": "simulated", "target": "ada@example.com" }
  ]
}

The full payload, including button.url, is on the delivery in the REST API and the get-submission MCP tool, until retention clears it (30 days by default).

Testing the spam filter

Sandbox submissions skip the spam filter, so tests don’t use your classifier budget and aren’t flagged. Sandbox callers of the submit endpoint still get a spam object in the response, with flagged, spam, failed_rules and reasons, but it reports that nothing was flagged. The cheap filters, country and disposable email, still run.

Type to search…

↑↓ navigate↵ selectEsc close