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

# Webhook Ingestion

> Push feedback to ClosedLoop AI from any platform: surveys with no native connector, in-product widgets, mobile apps. Webhook in, scored insights out.

Connect 40+ platforms to ClosedLoop AI via webhooks: surveys, reviews, meetings, and more. Data is verified, transformed, and routed into the AI pipeline automatically. Within minutes, your webhook data becomes scored product intelligence alongside all your other sources.

## Endpoint Format

All webhook endpoints follow the same URL pattern:

```
POST https://mcp.closedloop.sh/webhooks/{category}/{platform}
```

For example:

```
POST https://mcp.closedloop.sh/webhooks/surveys/typeform
POST https://mcp.closedloop.sh/webhooks/meetings/gong
POST https://mcp.closedloop.sh/webhooks/reviews/g2
```

## Supported Platforms

### Surveys

Collect structured data from survey and form platforms.

| Platform        | Endpoint                            |
| --------------- | ----------------------------------- |
| Typeform        | `/webhooks/surveys/typeform`        |
| SurveyMonkey    | `/webhooks/surveys/surveymonkey`    |
| Google Forms    | `/webhooks/surveys/google-forms`    |
| Qualtrics       | `/webhooks/surveys/qualtrics`       |
| Jotform         | `/webhooks/surveys/jotform`         |
| Airtable Forms  | `/webhooks/surveys/airtable-forms`  |
| Microsoft Forms | `/webhooks/surveys/microsoft-forms` |
| Formstack       | `/webhooks/surveys/formstack`       |
| Wufoo           | `/webhooks/surveys/wufoo`           |
| Cognito Forms   | `/webhooks/surveys/cognito-forms`   |

### Feedback

Capture data from dedicated product feedback management tools.

| Platform        | Endpoint                             |
| --------------- | ------------------------------------ |
| UserVoice       | `/webhooks/feedback/uservoice`       |
| Canny           | `/webhooks/feedback/canny`           |
| Productboard    | `/webhooks/feedback/productboard`    |
| Aha!            | `/webhooks/feedback/aha`             |
| Feature Request | `/webhooks/feedback/feature-request` |
| Upvoty          | `/webhooks/feedback/upvoty`          |
| Nolt            | `/webhooks/feedback/nolt`            |
| HelloNext       | `/webhooks/feedback/hellonext`       |
| FeedBear        | `/webhooks/feedback/feedbear`        |
| Savio           | `/webhooks/feedback/savio`           |

### Reviews

Monitor customer reviews from major review platforms.

| Platform       | Endpoint                           |
| -------------- | ---------------------------------- |
| G2             | `/webhooks/reviews/g2`             |
| Capterra       | `/webhooks/reviews/capterra`       |
| Trustpilot     | `/webhooks/reviews/trustpilot`     |
| Google Reviews | `/webhooks/reviews/google-reviews` |
| Yelp           | `/webhooks/reviews/yelp`           |
| App Store      | `/webhooks/reviews/app-store`      |
| Play Store     | `/webhooks/reviews/play-store`     |
| Glassdoor      | `/webhooks/reviews/glassdoor`      |
| Indeed         | `/webhooks/reviews/indeed`         |
| BBB            | `/webhooks/reviews/bbb`            |

### Meetings

Receive transcripts and notes from meeting intelligence platforms.

| Platform   | Endpoint                        |
| ---------- | ------------------------------- |
| Gong       | `/webhooks/meetings/gong`       |
| Chorus     | `/webhooks/meetings/chorus`     |
| Fireflies  | `/webhooks/meetings/fireflies`  |
| Avoma      | `/webhooks/meetings/avoma`      |
| Otter      | `/webhooks/meetings/otter`      |
| MeetRecord | `/webhooks/meetings/meetrecord` |
| Rev        | `/webhooks/meetings/rev`        |
| Sonix      | `/webhooks/meetings/sonix`      |
| Trint      | `/webhooks/meetings/trint`      |
| Temi       | `/webhooks/meetings/temi`       |

## Authentication

Every webhook request must be authenticated using two mechanisms:

### API Key Header

Include your webhook API key in the request header:

```
x-api-key: your-webhook-api-key
```

### HMAC-SHA256 Signature

ClosedLoop AI verifies the integrity of each webhook payload using HMAC-SHA256. The signature is computed over the raw request body using your webhook secret.

**Supported signature headers** (checked in order):

| Header                | Used By                |
| --------------------- | ---------------------- |
| `x-webhook-signature` | Generic / default      |
| `x-hub-signature-256` | GitHub-style platforms |
| `x-signature`         | Various platforms      |
| `typeform-signature`  | Typeform               |

The signature can be sent as either **hex** or **base64** encoded: ClosedLoop AI auto-detects the encoding format.

<Tip>Signatures with a `sha256=` prefix are automatically stripped before verification.</Tip>

### Getting Your Webhook Secret

