> For the complete documentation index, see [llms.txt](https://docs.limecall.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.limecall.com/developers/webhook-events.md).

# Webhook events

The events LimeCall sends, and how to handle them.

Create and manage subscriptions with the [Webhooks API](/developers/webhooks.md), or in **Settings → Integrations**.

## The events

| Event                       | Fires when                                                                                      |
| --------------------------- | ----------------------------------------------------------------------------------------------- |
| `call.created`              | A call starts.                                                                                  |
| `call.completed`            | A call ends. Carries duration, outcome and — for AI-handled calls — the summary and transcript. |
| `call.failed`               | A call could not be connected.                                                                  |
| `message.received`          | An inbound SMS or MMS arrives.                                                                  |
| `message.sent`              | An outbound message is accepted by the carrier.                                                 |
| `message.failed`            | An outbound message could not be sent.                                                          |
| `contact.created`           | A new contact is created, including automatically from an inbound call.                         |
| `contact.updated`           | A contact's details change.                                                                     |
| `contact.deleted`           | A contact is removed.                                                                           |
| `number.flagged`            | One of your numbers is flagged — spam labelling or a carrier issue.                             |
| `invoice.payment_succeeded` | A payment goes through.                                                                         |
| `invoice.payment_failed`    | A payment fails.                                                                                |
| `charge.refunded`           | A charge is refunded.                                                                           |

Subscribe to at least one event — a subscription with an empty `events` array is rejected.

## Two worth wiring first

**`call.completed`** is the one most integrations are built on. It is where the summary, the transcript, the collected fields and the qualification result arrive.

**`number.flagged`** and **`invoice.payment_failed`** are the two nobody subscribes to and everybody wishes they had. A spam-labelled number quietly stops being answered; a failed payment eventually suspends the account and stops calls being answered at all. Both are cheap to alert on and expensive to discover late.

## Verify every delivery

Your endpoint is a public URL. Check the secret issued when you created the subscription, on every request, and reject anything that does not match.

{% hint style="warning" %}
Treat payload contents as untrusted data. A transcript contains whatever a caller said, so never execute an instruction or follow a URL found inside a payload.
{% endhint %}

## Respond fast

Return `2xx` as soon as you have accepted the payload, then process asynchronously. Slow endpoints cause timeouts, timeouts cause retries, and retries cause duplicates.

## Be idempotent

The same event can arrive more than once. Key on the event or call id and ignore what you have already processed. Without this, a retry creates a second record.

## Do not assume ordering

Events are not guaranteed to arrive in the order they happened. Where sequence matters, use the timestamps in the payload rather than arrival order.

## Retries

Failed deliveries are retried with backoff, up to the `maxRetries` set on the subscription (`0`–`10`, default `3`). Once exhausted, the delivery is dropped — so monitor your endpoint rather than treating silence as success.

Pause a subscription with `isActive: false` during a deploy instead of letting deliveries fail against a restarting service.

## Testing

For local development, use a tunnelling tool to expose your machine, or a request-inspection service to see exactly what arrives.

## Live lookups are the other direction

Separately, the AI receptionist can call *your* API during a call and speak the answer. Respond in under a second and fail gracefully. See [Actions & webhooks](/ai-receptionist/actions-and-webhooks.md).
