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

# Hany Webhooks: Real-Time Delivery Event Notifications

> Hany webhooks push real-time event data to your server. Set a callback_url when sending SMS to receive instant delivery status updates.

Webhooks let you receive instant, server-to-server notifications when events occur in Hany — no polling required. Instead of repeatedly querying the API to check whether an SMS was delivered, Hany sends an HTTP POST request directly to a URL you specify the moment the event happens.

## How Webhooks Work

<Steps>
  <Step title="Provide a callback URL">
    Include a `callback_url` in your send request. This is the HTTPS endpoint on your server that Hany will call when an event fires.
  </Step>

  <Step title="Hany sends an HTTP POST">
    When the event occurs (for example, a delivery confirmation arrives from the carrier), Hany sends an HTTP POST request to your `callback_url` with a JSON payload describing the event.
  </Step>

  <Step title="Acknowledge with HTTP 200">
    Your server must respond with an HTTP `200 OK` status code to confirm receipt. Any response body is ignored — only the status code matters.
  </Step>

  <Step title="Automatic retries on failure">
    If your server does not respond with `200`, Hany retries the delivery on a fixed schedule — up to 3 total attempts — before marking the event as undelivered. See the [Retry Policy](#retry-policy) section for the exact schedule.
  </Step>
</Steps>

## Registering a Webhook URL

Webhook URLs are configured **per-request** using the `callback_url` parameter on any send endpoint. There is no separate webhook registration step — simply include your endpoint URL when you send a message.

```bash theme={null}
curl -X POST https://api.hany.tools/v1/sms/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15550001234",
    "from": "YourBrand",
    "message": "Your order has shipped!",
    "callback_url": "https://yourapp.com/webhooks/hany"
  }'
```

When Hany receives a delivery status update for this message, it will POST the event payload to `https://yourapp.com/webhooks/hany`.

## Webhook Security

Keep your webhook endpoint secure and resilient by following these best practices:

* **Use HTTPS only.** Hany will not deliver webhooks to plain HTTP endpoints. Always use a valid TLS certificate.
* **Validate the payload structure.** Check that the incoming payload contains the fields you expect before processing it. Reject malformed requests with a `400` status.
* **Respond within 5 seconds.** Hany waits up to 5 seconds for a response. If your handler takes longer, move heavy processing to a background job and return `200` immediately.
* **Return HTTP 200 to acknowledge.** Any status code other than `200` is treated as a failure and triggers a retry. This includes `2xx` codes such as `201` or `204`.

<Warning>
  Do not perform database writes, API calls, or other slow operations synchronously inside your webhook handler. Respond with `200` first, then process the event asynchronously to prevent timeouts and duplicate deliveries.
</Warning>

## Retry Policy

When your endpoint fails to return HTTP `200`, Hany automatically retries the delivery on the following schedule:

| Attempt   | Timing                     |
| --------- | -------------------------- |
| Attempt 1 | Immediately                |
| Attempt 2 | 30 seconds after Attempt 1 |
| Attempt 3 | 5 minutes after Attempt 2  |

After 3 consecutive failures, Hany marks the webhook event as **undelivered** and stops retrying. Make sure your endpoint is reachable and returns `200` reliably to avoid missed events.

<Note>
  Each retry sends the same payload as the original request. Design your handler to be **idempotent** — processing the same event more than once should not cause unintended side effects.
</Note>

## Supported Events

The following webhook event types are currently available:

| Event           | Description                                               |
| --------------- | --------------------------------------------------------- |
| `sms.delivered` | SMS successfully delivered to the recipient               |
| `sms.failed`    | SMS delivery failed after all carrier retries             |
| `sms.sent`      | SMS dispatched from Hany's gateway to the carrier network |

<CardGroup cols={1}>
  <Card title="Delivery Status Webhook" icon="circle-check" href="/api-reference/webhooks/delivery-status">
    Full payload reference for `sms.delivered`, `sms.failed`, and `sms.sent` events, plus a server-side handling example.
  </Card>
</CardGroup>
