Skip to main content
An event is a short note saying that something changed at a clinic: an item’s stock band moved from in_stock to low, a catalogue item was edited, a pharmacy’s till stopped reporting. An event says what changed and where. It never carries the record itself. When you get one, you read the record to see the new state. There are two ways to receive events:
  • Webhooks push each event to an address you register. This is the normal way. See Verifying a webhook’s signature for how to trust a delivery, and Webhooks in the developer portal to add an address.
  • The change feed (this page) lets you ask for events yourself. Use it to catch up after your endpoint was down, or to check that you have not missed one.
You do not need both, but most integrations use the feed as a safety net behind webhooks. The same catch-up idea is explained alongside duplicate handling in Retries and duplicates.

Read the feed

This route does not use the cursor paging described on Pagination. There is no starting_after, no has_more and no next_cursor. You page with after_seq and next_after, as shown below.

Event types

listing.freshness.changed means the clinic’s till has stopped (or started again) reporting stock. It is sent once per clinic when that changes, not once per item. When it goes stale, bands for that clinic’s items are unknown until the till reports again. See Stock bands. An inventory.availability.changed event is sent when an item’s band changes, never for every unit sold.

Catching up

Keep the highest seq you have processed. After an outage, ask for everything after it, and keep asking until next_after stops moving:
Because the same event can reach you by webhook and through the feed, process each one once: remember the seq you last handled and skip anything at or below it. Handling an event twice should be harmless anyway, because every event only tells you to go and read the current state.

Things to know

  • You only see event types your key may see. An event appears only if your key currently holds the permission in the table above. If a permission is removed, events that needed it stop appearing, even ones recorded earlier.
  • Events are kept for 30 days. The feed is for catching up after a short outage, not a permanent history. If you were away longer, read the records themselves.
  • A clinic only has events once someone is listening. Events are recorded for a clinic while it has a webhook address registered, or an organization with a webhook address is connected to it. A clinic with neither has an empty feed, and the feed does not fill in changes from before a listener existed.
  • Read the record, not the event. data is deliberately small. Use subject_id to fetch the item (see Inventory) and get its current state.
  • Reading the feed counts as a request, like any other read. It uses your per-minute limit and, for an organization, your monthly allowance. Deliveries to your webhook address are not counted. See Rate limits and Usage and billing.
  • Errors. A clinic your key cannot reach returns 404 with code: "not_found". A bad after_seq or limit returns 400 with code: "invalid_request". A test key asking for a real clinic returns 403 with code: "sandbox_only". See Errors.

Recipes

Keep an availability cache fresh. Register a webhook address for inventory.availability.changed. On each event, read the item and update your copy. Once an hour, and after any outage, call the feed with your last seq to catch anything a delivery missed. Notice a pharmacy going quiet. Watch for listing.freshness.changed with "stale": true. Show that pharmacy’s availability as unknown until you see the same event with "stale": false.

See also