> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useorbitcrm.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Send form submission data to any URL in real-time. Perfect for custom backends, internal tools, or services without native integrations.

> [!NOTE]
>
> Webhooks require the **Pro** plan or higher.

## What are Webhooks?

Webhooks are HTTP callbacks that send data to a URL you specify when events occur—such as a form submission. OrbitForms webhooks let you:

* **Real-time** — Data is sent immediately when a submission is received
* **Flexible** — Works with any service that accepts HTTP POST requests
* **Secure** — Verify requests using HMAC-SHA256 signatures
* **Retries** — Automatic retries if your endpoint fails

## Setting Up a Webhook

Webhooks are configured per team and fire on form submissions. Because the payload contains your form's field names, create your form first so you know exactly which keys to expect.

**1. Create and publish your form**

Build your form in the editor and publish it. The keys in the webhook payload's `submission_data` object are your form's field names — so decide on final field names (e.g. `email`, `first_name`, `company`) before wiring up your endpoint, and make sure your endpoint reads the same names.

**2. Open the Webhooks integration**

In the dashboard, go to **Integrations** and open the **Webhooks** card.

**3. Click Add Webhook**

Click **Add Webhook** to open the configuration dialog.

**4. Enter your endpoint URL**

Enter the full endpoint URL (e.g., `https://your-server.com/webhook`). HTTPS is required, the URL can't contain credentials, and private/internal addresses are blocked.

**5. Select events and scope**

Choose which events to send: form submissions, contacts, companies, deals, tasks, meetings and calls (the [events reference](https://docs.useorbitcrm.ai/developers/webhooks/events.md) describes each payload). Submission events can be limited to one specific form; any other event makes the webhook **Global**, since contacts, deals and calls belong to the workspace, not a form.

**6. Set a signing secret**

Leave the signing secret blank to auto-generate one, or paste your own. The secret is shown **only once** when the webhook is created — copy it and store it somewhere safe.

**7. Configure optional settings**

Add custom headers (names must start with an approved prefix such as `X-Custom-`), and adjust the advanced delivery settings if needed: retry count (0–5, default 3), retry delay (10–300 seconds, default 60), and timeout (5–60 seconds, default 30).

**8. Save and test**

Click **Create Webhook**, then submit a test submission through your form. You can inspect every delivery attempt — status code, response body, and failures — in the **Delivery Logs** section of the same page.

## Payload Format

Each webhook request is sent as a JSON payload with the following structure:

```json theme={null}
{
  "event": "submission.created",
  "timestamp": "2025-03-07T12:00:00.000Z",
  "data": {
    "form_id": "a1b2c3d4-...",
    "form_title": "Contact Form",
    "form_slug": "contact-form",
    "submission_id": "e5f6g7h8-...",
    "submission_data": {
      "email": "user@example.com",
      "name": "Jane Doe",
      "message": "Hello, I'd like to learn more."
    },
    "submitted_at": "2025-03-07T12:00:00.000Z",
    "metadata": {
      "referrer": "https://google.com",
      "user_agent": "Mozilla/5.0 ...",
      "device_type": "desktop",
      "country": "US",
      "utm_source": "newsletter",
      "utm_medium": "email",
      "utm_campaign": "spring-launch"
    }
  }
}
```

| Field | Description |
| - | - |
| `event` | The event type (e.g., `submission.created`) |
| `timestamp` | ISO 8601 timestamp of delivery |
| `data.form_id` | Unique form identifier |
| `data.form_title` | Display name of the form |
| `data.form_slug` | URL slug of the form |
| `data.submission_id` | Unique submission identifier |
| `data.submission_data` | Form field values, keyed by the field names you set in the form builder |
| `data.submitted_at` | When the submission was received |
| `data.metadata` | Optional context: referrer, user agent, device type, country, and UTM parameters |

## Security & Verification

OrbitForms signs each webhook request with HMAC-SHA256. Verify the signature before processing.

### Signature Header

The signature is sent in the `X-Orbit-Signature` header in the format `sha256=<hex digest>`. Each request also includes `X-Orbit-Event` (the event type), `X-Orbit-Delivery-ID` (a unique delivery ID), and `X-Orbit-Timestamp`.

### Verification Steps

1. **Get the raw request body** — Use the raw bytes as received (do not parse and re-serialize JSON)
2. **Compute HMAC-SHA256** — Using your webhook signing secret as the key
3. **Compare with the header** — Prefix your computed hex digest with `sha256=` and compare it to the header value using a timing-safe comparison
4. **Reject if mismatched** — Do not process requests with invalid signatures

Example (Node.js):

```javascript theme={null}
const crypto = require('crypto');

function verifyWebhook(rawBody, signatureHeader, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody, 'utf8')
    .digest('hex');
  const a = Buffer.from(signatureHeader);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```

## Error Handling & Retries

### Success Response

Your endpoint should return a **2xx** status code (e.g., 200, 201, 204) to indicate successful processing.

### Automatic Retries

If your endpoint returns a 5xx status, a 429, or times out, OrbitForms retries with exponential backoff and jitter — up to your configured retry count (default **3 retries**). The `Retry-After` header is honored for 429 responses. Other 4xx errors (like 400 or 404) are treated as permanent and are not retried.

### Timeout

Requests time out after **30 seconds** by default (configurable from 5 to 60 seconds). Ensure your endpoint responds within this window.

## Next Steps

> [card] [Integrations](https://docs.useorbitcrm.ai/guides/integrations)
>
> Connect to CRMs, Slack, and more

> [card] [API Reference](https://docs.useorbitcrm.ai/guides/api-reference.md)
>
> Programmatic access to forms and submissions


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.