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

# Webhooks

> Receive real-time notifications for events in your project

Webhooks allow you to receive real-time HTTP notifications when events occur in your Gately project. Use them to trigger automations, sync data, or integrate with external services.

## Overview

When an event occurs (e.g., new member signup), Gately sends an HTTP POST request to your configured webhook URL with event data.

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Gately
    participant Your Server
    
    User->>Gately: Signs up
    Gately->>Your Server: POST /webhook
    Your Server->>Gately: 200 OK
```

## Setting Up Webhooks

### Via Dashboard

1. Go to **Webhooks** in your dashboard
2. Click **Create Webhook**
3. Enter your endpoint URL
4. Select events to subscribe to
5. Save

### Webhook Configuration

| Field   | Description                        |
| ------- | ---------------------------------- |
| URL     | Your endpoint URL (HTTPS required) |
| Events  | Events to trigger the webhook      |
| Secret  | Signing secret for verification    |
| Headers | Custom headers to include          |
| Active  | Enable/disable the webhook         |

## Events

### Member Events

| Event                 | Description                      |
| --------------------- | -------------------------------- |
| `member.created`      | New member signed up             |
| `member.updated`      | Member profile updated           |
| `member.deleted`      | Member account deleted           |
| `member.login`        | Member logged in                 |
| `member.plan_changed` | Member changed subscription plan |

### Form Events

| Event            | Description              |
| ---------------- | ------------------------ |
| `form.submitted` | Form submission received |
| `form.created`   | New form created         |
| `form.updated`   | Form settings updated    |

### Subscription Events

| Event                    | Description              |
| ------------------------ | ------------------------ |
| `subscription.created`   | New subscription started |
| `subscription.updated`   | Subscription modified    |
| `subscription.cancelled` | Subscription cancelled   |
| `subscription.renewed`   | Subscription renewed     |

### Payment Events

| Event               | Description        |
| ------------------- | ------------------ |
| `payment.succeeded` | Payment successful |
| `payment.failed`    | Payment failed     |
| `refund.created`    | Refund issued      |

### Helpdesk Events

| Event            | Description           |
| ---------------- | --------------------- |
| `ticket.created` | New support ticket    |
| `ticket.updated` | Ticket status changed |
| `ticket.replied` | New reply on ticket   |

## Payload Format

All webhook payloads follow this structure:

```json theme={null}
{
  "id": "evt_123456789",
  "event": "member.created",
  "created_at": "2024-01-15T10:30:00Z",
  "project_id": "proj_abc123",
  "data": {
    // Event-specific data
  }
}
```

### Example: Member Created

```json theme={null}
{
  "id": "evt_123456789",
  "event": "member.created",
  "created_at": "2024-01-15T10:30:00Z",
  "project_id": "proj_abc123",
  "data": {
    "id": "mem_xyz789",
    "email": "user@example.com",
    "full_name": "John Doe",
    "plan_id": "free",
    "status": "active",
    "created_at": "2024-01-15T10:30:00Z"
  }
}
```

### Example: Form Submitted

```json theme={null}
{
  "id": "evt_987654321",
  "event": "form.submitted",
  "created_at": "2024-01-15T11:00:00Z",
  "project_id": "proj_abc123",
  "data": {
    "form_id": "form_123",
    "submission_id": "sub_456",
    "fields": {
      "name": "Jane Smith",
      "email": "jane@example.com",
      "message": "Hello!"
    },
    "submitted_at": "2024-01-15T11:00:00Z"
  }
}
```

## Verifying Webhooks

All webhooks are signed with your webhook secret. Verify the signature to ensure the request is from Gately.

### Signature Header

```
X-Gately-Signature: sha256=abc123...
```

### Verification (Node.js)

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

function verifyWebhook(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex')
  
  return `sha256=${expectedSignature}` === signature
}

// Express middleware
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-gately-signature']
  
  if (!verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature')
  }
  
  const event = JSON.parse(req.body)
  // Process event...
  
  res.status(200).send('OK')
})
```

### Verification (Python)

```python theme={null}
import hmac
import hashlib

def verify_webhook(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    
    return f"sha256={expected}" == signature
```

## Retry Policy

If your endpoint returns a non-2xx status code, Gately will retry:

| Attempt | Delay      |
| ------- | ---------- |
| 1       | Immediate  |
| 2       | 1 minute   |
| 3       | 5 minutes  |
| 4       | 30 minutes |
| 5       | 2 hours    |

After 5 failed attempts, the webhook is marked as failed.

## Best Practices

<AccordionGroup>
  <Accordion title="Respond Quickly">
    Return a 200 response immediately, then process the event asynchronously.
  </Accordion>

  <Accordion title="Handle Duplicates">
    Use the event `id` to deduplicate events (webhooks may be sent multiple times).
  </Accordion>

  <Accordion title="Verify Signatures">
    Always verify the webhook signature to prevent spoofing.
  </Accordion>

  <Accordion title="Use HTTPS">
    Only use HTTPS endpoints for security.
  </Accordion>

  <Accordion title="Log Events">
    Log all received events for debugging and auditing.
  </Accordion>
</AccordionGroup>

## Testing Webhooks

### Test from Dashboard

1. Go to **Webhooks > \[Your Webhook]**
2. Click **Send Test Event**
3. Select event type
4. View response

### Local Development

Use a tunnel service like ngrok for local testing:

```bash theme={null}
ngrok http 3000
```

Then use the ngrok URL as your webhook endpoint.

## Webhook Logs

View webhook delivery history:

1. Go to **Webhooks > \[Your Webhook] > Logs**
2. See all delivery attempts
3. View request/response details
4. Retry failed deliveries
