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

# Testing Webhooks

> How to test webhook delivery and signature verification locally.

Test your webhook integration before going to production.

## Testing Locally with ngrok

Your webhook endpoint needs a public URL. Use [ngrok](https://ngrok.com) to tunnel to your local server:

<Steps>
  <Step title="Start your local server">
    ```bash theme={null}
    node server.js
    # Listening on http://localhost:3000
    ```
  </Step>

  <Step title="Start ngrok">
    ```bash theme={null}
    ngrok http 3000
    # Forwarding: https://abc123.ngrok.io → http://localhost:3000
    ```
  </Step>

  <Step title="Register the webhook">
    Use the ngrok URL as your webhook endpoint:

    ```bash theme={null}
    curl -X POST https://www.agentref.co/api/v1/webhooks \
      -H "Authorization: Bearer ak_live_YOUR_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Local Testing",
        "url": "https://abc123.ngrok.io/webhooks/agentref",
        "subscribedEvents": ["conversion.created", "affiliate.joined"]
      }'
    ```
  </Step>

  <Step title="Trigger an event">
    Perform an action that triggers a webhook, such as completing a Stripe test checkout with attribution metadata or approving an affiliate application.
  </Step>
</Steps>

## Simulating a Webhook with cURL

To test your endpoint's signature verification, simulate a delivery:

```bash theme={null}
# Your webhook secret
SECRET="whsec_your_secret_here"

# Build the payload
BODY='{"id":"msg_test_001","type":"conversion.created","schemaVersion":2,"createdAt":"2026-03-23T18:00:00.000Z","merchantId":"mer_test","environment":"development","data":{"id":"conv_test","affiliateId":"aff_test","programId":"prg_test","paymentProvider":"stripe","externalId":"cs_test","saleAmount":9900,"refundedAmount":0,"currency":"usd","status":"pending"}}'

# Generate signature
MSG_ID="msg_test_001"
TIMESTAMP=$(date +%s)
SIGNATURE=$(echo -n "${MSG_ID}.${TIMESTAMP}.${BODY}" | openssl dgst -sha256 -hmac $(echo -n "${SECRET#whsec_}" | base64 -d) -binary | base64)

# Send the request
curl -X POST http://localhost:3000/webhooks/agentref \
  -H "Content-Type: application/json" \
  -H "svix-id: ${MSG_ID}" \
  -H "svix-timestamp: ${TIMESTAMP}" \
  -H "svix-signature: v1,${SIGNATURE}" \
  -d "${BODY}"
```

## Verification Checklist

Before going to production, confirm:

* [ ] Your endpoint returns `200` within 30 seconds
* [ ] Signature verification works correctly
* [ ] You handle duplicate deliveries (check event `id`)
* [ ] You process events asynchronously (don't block the response)
* [ ] Your endpoint uses HTTPS in production
* [ ] You've subscribed only to events you need
* [ ] Error handling is in place – a crash won't take down your server

## Debugging Delivery Issues

If webhooks aren't arriving:

1. **Check the dashboard** – go to Settings → Webhooks to see delivery status and errors
2. **Verify the URL** – is your endpoint reachable from the public internet?
3. **Check HTTPS** – production webhooks require HTTPS (localhost HTTP is allowed in development)
4. **Check event subscription** – did you subscribe to the event types you're expecting?
5. **Check response code** – a non-2xx response triggers retries, not immediate re-delivery
