REST API

Everything the browser does goes through the server’s REST API, so other programs can use it too, for example to import annotations or read the statistics.

Basics

  • All routes are under /api; requests and answers are JSON. folder and name are query parameters.

  • Everything except GET /api/status and the sign-in routes needs a session: sign in with POST /api/auth/login and send the session cookie with every request.

  • Changing requests (POST, PUT, DELETE) need the header X-Requested-With: lsa.

  • The user is always the signed-in one. Routes about images, settings, history and notes take project=<id> (default: the only project the user takes part in, else default).

  • Errors: {"error": "<code>", "message": "<text>"} with the HTTP status (400 bad request, 401 not signed in, 403 role missing, 404 not found, 409 conflict, 423 locked).

curl -c cookies.txt -H "X-Requested-With: lsa" -H "Content-Type: application/json" \
     -d '{"username":"anna","password":"..."}' https://annotation.example.com/api/auth/login
curl -b cookies.txt "https://annotation.example.com/api/images?project=line-5&folder=2026-10-28"

Routes

Role in brackets: Admin is the server admin; the other roles are the user’s roles in the project.

Sign-in and users

Method and path Purpose

GET /status

Version, licence state (public)

GET /auth/providers

Which sign-in methods are offered (public)

POST /auth/login

{username, password}: local account, then directory → session cookie

GET /auth/oidc/start, /auth/oidc/callback

Single sign-on (browser redirects)

POST /auth/logout

End the session; returns the provider’s logout address for single sign-on sessions

GET /auth/me

The signed-in user and their roles

POST /auth/password

{current, password}: change the own password (local accounts)

GET/POST /admin/users, PUT/DELETE /admin/users/<name>, POST /admin/users/<name>/password

User management (Admin)

GET/PUT /admin/mappings

Group → role mappings (Admin)

GET /admin/auth, POST /admin/auth/test-ldap

Configured sign-in methods, test a directory sign-in (Admin)

GET/POST /admin/backups, GET /admin/backups/<file>

List, make and download backups (Admin)

Projects

Method and path Purpose

GET /projects

Projects the user takes part in, with their roles; for admins also the S3 targets

POST /projects

{name, description, folder?, storage?, prefix?, openToAll}: new project (Admin)

GET/PUT /projects/<id>

Details; name, description, open to all, members (Project admin)

DELETE /projects/<id>

{deleteFiles}: remove the project (Admin)

GET /projects/<id>/export[?history=0]

The project file (tar) (Admin)

POST /projects/import, PUT /projects/import/<upload>?offset=, POST /projects/import/<upload>/finish

Upload a project file in pieces and unpack it as a new project (Admin)

GET /people

People with a role in the project (to address notes)

Images and annotations

Method and path Purpose

GET /folders

Sub-folders of the project

GET /images?folder=

Images with annotated and locked state and open notes; with several annotators also the counts and review state

GET /image?folder=&name=

The image (PNG)

GET /annotations?folder=&name=[&layer=annotator]

Boxes, image size, revision, lock. layer=annotator: your own version

PUT /annotations?folder=&name=[&layer=annotator]

Save {session, baseRevision, boxes, force?} → 409 on conflict, 423 if locked

POST/DELETE /lock?folder=&name=[&layer=annotator]

Take, renew or release the edit lock ({session})

DELETE /image?folder=&name=

Delete an image with its files, versions, history and notes (Project admin)

POST /geometry/fit-box

Smallest oriented box around {points: [[x, y], …]}

A box is {"cx": 412.3, "cy": 267.8, "width": 188.0, "height": 71.4, "angle": -0.385, "label": "bracket", "metadata": null} (angle in radians).

History, notes, settings

Method and path Purpose

GET /history?folder=&name=[&layer=annotator&owner=], GET /history/version?id=

Saved versions of an annotation; one version with its boxes

GET /notes?folder=&name=, GET /notes/open[?mine=1]

Revision notes of an image; open notes of the project

POST /notes, PUT/DELETE /notes/<id>

{folder, name, text, assignee, x?, y?}; {status, reply, text}; delete (author or Project admin)

GET /settings, PUT /settings

Project settings (changing: Project admin)

POST /labels

Add a label to the shared list (Annotator, Reviewer)

Review and suggestions

Method and path Purpose

GET /compare?folder=&name=

All annotators' boxes, matched objects and differences (Reviewer)

GET /statistics[?folder=]

Agreement statistics for a folder or the project (Reviewer)

POST /preannotate?folder=&name=

Box suggestions; body {boxes?, labels?}; 501 without a service, 502 if none answers

GET /preannotate/services

The box suggestion services, their backends and networks