Skip to content

The REST API

Needs module.integrations. Authenticated with an API key.

GET https://helpdesk.yourschool.org/api/v1/ping
Authorization: Bearer pb_live_...

Every request carries the key as a bearer token. There is no session, no cookie and no ambient administrator.

The key’s scopes determine what it can do, using the same permission set as roles. A key without device.view gets a 403 from the devices endpoint.

MethodPathReturnsNeeds
GET/api/v1/pingA liveness response, and confirmation the key worksAny valid key
GET/api/v1/devicesDevicesdevice.view
GET/api/v1/submissionsSubmissionsrepair.view

ping is the first call to make with a new key. It confirms the key is valid and the module is enabled, without needing any particular scope.

Every request runs inside the key’s tenant. There is no cross-tenant access and no parameter that would grant it.

For local development or a client that reaches the API by an address that does not identify the tenant, x-tenant-slug resolves it. See how it fits together.

Standard HTTP status codes.

CodeMeans
401Missing or invalid key
403The key lacks the permission for this endpoint
404The module is not enabled, or the record does not exist
429Rate limited

A 404 on an endpoint you expect to exist is usually the module being off rather than a wrong path. Check Admin, Features.

Requests are rate limited per key. Back off on a 429 rather than retrying immediately.

The REST surface is deliberately small. The richer interface is the MCP server, which exposes the whole desk tool catalogue over JSON-RPC with the same key and the same permission checks:

Tool
people.search, people.profileFind somebody, see their loans, devices and submissions
loans.list, loans.issue, loans.returnThe loan desk
submissions.list, submissions.get, submissions.create, submissions.assignTickets and repairs
devices.searchThe asset register
costs.breakdownSpend by type, coverage or period

MCP is designed for AI clients but it is ordinary JSON-RPC over HTTP, so anything that can make an HTTP request can use it.

Do not poll. Register an outbound webhook and receive signed callbacks when things happen.

For a browser client, the realtime event stream is the same events over server-sent events.

Every action taken with a key is written to the audit log, attributed to the key. Nothing is exempt.

The path carries the version. A breaking change means a new version rather than a change under /v1.