> ## 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 data to any endpoint

> [!NOTE]
>
> Webhooks are a **Pro** plan feature.

## Start Here

Webhooks let you send form submission data to any URL in real-time. This is perfect for building custom integrations, connecting to internal systems, or triggering complex automation workflows. This guide shows you how to set up and secure webhooks.

### Overview

Here's the idea in plain terms:

* You provide a **webhook URL** where OrbitForms should send data.
* When someone submits a form, Orbit sends a **POST request** with the submission data.
* Your server receives the data and processes it however you need.
* We include authentication headers so you can verify requests are from Orbit.

### Why This Matters

Webhooks give you complete flexibility. Connect to any backend, internal tool, or custom service — even systems we don't have native integrations for. They're perfect for developers who need full control over their data flow.

***

## Step 1: Create Your Webhook Endpoint

First, set up a URL on your server that can receive POST requests.

**What to do:**

* Create an endpoint on your server that accepts POST requests.
* The endpoint must be publicly accessible (not localhost).
* The URL must use HTTPS for security.

**What this does:**

* Creates a destination for your form data.
* Your server can then process, store, or forward the data as needed.

> [!WARNING]
>
> Your endpoint must respond with a 2xx status code (like 200) to confirm receipt. If it doesn't, we'll retry the webhook.

***

## Step 2: Add the Webhook in Orbit

Now configure OrbitForms to send data to your endpoint.

**What to do in Orbit:**

1. Go to your form and click the **Integrations** tab.
2. Click **Add Integration** and select **Webhook**.
3. Enter your **Webhook URL** (must be HTTPS).
4. Optionally add authentication headers (see Authentication section below).
5. Click **Test Webhook** to verify it works.
6. Click **Save** to enable the webhook.

***

## Payload Format

Webhooks send a POST request with a JSON body containing the form submission data. The example below shows the `submission.created` event:

```json theme={null}
{
  "event": "submission.created",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "form_id": "550e8400-e29b-41d4-a716-446655440000",
    "form_title": "Contact Form",
    "form_slug": "contact",
    "submission_id": "660e8400-e29b-41d4-a716-446655440001",
    "submission_data": {
      "email": "john@example.com",
      "name": "John Doe",
      "message": "Hello, I have a question..."
    },
    "submitted_at": "2024-01-15T10:30:00Z",
    "metadata": {
      "referrer": "https://yoursite.com/contact",
      "device_type": "desktop",
      "utm_source": "google"
    }
  }
}
```

> [!TIP]
>
> The `submission_data` object contains all form fields exactly as submitted. Field names match your form field labels.

### Available Events

A webhook can subscribe to any event in the catalog. Submission events can be limited to one form; everything else is sent for the whole workspace.

| Object | Events |
| - | - |
| Submissions | `submission.created`, `submission.qualified`, `submission.updated`, `submission.deleted` |
| Contacts | `contact.created`, `contact.updated`, `contact.archived`, `contact.deleted`, `contact.tag_added`, `contact.tag_removed`, `contact.association_changed`, `contact.job_changed` |
| Companies | `company.created`, `company.updated`, `company.deleted`, `company.restored`, `company.merged`, `company.tag_added`, `company.tag_removed` |
| Deals | `deal.created`, `deal.updated`, `deal.stage_changed`, `deal.deleted`, `deal.restored`, `deal.merged`, `deal.tag_added`, `deal.tag_removed`, `deal.association_changed`, `deal.line_item_added`, `deal.line_item_updated`, `deal.line_item_removed` |
| Products | `product.created`, `product.updated`, `product.archived`, `product.restored` |
| Quotes | `quote.created`, `quote.updated`, `quote.published`, `quote.viewed`, `quote.accepted`, `quote.voided`, `quote.deleted` |
| Tasks | `task.created`, `task.updated`, `task.completed`, `task.deleted`, `task.restored` |
| Meetings | `meeting.booked`, `meeting.rescheduled`, `meeting.cancelled` |
| Calls | `call.completed`, `call.transcribed`, `call.analyzed` |

Every payload and the fields it carries are described in the [webhook events reference](https://docs.useorbitcrm.ai/developers/webhooks/events.md).

***

## Authentication

Secure your webhook endpoint by adding authentication headers. We recommend using at least one of these methods:

### Bearer Token

```
Authorization: Bearer your-secret-token
```

### API Key Header

```
X-API-Key: your-api-key
```

### Webhook Signature

Each webhook includes a signature header you can use to verify the request came from Orbit:

```
X-Orbit-Signature: sha256=...
```

***

## Retry Logic

If your webhook endpoint returns an error or doesn't respond, OrbitForms automatically retries up to **3 times** with exponential backoff and jitter:

### Retry Schedule

| Retry | Approximate timing (default settings) |
| - | - |
| 1st retry | \~1 minute after initial failure |
| 2nd retry | \~2 minutes after 1st retry |
| 3rd retry | \~4 minutes after 2nd retry |

Notes on retry behavior:

* **4xx responses are not retried** (except `429 Too Many Requests`, which is retried honoring the `Retry-After` header, capped at 5 minutes).
* **5xx responses, network errors, and timeouts are retried.**
* Retry count and delay are configurable per webhook (retries capped at 5, delay capped at 5 minutes).

> [!TIP]
>
> If all retries fail, check your endpoint logs for errors. Common issues include timeouts, invalid responses, or authentication problems.

***

## Common Issues and Fixes

> [accordion] Webhook not receiving data
>
> * Verify your endpoint URL is correct and publicly accessible.
> * Check that your server is accepting POST requests.
> * Make sure your URL uses HTTPS (HTTP is not supported).

> [accordion] Webhook keeps retrying
>
> * Your endpoint must return a 2xx status code (like 200).
> * 5xx responses and timeouts trigger retries; 4xx responses (except 429) stop delivery immediately.
> * Check your server logs for errors processing the request.

> [accordion] Request timing out
>
> * Webhooks time out after 30 seconds by default (configurable up to 60 seconds per webhook).
> * Return a quick response, then process data asynchronously.
> * Avoid slow database queries or external API calls during the request.

### Response Status Codes

| Code | Meaning |
| - | - |
| 2xx | Success - submission delivered |
| 4xx | Client error - will not retry (except 429, which retries honoring `Retry-After`) |
| 5xx | Server error - will retry |

***

## Related Articles

> [card] [Zapier Integration](https://docs.useorbitcrm.ai/integrations/zapier.md)
>
> Connect to 5,000+ apps with no code

> [card] [HubSpot Integration](https://docs.useorbitcrm.ai/integrations/hubspot.md)
>
> Connect to HubSpot CRM

> [card] [Workflow Features](https://docs.useorbitcrm.ai/guides/workflows.md)
>
> Automate with built-in workflows

> [card] [All Integrations](https://docs.useorbitcrm.ai/integrations)
>
> Browse all available integrations


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