# Lupa > Lupa is a veterinary practice management platform. This is the developer > portal for its public REST API, which covers clients, pets, appointments, > clinical records, invoices and inventory for veterinary practices. Requests authenticate with a bearer API key issued by a practice administrator from inside Lupa. Every key acts as an employee of the practice and can never do more than that employee can in Lupa: it reaches only that employee's companies and stores, and each endpoint needs the same permissions as the matching action in the staff app. Keys are read only or read & write; a read only key can call GET endpoints and POST searches, and any other write returns 403. Every endpoint except `GET /v1/companies` requires a `companyId`: as a query parameter on GET and DELETE, and inside the JSON body on POST, PUT and PATCH. The OpenAPI document is authoritative for where each endpoint takes its input. The API is served from `https://api.lupapets.com/api/external`. List endpoints are cursor-paginated and return `data`, `nextCursor`, `hasMore` and `totalCount`. Rate limit is 100 requests per minute per key. ## Docs - [Quick start](https://developers.lupapets.com/guide): getting from an API key to a booked appointment — authentication, finding your companyId, cursor pagination, date filtering, enums, error handling and rate limits, with runnable cURL for every step - [MCP server](https://developers.lupapets.com/mcp): connecting Claude, Cursor or any MCP client to Lupa — credentials, the permission model, the tool set, and how to discover and safely run any operation - [Access & permissions](https://developers.lupapets.com/permissions): how REST and MCP requests are authorised — the acting employee, company and store scope, read only and read & write keys, employee permissions, the extra MCP permissions, what each 401, 403 and 404 means, and step-by-step instructions for creating a key and giving it the right permissions in Lupa - [API reference](https://developers.lupapets.com/docs): every endpoint, parameter, response field and error code, rendered from the OpenAPI document ## Machine-readable - [OpenAPI document](https://api.lupapets.com/api/openapi.json): the full OpenAPI 3.0 spec — generate a typed client from this rather than hand-writing one - [API llms.txt](https://api.lupapets.com/api/llms.txt): endpoint-level summary of the API written for models, including the full endpoint list, common workflows and the error format - [MCP endpoint](https://api.lupapets.com/api/mcp): Streamable HTTP MCP server; authenticate with a Lupa API key or a pre-registered OAuth client ## Notes - Enum values are served by the API itself at `GET /v1/enums` and `GET /v1/enums/{enumName}`. Treat those as the source of truth rather than hardcoding values. - There is no official SDK. The quick start uses cURL so it runs anywhere. - Errors return `type: "LUPA_ERROR"`, a stable `message` key, and a `data` object carrying `httpStatus`, a human-readable `suggestion`, and an `errorInstanceId` to quote in support requests. ## Optional - [Lupa](https://lupapets.com): the product site