> For the complete documentation index, see [llms.txt](https://docs.omni.integratedcommerce.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.omni.integratedcommerce.io/webhooks/svix/moving-from-legacy.md).

# Moving from legacy to Svix

Register on Svix while legacy deliveries continue, accept both signatures, deduplicate, then retire the legacy registration.

Once Fiska has enabled Svix for your account, your legacy endpoints keep working. Nothing is switched over for you: you register endpoints on Svix, and for as long as the legacy registration also exists, every event is delivered twice - once with the `x-fsk-wh-chksm` checksum and once with the `svix-*` headers. This is expected, not a fault, and it lets you verify Svix handling against live traffic before anything is removed.

{% hint style="warning" %}
Svix webhooks are invite only. If Fiska has not enabled Svix for your account, there is nothing to move to yet - see [Requesting access](/webhooks/svix.md#requesting-access).
{% endhint %}

## Step by step

{% stepper %}
{% step %}

## Register your endpoint in the partner portal

Add the URL and subscribe it to the event types you handle. See [Configuring endpoints](/webhooks/svix/configuration.md).
{% endstep %}

{% step %}

## Verify Svix signatures alongside the legacy checksum

Make your handler accept either signature scheme, keyed on which headers are present. See [Handling both](#handling-both) below.
{% endstep %}

{% step %}

## Deduplicate on event ID

You will receive every event twice while both registrations exist. See [Deduplicate on event.id](/webhooks/webhooks.md#deduplicate-on-event-id).
{% endstep %}

{% step %}

## Ask support to retire the legacy registration

Once you have observed Svix deliveries arriving and verifying correctly, contact <support@integratedcommerce.io> to remove the legacy configuration. After that, you can delete the legacy verification branch.
{% endstep %}
{% endstepper %}

## Handling both

While your endpoint is registered on both delivery methods, branch on which headers are present:

```javascript
app.post("/webhooks", express.raw({ type: "application/json" }), (req, res) => {
  let ok;
  if (req.header("svix-signature")) {
    ok = verifySvix(req);          // see Verifying signatures
  } else if (req.header("x-fsk-wh-chksm")) {
    ok = verifyLegacy(req.body, req.header("x-fsk-wh-chksm"));   // see Verifying the checksum
  } else {
    ok = false;                    // unsigned: reject
  }
  if (!ok) return res.sendStatus(400);

  const event = JSON.parse(req.body);
  if (alreadyProcessed(event.event.id)) return res.sendStatus(202);

  res.sendStatus(202);
  enqueue(event);
});
```

`verifySvix` is the check from [Verifying signatures](/webhooks/svix/verifying-signatures.md); `verifyLegacy` is the check from [Verifying the checksum](/webhooks/legacy/verifying-the-checksum.md). A request with neither set of headers is unsigned and must be rejected. Once support confirms the legacy registration is removed, delete the legacy branch.

{% hint style="info" %}
Use the same URL for both registrations only if you want to. Registering a new URL on Svix and leaving the legacy URL untouched also works, and keeps the two handlers apart. Deduplicate on `event.id` either way, because the same event still reaches both.
{% endhint %}

## What does not change

* The event payload and the [event catalog](/webhooks/events.md) are identical on both delivery methods.
* `event.id` is the same value on both for the same event.
* Your endpoint requirements - HTTPS, prompt `2xx`, idempotency - are the same.

## Related

* [Svix webhooks](/webhooks/svix.md)
* [Legacy webhooks](/webhooks/legacy.md)
