Changelog
An integrator's first question about any API is whether it will move under them. This is the answer. Breaking changes get a new version prefix; everything below is additive unless it says otherwise.
September 2026
Scoped access tokens
addedv1
Integration tokens now carry an explicit list of abilities and an expiry you choose, managed under Settings → Access tokens.
Every endpoint now states the scope it needs, and a token that lacks it gets a 403 naming the missing scope rather than a silent no-op.
Existing tokens are unaffected. Device tokens minted by the capture app hold the single capture ability, as before, which maps to exactly the endpoints the app uses and no further.
Session requests — the office dashboard — carry no abilities and are unchanged. Their permissions are the user's role and the policies, as they always were.
Tasks, pages and customers on the API
addedv1
Three new resources, all following the existing conventions.
GET /tasks,POST /tasks,PATCH /tasks/{task},DELETE /tasks/{task}—
work raised on site, optionally pointing at the photo that shows the problem.
GET /pages,GET /pages/{page},POST /pages,PATCH /pages/{page}—
the written record for a job. Returned both as Markdown source and as already-escaped HTML.
GET /customers,GET /customers/{customer},POST /customers— the
office's customer list.
New scopes: tasks:read, tasks:write, pages:read, pages:write, customers:read, customers:write.
Rate limiting, with a separate bucket for uploads
addedv1
Uploads are limited independently of the rest of the API, so a device draining a large offline backlog cannot lock the office out of the endpoints it is using at the same time.
Limits are config values on the buyer's own install — see config/trace.php.
Webhook payloads match the REST resource exactly
changedv1
A webhook's data block is now byte-for-byte the resource the REST API returns. Previously a photo arrived with url and thumb_url at the top level, while GET /photos/{id} nested them under urls.
If you parse both surfaces, you can now delete one of your two parsers. If you only consume webhooks, update the paths: url → urls.full, thumb_url → urls.thumb.
August 2026
Video capture through the same queue
addedv1
POST /photos accepts video. The response carries media_type and, where known, duration_seconds and a poster URL.
Video rides the same offline queue, retry schedule and GPS matching as a photograph. Only the file and the playback differ.
July 2026
API v1
addedv1
First public release. Projects, photos, before-and-after pairs, checklists, comments and reports, plus signed webhooks.