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

# Webhooks

> Receive real-time notifications when forms are submitted

## Overview

Webhooks let you receive an HTTP POST request to your server whenever a form submission is completed. This enables real-time integrations with your backend, CRM, notification systems, or any external service.

A webhook fires when **all required questions** on a form have been answered.

## Configuring a Webhook

Use the [Update Form](/api-reference/forms/update-form) endpoint to set a webhook URL and enable delivery:

```bash theme={null}
curl -X PATCH https://geniusforms.ai/api/v1/forms/208 \
  -H "X-API-Key: gf_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "webhookUrl": "https://example.com/webhooks/geniusforms",
    "webhookEnabled": true
  }'
```

The response includes the updated webhook configuration:

```json theme={null}
{
  "id": 208,
  "title": "Customer Feedback",
  "webhook": {
    "enabled": true,
    "url": "https://example.com/webhooks/geniusforms"
  }
}
```

### Disabling a Webhook

Set `webhookEnabled` to `false` to stop deliveries without removing the URL:

```bash theme={null}
curl -X PATCH https://geniusforms.ai/api/v1/forms/208 \
  -H "X-API-Key: gf_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "webhookEnabled": false }'
```

To clear the URL entirely, set `webhookUrl` to `null`. This automatically disables the webhook:

```bash theme={null}
curl -X PATCH https://geniusforms.ai/api/v1/forms/208 \
  -H "X-API-Key: gf_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "webhookUrl": null }'
```

## Payload Format

When a form submission is completed, GeniusForms sends a `POST` request with a JSON body:

```json theme={null}
{
  "form_id": 208,
  "form_name": "Customer Feedback",
  "submission_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "submitted_at": "2026-02-07T14:30:00.000Z",
  "data": {
    "Your name": "Jane Smith",
    "Your email": "jane@example.com",
    "How satisfied are you?": "5",
    "Any additional feedback?": "Great product, keep it up!"
  }
}
```

| Field           | Description                                                      |
| --------------- | ---------------------------------------------------------------- |
| `form_id`       | The numeric ID of the form                                       |
| `form_name`     | The form's title                                                 |
| `submission_id` | Unique session ID for this submission                            |
| `submitted_at`  | ISO 8601 timestamp                                               |
| `data`          | Key-value pairs mapping question text to the respondent's answer |

The request includes these headers:

| Header         | Value                       |
| -------------- | --------------------------- |
| `Content-Type` | `application/json`          |
| `User-Agent`   | `GeniusFormsAI-Webhook/1.0` |

## Testing Your Webhook

Before going live, verify your endpoint works with the [Test Webhook](/api-reference/webhooks/test-webhook) endpoint:

```bash theme={null}
curl -X POST https://geniusforms.ai/api/v1/forms/208/webhook/test \
  -H "X-API-Key: gf_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/webhooks/geniusforms" }'
```

This sends a sample payload to the URL and returns the result:

```json theme={null}
{
  "success": true,
  "statusCode": 200,
  "error": null
}
```

If no `url` is provided in the request body, it tests the form's currently configured webhook URL.

## Checking Delivery Logs

Use the [Get Webhook Logs](/api-reference/webhooks/get-webhook-logs) endpoint to review delivery history:

```bash theme={null}
curl https://geniusforms.ai/api/v1/forms/208/webhook/logs?limit=10 \
  -H "X-API-Key: gf_live_your_key_here"
```

```json theme={null}
{
  "logs": [
    {
      "id": 42,
      "sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "webhookUrl": "https://example.com/webhooks/geniusforms",
      "status": "success",
      "responseCode": 200,
      "errorMessage": null,
      "createdAt": "2026-02-07T14:30:01.000Z"
    }
  ],
  "total": 1,
  "hasMore": false,
  "limit": 10,
  "offset": 0
}
```

## Checking Webhook Status

Get a quick summary of the current configuration and the last delivery attempt with the [Get Webhook Status](/api-reference/webhooks/get-webhook-status) endpoint:

```bash theme={null}
curl https://geniusforms.ai/api/v1/forms/208/webhook/status \
  -H "X-API-Key: gf_live_your_key_here"
```

```json theme={null}
{
  "enabled": true,
  "url": "https://example.com/webhooks/geniusforms",
  "lastDelivery": {
    "status": "success",
    "responseCode": 200,
    "error": null,
    "attemptedAt": "2026-02-07T14:30:01.000Z"
  }
}
```

## Security Notes

* **HTTPS recommended** - Use HTTPS URLs for webhook endpoints to protect payload data in transit.
* **Localhost blocked in production** - `localhost`, `127.0.0.1`, and private IP ranges (`192.168.*`, `10.*`, `172.*`) are blocked in production to prevent SSRF attacks.
* **10-second timeout** - Webhook requests time out after 10 seconds. Return a `2xx` response quickly and process the data asynchronously if needed.
* **Non-blocking** - Webhook failures never prevent form submissions from being saved. Failed deliveries are logged for debugging.
* **No retries** - Failed webhook deliveries are not automatically retried. Check the delivery logs to identify and resolve issues.

## Validation Rules

| Rule         | Detail                                                                                        |
| ------------ | --------------------------------------------------------------------------------------------- |
| URL format   | Must be a valid HTTP or HTTPS URL                                                             |
| URL length   | Maximum 2000 characters                                                                       |
| Enabling     | `webhookEnabled: true` requires a `webhookUrl` to be set (on the form or in the same request) |
| Clearing URL | Setting `webhookUrl` to `null` or `""` automatically sets `webhookEnabled` to `false`         |
