# Keep your orders in sync

This guide keeps a copy of your orders in your own system, up to date within about a minute, without losing changes.

## The design

1. **Webhooks for speed.** Subscribe an endpoint to `order.status_changed` and `order.awaiting_payment`. For each event, fetch the order with [`GET /v1/orders/{id}`](https://docs.rephut.com/developers/reference/orders#get-an-order) and save it.
2. **Polling as a safety net.** Every so often (for example every quarter of an hour), run the [Incremental sync](https://docs.rephut.com/developers/incremental-sync) recipe with `updatedSince`. It catches anything a webhook missed, such as events from while your endpoint was down.
3. **One way to save.** Both paths save the order by `id` and overwrite your copy with what `GET` returned. Because the copy always comes from `GET`, order and duplicates don't matter.

## Handling an event

```js
// Called by your queue worker with the event body your receiver stored (see the Webhooks pages).
async function handleOrderEvent(event, saveOrder) {
  const response = await fetch(`https://api.rephut.com/v1/orders/${event.data.id}`, { headers: { Authorization: `Bearer ${process.env.FULFILLBOT_API_KEY}` } });
  if (response.status === 404) return; // The order is no longer yours.
  if (!response.ok) throw new Error(`HTTP ${response.status}`); // Let the queue retry later.
  const { data } = await response.json();
  await saveOrder(data);
}

export { handleOrderEvent };
```

## Things that trip people up

- Lists are sorted by creation time, so an old order that changed is on a later page. Always read every page of an `updatedSince` query.
- Watch your read limit (120 a minute). Fetching an order per event is one read; a busy store can batch events and fetch each order once.
- New orders created in the portal, from a file or by your store also send `order.status_changed`.
