Webhooks StarterTeam

Webhooks make every submission a trigger: score a lead in n8n before it's even stored, reject spam with a rule you control, draft the reply email, open the Jira ticket, ping the on-call channel. Snapi calls your endpoint (or n8n, Make, Zapier — anything with a URL) at two moments — before a record is saved, where you can modify or veto it, and after, where the downstream automation begins. Configure both per form.

Webhook types

Each form supports two webhook timing modes:

Configuring a webhook

  1. Optionally, open Settings → External APIs and add your n8n instance or any generic HTTP base URL as a reusable connection.
  2. Open the form in the builder and go to its Webhooks tab.
  3. For the Pre-Webhook and/or Post-Webhook, choose Manual URL or External API.
  4. Enter the full webhook URL (manual mode), or select a connection and enter the endpoint path to append to its base URL (external mode).
  5. Save.

Webhook URLs must use HTTPS and cannot point at private or local addresses.

i
Webhooks require a Starter or Team plan. They are disabled on the Free plan.

Payload format

Snapi sends a POST request (or the method you configure) with Content-Type: application/json. When a new record is submitted, the pre-event webhook receives the form and the submitted data:

{
  "entity": {
    "id": "ent_abc123xyz",
    "name": "Contact",
    "slug": "contact"
  },
  "data": {
    "name": "Alice Johnson",
    "email": "alice@example.com",
    "message": "Interested in a demo"
  }
}
i
Naming note: forms are called entities in the API and webhook payloads for backwards compatibility.

Post-event webhooks include an event field, which is one of:

Deleting a record does not fire a webhook.

Pre-event webhooks

For pre-event webhooks, your endpoint can modify the record before it is saved. Return a JSON object with a data key containing the modified fields:

// Enrich or validate — return modified data
{
  "data": {
    "name": "Alice Johnson",
    "email": "alice@example.com",
    "score": 82
  }
}

To reject the record, respond with a JSON body containing { "abort": true }. Snapi rejects the submission with a 409 Conflict error and includes your full response body in the error's details field.

When an existing record is updated, the pre-event payload is { "event": "record.updating", "record": { "id": "...", "data": { ... } }, "newData": { ... } } — respond the same way to modify or abort the update.

!
Timeout: Pre-event webhooks must respond within 10 seconds. If they time out or error, the record is saved as-is with the originally submitted data.

Securing your webhook endpoint

Snapi does not currently sign webhook payloads. To make sure requests hitting your endpoint really come from Snapi, include a secret token in the webhook URL and verify it on your server:

// Configure the webhook URL as:
//   https://your-server.com/webhook/snapi?token=YOUR_SECRET

// Express example — reject requests without the shared secret
app.post('/webhook/snapi', (req, res) => {
  if (req.query.token !== process.env.SNAPI_SHARED_SECRET) {
    return res.status(401).end();
  }
  // ...handle the payload
});
Always validate incoming requests before trusting webhook payloads — especially for pre-event webhooks that can modify data.

Retry policy

Webhooks are not retried:

If you need guaranteed processing, point the webhook at a highly available receiver (such as an n8n instance) and queue the work there.

n8n integration

Snapi has first-class support for n8n. In Settings → External APIs, add an n8n connection with your instance's base URL. When configuring a webhook on a form, select this connection and enter your workflow's webhook path — Snapi combines it with the base URL for you.

Use the Webhook trigger node in n8n with POST method. The body will contain the full Snapi payload.