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

# Webhook routing

> Choose where incoming Instagram DMs are delivered.

## Listen in sandbox

Run `hookmyapp sandbox listen` to tell HookMyApp where to send sandbox Instagram DMs while you test.

If you are using the starter kit, it serves per-channel routes.<br />
Use `--path` to choose the Instagram route in your local receiver:

```bash theme={null}
hookmyapp sandbox listen --port 3000 --path /webhook/instagram
```

View the current sandbox session with `hookmyapp sandbox status`.

## Listen to account locally

Run `hookmyapp channels listen <channel>` to tell HookMyApp to send DMs from your connected Instagram account to your computer or server while the command is running.

Use this to test with your real Instagram account before you deploy.<br />
Use `--path` to choose the Instagram route in your local receiver:

```bash theme={null}
hookmyapp channels listen ch_xxxxxxxx --path /webhook/instagram
# or omit the channel arg for the interactive picker:
hookmyapp channels listen
```

If you set a webhook URL while local listening is running, local listening stops.
Use one message destination per channel.

## Deployed webhook URL

When your receiver is deployed, set its public URL with `hookmyapp channels webhook set`.
HookMyApp sends new Instagram DMs to that URL.

```bash theme={null}
hookmyapp channels webhook set ch_xxxxxxxx \
  --url https://api.acme.com/webhook/instagram \
  --verify-token $(openssl rand -hex 32)

# Show webhook URL and verification state
hookmyapp channels webhook show ch_xxxxxxxx

# Clear webhook URL
hookmyapp channels webhook clear ch_xxxxxxxx
```

## Verify delivery end-to-end

1. **Check the current webhook URL.** `hookmyapp channels webhook show <channel>` prints the URL and its verified status. If the status is not `verified`, your server failed the verification request.
2. **Check channel health.** `hookmyapp channels health <channel>` shows webhook state and channel health. Anything not `healthy` means Meta cannot deliver.
3. **Send yourself a test DM.** From another account, message your Instagram account. Watch your server logs for the inbound POST and a 200 response.
4. **If signature fails, refresh env.** A signature-mismatch 401 means your local `WEBHOOK_HMAC_SECRET` is stale. Re-run `hookmyapp sandbox env --write .env` (sandbox) or `hookmyapp channels env <channel>` (your own channel) and restart your server.

## When things break

* Webhook verify GET returns 404: your server is not handling `GET /webhook/instagram`.<br />
  Add the verification route that echoes the verify token.
* Signature mismatch on POST: your `.env` is stale.<br />
  Re-pull env values and restart.
* No delivery at all: run `hookmyapp channels health <channel>`.<br />
  If it is unhealthy, delivery is blocked at Meta.
* Local listening stopped: `hookmyapp sandbox listen` exited.<br />
  Re-run it.
* Local listening changed: another webhook URL was set on the channel.<br />
  Re-run `channels listen` if you still want DMs on your laptop.

## Next steps

* [Receive webhooks](/instagram/receive-webhooks): Re-check the verify-and-acknowledge contract.
* [Send text](/instagram/send-messages/text): Send a reply after your webhook receives a DM.