1. Log in to [ClosedLoop AI](https://app.closedloop.sh)
2. Navigate to **Settings** → **API Keys**
3. Generate a **Webhook Key**: this is your HMAC signing secret
4. Copy the secret and configure it in your source platform's webhook settings

## Standard Payload Format

After receiving a webhook, ClosedLoop AI transforms the platform-specific payload into a standard format before inserting it into the processing pipeline:

```json theme={null}
{
  "title": "Customer feedback from Typeform survey",
  "content": "The new dashboard is hard to navigate. I keep losing track of where my reports are.",
  "source_id": "typeform-response-abc123",
  "timestamp": "2026-02-24T10:30:00Z",
  "customer_id": "cust_12345",
  "reporter_name": "Jane Smith",
  "reporter_email": "jane@example.com",
  "language": "en"
}
```

| Field            | Type           | Description                                     |
| ---------------- | -------------- | ----------------------------------------------- |
| `title`          | string         | Human-readable title for the item               |
| `content`        | string         | The main text, transcript, or review body       |
| `source_id`      | string         | Unique identifier from the source platform      |
| `timestamp`      | string         | ISO 8601 timestamp of when the item was created |
| `customer_id`    | string \| null | Optional customer identifier                    |
| `reporter_name`  | string \| null | Name of the person who submitted the data       |
| `reporter_email` | string \| null | Email of the person who submitted the data      |
| `language`       | string         | Language code (defaults to `en`)                |

<Note>You don't need to send data in this exact format. Each platform has its own native webhook payload: ClosedLoop AI automatically transforms it to this standard schema.</Note>

## Setup Steps

<AccordionGroup>
  <Accordion icon="key" title="Step 1: Get your webhook secret">
    1. Go to [ClosedLoop AI](https://app.closedloop.sh) → **Settings** → **API Keys**
    2. Click **Generate New Key** and select **Webhook Key**
    3. Copy the secret. You'll need it to configure your source platform

    <Warning>Store your webhook secret securely. You won't be able to view it again after creation.</Warning>
  </Accordion>

  <Accordion icon="plug" title="Step 2: Configure your source platform">
    In your source platform's webhook settings:

    1. Set the **webhook URL** to your ClosedLoop AI endpoint:
       ```
       https://mcp.closedloop.sh/webhooks/{category}/{platform}
       ```
    2. Set the **signing secret** to your ClosedLoop AI webhook secret
    3. Select the events you want to send (e.g., new responses, new reviews)
    4. Save the webhook configuration
  </Accordion>

  <Accordion icon="check" title="Step 3: Verify with a test payload">
    Most platforms have a "Send test webhook" button. Use it to verify:

    * The webhook reaches ClosedLoop AI successfully
    * The HMAC signature is verified
    * The payload is transformed correctly

    Check the response. A successful webhook returns:

    ```json theme={null}
    {
      "success": true,
      "message": "Webhook processed successfully",
      "data_id": "uuid-of-created-record"
    }
    ```
  </Accordion>
</AccordionGroup>

## Health & Discovery

### Health Check

Verify the webhook system is operational:

```bash theme={null}
curl https://mcp.closedloop.sh/webhooks/health
```

```json theme={null}
{
  "success": true,
  "message": "Webhook endpoints are healthy",
  "timestamp": "2026-02-24T10:00:00.000Z"
}
```

### Endpoint Discovery

List all available webhook endpoints:

```bash theme={null}
curl https://mcp.closedloop.sh/webhooks/endpoints
```

```json theme={null}
{
  "success": true,
  "message": "Available webhook endpoints",
  "data": {
    "surveys": ["POST /webhooks/surveys/typeform", "..."],
    "feedback": ["POST /webhooks/feedback/uservoice", "..."],
    "reviews": ["POST /webhooks/reviews/g2", "..."],
    "meetings": ["POST /webhooks/meetings/gong", "..."]
  },
  "total_endpoints": 40
}
```

## Code Examples

### Sending a Webhook with cURL

```bash theme={null}
# Compute HMAC-SHA256 signature
PAYLOAD='{"form_response":{"form_id":"abc123","submitted_at":"2026-02-24T10:30:00Z","answers":[{"type":"text","text":"The dashboard needs better filtering"}]}}'
SECRET="your-webhook-secret"
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2)

# Send the webhook
curl -X POST https://mcp.closedloop.sh/webhooks/surveys/typeform \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -H "x-webhook-signature: sha256=$SIGNATURE" \
  -d "$PAYLOAD"
```

### Verifying HMAC in Node.js

If you're building a proxy or middleware that forwards webhooks to ClosedLoop AI, here's how to verify signatures:

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

function verifyWebhookSignature(rawBody, signature, secret) {
  // Strip sha256= prefix if present
  const sig = signature.replace(/^sha256=/, '');

  // Compute expected signature
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  // Use timing-safe comparison
  return crypto.timingSafeEqual(
    Buffer.from(sig, 'hex'),
    Buffer.from(expected, 'hex')
  );
}
```

## Error Handling

| HTTP Status | Error Code                    | Description                                         |
| ----------- | ----------------------------- | --------------------------------------------------- |
| 401         | `WEBHOOK_VERIFICATION_FAILED` | HMAC signature mismatch or missing signature header |
| 400         | `INVALID_PAYLOAD_FORMAT`      | Payload could not be parsed or transformed          |
| 500         | `PROCESSING_ERROR`            | Internal error during webhook processing            |

**Common issues:**

* **Missing signature**: Ensure your platform is configured to sign webhooks with the correct secret
* **Wrong endpoint**: Verify the category and platform in the URL match your source
* **Payload too large**: Webhook payloads are limited to 10 MB
* **Secret mismatch**: Regenerate your webhook secret if signatures consistently fail

## What Happens Next

After a webhook is received and verified:

1. The payload is transformed to the standard format
2. Data is inserted into the processing pipeline
3. AI analysis runs automatically: insights are scored by business impact
4. Product intelligence appears in your dashboard and is available to MCP-connected AI dev agents

<Card title="View Your Intelligence" icon="database" href="https://app.closedloop.sh/feedback">
  See processed webhook data as scored product intelligence in your ClosedLoop AI dashboard
</Card>
