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

# Receiving Webhooks

> Understand how webhooks are received and stored by agntdata.

## How Webhooks Are Received

When an external service sends a webhook to your endpoint, agntdata:

1. Accepts the HTTP request
2. Stores the payload, headers, and metadata as a "delivery"
3. Returns a `200 OK` response to the sender

```mermaid theme={null}
sequenceDiagram
    participant Service as External Service
    participant agntdata as agntdata Webhook
    participant DB as Storage

    Service->>agntdata: POST /webhooks/ingest/:hookId
    Note right of Service: Headers + JSON Body
    agntdata->>DB: Store delivery
    agntdata->>Service: 200 OK
```

## What Gets Stored

Each delivery includes:

| Field               | Description                                       |
| ------------------- | ------------------------------------------------- |
| `id`                | Unique delivery identifier                        |
| `webhookEndpointId` | The endpoint that received it                     |
| `rawPayload`        | The complete JSON body                            |
| `headers`           | HTTP headers from the request                     |
| `sourceIp`          | IP address of the sender                          |
| `createdAt`         | When the delivery was received                    |
| `acknowledgedAt`    | When you marked it as processed (null if pending) |

## Supported Methods and Formats

### HTTP Methods

agntdata webhook endpoints accept:

* `POST` — Standard webhook delivery

### Content Types

* `application/json` — Parsed and stored as JSON
* Other content types — Stored as `{ raw: "..." }`

<Note>
  JSON payloads are recommended for best compatibility.
</Note>

## Delivery Example

A Stripe webhook delivery might look like:

```json theme={null}
{
  "id": "del_abc123",
  "webhookEndpointId": "wh_xyz789",
  "workspaceId": "ws_abc123",
  "rawPayload": {
    "id": "evt_1234",
    "type": "payment_intent.succeeded",
    "data": {
      "object": {
        "id": "pi_5678",
        "amount": 2000,
        "currency": "usd"
      }
    }
  },
  "headers": {
    "content-type": "application/json",
    "stripe-signature": "t=1699999999,v1=abc123..."
  },
  "sourceIp": "54.187.174.169",
  "acknowledgedAt": null,
  "createdAt": "2024-01-15T10:30:00Z"
}
```

## Response to Senders

On success, agntdata returns:

```json theme={null}
{
  "received": true,
  "deliveryId": "uuid-..."
}
```

This ensures external services know the delivery was received and can track it.

## Handling Large Payloads

Payloads up to 1 MB are accepted. For larger payloads:

<Warning>
  Payloads exceeding 1 MB are rejected with a `413 Payload Too Large` error.
</Warning>

If you need to receive larger payloads, consider:

* Asking the sender to paginate or summarize data
* Using a different integration approach
* Contacting us about enterprise limits

## Verifying Webhook Signatures

Many services sign their webhooks for security. The signature is typically in a header:

| Service | Signature Header        |
| ------- | ----------------------- |
| Stripe  | `stripe-signature`      |
| GitHub  | `x-hub-signature-256`   |
| Shopify | `x-shopify-hmac-sha256` |
| Twilio  | `x-twilio-signature`    |

When processing deliveries, verify signatures against the `headers` field:

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

function verifyStripeSignature(payload, signature, secret) {
  const [timestamp, hash] = parseStripeSignature(signature);
  const expectedHash = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${JSON.stringify(payload)}`)
    .digest('hex');
  return hash === expectedHash;
}
```

## Error Handling

If agntdata can't process an incoming webhook:

| Status | Meaning                                            |
| ------ | -------------------------------------------------- |
| `200`  | Success — delivery stored                          |
| `404`  | Endpoint not found — check the `hookId` in the URL |
| `413`  | Payload too large — exceeds 1 MB limit             |
| `500`  | Server error — will be retried by most senders     |

## Next Steps

<CardGroup cols={2}>
  <Card title="Managing Deliveries" icon="list-check" href="/webhooks/deliveries">
    Learn how to fetch and acknowledge deliveries.
  </Card>

  <Card title="Creating Endpoints" icon="plus" href="/webhooks/endpoints">
    Set up more webhook endpoints.
  </Card>
</CardGroup>
