Skip to main content
This page takes you from a new API key to a paginated list of orders. Every example runs on your server, never in a browser.

Before you start

  • An API key with the scopes clinics:read, catalog:read and orders:read. See Authentication for how to get one.
  • One of: curl, Node.js 18 or later (it includes fetch), or Python 3 with the requests package (pip install requests).
  • The JavaScript examples use top-level await: save them in a file ending in .mjs.

Steps

1

Put the key in an environment variable

Never write the key in your code. Export it in the shell (or load it from your secret manager):
All the examples below read MUVEYA_API_KEY and call https://api.muveya.com.
2

Identify the key

GET /v1/me needs no scope. It tells you which dental clinic the key reads and which scopes it holds.
Response
A 401 with api_keys.invalid means the header or the key is wrong. See Authentication failures.
3

List your locations

GET /v1/clinics (scope clinics:read) returns every location of the dental clinic in one page. GET /v1/warehouses works the same way for warehouses.
Response
Keep a map of clinicId to name: orders and analytics refer to locations by id.
4

List catalog items

GET /v1/catalog/items (scope catalog:read) returns every catalog item, whatever its status, in one page.
Response
This key has no catalog.cost:read, so the cost fields are absent. With that scope, each item also carries costStatus and, when a cost is recorded, cost, currency and costMeasurement. Check costStatus before using an amount: see Catalog costs.
5

Read an order

Take an orderId from GET /v1/orders and read it with GET /v1/orders/{orderId} (scope orders:read). The detail includes the lines and the approval plan.
Response
The order value and the patientRef of a clinical order are never returned on /v1. An order of another dental clinic, or an id that does not exist, answers 404 with the code orders.not_found.
6

Walk through pages

GET /v1/orders is paginated. Ask for up to 200 orders per page, and pass nextCursor back as cursor while hasMore is true. Send the same filters with every page.
First page
Orders come oldest first. The cursor is opaque: do not decode or build it. See Pagination for every rule.

Handle errors and limits

Two habits make an integration robust from day one:
  1. Branch on code, not on text. Every error is a problem document with a stable code and a requestId. Log both. See Errors.
  2. Respect the rate limit. Each key has a budget of requests per minute. On a 429, wait the number of seconds in Retry-After and try again. See Rate limits.

Next steps

Choose scopes

Least-privilege recipes for common integrations.

Export the briefing

Request a CSV, poll it and verify its checksum.

Stay in sync without webhooks

Polling recipes for orders, deliveries and stock.

Connect an AI assistant

MCP uses a separate OAuth sign-in and authorization flow.