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

# Migrate from legacy webhooks

> Move webhooks created in the Quo app or through the v1 API to new webhooks.

New webhooks replace legacy webhooks that you created in the Quo app or with the `/v1/webhooks` endpoints. Event names do not change, but the payload shape, the signature headers, and the signing secret do.

## What changes

| Area | Legacy | New |
| - | - | - |
| Payload | `data.object` | `data.resource`, `data.context`, and `data.links` |
| Signature | `OpenPhone-Signature` header | `webhook-id`, `webhook-timestamp`, and `webhook-signature` headers |
| Signing secret | Legacy key | `whsec_…` key. The [`svix`](https://www.npmjs.com/package/svix) library verifies it. |
| API endpoints | One `/v1/webhooks/*` endpoint for each event family | One `POST /webhooks` with an `events` array |

## Update your endpoint

Before you enable a new webhook, make these changes:

* Parse the new payloads. See [Webhook event payloads](https://www.quo.com/docs/2026-03-30/webhooks-event-payloads.md).
* Verify the new signature headers. Code that verifies the legacy `OpenPhone-Signature` header rejects every new delivery. See [Validate webhook signatures](https://www.quo.com/docs/2026-03-30/webhooks-signature-validation.md).

Your endpoint continues to receive legacy deliveries until you switch. Accept both formats at the same URL, or give the new webhook a different URL.

## Migrate an app webhook

**1. Create a replacement**

In **Settings → Webhooks**, open the webhook and click **Duplicate as new webhook**. A create form opens with the URL, label, events, and phone number filters of the original webhook. Review the form, then create the replacement. It starts disabled and has a new signing secret. Contact events are workspace-wide, so Quo drops member and group filters on them.

**2. Test your endpoint**

On the details page of the replacement, send a test event for each event type that you subscribe to.

**3. Enable the replacement**

Disable the original webhook, then enable the replacement immediately. Quo does not let you enable the replacement while the original is enabled. Events that occur between the two steps are not delivered.

To roll back, disable the replacement, then enable the original.

## Migrate a v1 API webhook

**1. Find your legacy webhooks**

Call `GET /v1/webhooks` to get the URL, events, and `resourceIds` of each webhook. You can combine webhooks that send to the same URL into one new webhook.

**2. Create the replacement, disabled**

```bash theme={null}
curl https://api.quo.com/webhooks \
  -X POST \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Quo-Api-Version: 2026-03-30" \
  -d '{
    "url": "https://example.com/webhooks/quo",
    "events": ["message.received", "call.completed"],
    "resourceIds": ["PN123"],
    "status": "disabled"
  }'
```

Keep the `key` field from the response. It is the new signing secret.

**3. Test your endpoint**

For each event type that you subscribe to, send a test event with [`POST /webhooks/:id/events/test`](https://www.quo.com/docs/2026-03-30/webhook-events/send-a-test-event-to-a-webhook). Put the event type in `eventType`, for example `{ "eventType": "message.received" }`.

Quo sends a signed request with sample data to your URL. Make sure that your endpoint verifies the signature and returns a `2xx` response. `GET /webhooks/:id/events` shows each test delivery and the response from your endpoint.

**4. Switch to the replacement**

> [!WARNING]
>
> Do not delete the legacy webhook until your tests pass. You cannot restore a deleted v1 webhook.

Delete the legacy webhook, then enable the replacement immediately. Events that occur between the two calls are not delivered.

```bash theme={null}
curl https://api.quo.com/v1/webhooks/{legacyId} \
  -X DELETE \
  -H "Authorization: YOUR_API_KEY"

curl https://api.quo.com/webhooks/{id} \
  -X PATCH \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Quo-Api-Version: 2026-03-30" \
  -d '{ "status": "enabled" }'
```
