---
title: "Webhooks"
description: "Check that an event is from Goomzo, and manage your endpoints."
url: "https://docs.goomzo.africa/docs/developers/python-sdk/webhooks"
docs_index: /llms.txt
lastUpdated: 2026-11-12
section: "Guides"
related:
  - /docs/developers/python-sdk/messages
  - /docs/developers/python-sdk/templates
  - /docs/developers/python-sdk/customers
---

> For an index of all documentation, see [/llms.txt](https://docs.goomzo.africa/llms.txt). Any page is also available as Markdown by adding .md to its URL.

# Webhooks

> Check that an event is from Goomzo, and manage your endpoints.

`verify_webhook` checks an event's signature and timestamp, and returns the event. See
[Signatures](https://docs.goomzo.africa/docs/developers/webhooks/signatures?utm_source=llms&utm_medium=ai).

## Requirements

- An endpoint, and its signing secret, which starts with `whsec_`. See [Webhooks](https://docs.goomzo.africa/docs/developers/webhooks?utm_source=llms&utm_medium=ai).

## Receive an event

Pass the body exactly as it arrived, before parsing it:

```python title="Flask"
import os
from flask import Flask, request
from goomzo import WebhookVerificationError, verify_webhook

app = Flask(__name__)

@app.post('/webhooks/goomzo')
def goomzo_webhook():
    try:
        event = verify_webhook(request.get_data(), request.headers, os.environ['GOOMZO_WEBHOOK_SECRET'])
    except WebhookVerificationError:
        return '', 400
    if event['type'] == 'message.delivered':
        mark_delivered(event['data']['id'])
    return '', 204
```

```python title="FastAPI"
from fastapi import FastAPI, HTTPException, Request

app = FastAPI()

@app.post('/webhooks/goomzo', status_code=204)
async def goomzo_webhook(request: Request) -> None:
    try:
        event = verify_webhook(await request.body(), request.headers, os.environ['GOOMZO_WEBHOOK_SECRET'])
    except WebhookVerificationError:
        raise HTTPException(400)
    ...
```

**Important:** Don't parse the body as JSON before checking it. The signature is of the body as it arrived.

## Manage endpoints

```python
endpoint = goomzo.webhook_endpoints.create({
    'url': 'https://example.com/webhooks/goomzo',
    'events': ['message.delivered', 'message.failed'],
})
endpoint['secret']  # whsec_…
```

| Method                                  | Does                                  |
| --------------------------------------- | ------------------------------------- |
| `webhook_endpoints.list()`              | Lists your endpoints.                 |
| `webhook_endpoints.get(id)`             | Gets one.                             |
| `webhook_endpoints.update(id, changes)` | Changes an endpoint, or turns it off. |
| `webhook_endpoints.delete(id)`          | Deletes one.                          |

## Next steps

- [Events](https://docs.goomzo.africa/docs/developers/webhooks/events?utm_source=llms&utm_medium=ai)
- [Errors](https://docs.goomzo.africa/docs/developers/python-sdk/errors?utm_source=llms&utm_medium=ai)

---

For an index of all available documentation, see [/llms.txt](https://docs.goomzo.africa/llms.txt)
