---
title: "REST API"
description: "REST API of the LumiScan Annotation Web server: sign-in, projects, images, annotations, locks, history, notes, settings, review and suggestions."
product: "LumiScan Annotation Web"
component: "lumiscan-annotation-web"
version: "2.4.0"
display_version: "2.4.0.0"
latest_version: false
language: "en"
url: "https://docs.hdvisionsystems.com/en/lumiscan-annotation-web/2.4.0/rest-api.html"
---

# REST API – LumiScan Annotation Web

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).

```bash
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, accepted image formats and the upload limit (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, their roles and `settings` (personal settings such as `language`) |
| `PUT /auth/settings` | `{language: "de"}`: save personal settings with the account; `null` removes one (the browser’s language applies again) |
| `GET /i18n` | Languages of the interface: `{languages: [{code, name, english}]}` (public) |
| `GET /i18n/<code>` | The translation table of a language, merged from the installed table and the `translations` folder (public; ETag) |
| `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, open notes, box count and labels of the reference annotation, the network’s uncertainty once rated, the export set (`set`), the done mark (`done`, `doneBy`, `doneAt`), for TIFF pages `file` and `page`; with several annotators also the counts and review state |
| `GET /image?folder=&name=` | The image: PNG, JPEG and BMP as stored, TIFF pages as PNG (a page is named `scan.tif#2`, URL-encoded `scan.tif%232`) |
| `PUT /image/done?folder=&name=` | `{"done": true}` or `false`: mark the image as done or remove the mark (Annotator, Reviewer) |
| `PUT /images/upload?folder=&name=` | Add an image file, sent as the body (`application/octet-stream`); `newFolder=1` creates the folder; larger files in pieces with `offset` (bytes so far) and `total` (file size). 409 `exists` if the name or its annotation file is taken (Project admin) |
| `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 |
| `POST /uncertainty/scan` | `{folder, includeAnnotated?, rescore?}`: the network rates the folder’s images in the background (Annotator) |
| `GET /uncertainty/status`, `POST /uncertainty/cancel` | Progress of the rating; stop it |
| `GET /training-export/preview` | What an export for LumiScan Training would contain; parameters `name`, `network`, `validation`, `test`, `together=1`, `folder` (repeatable), `nonRotable` (repeatable) (Reviewer) |
| `GET /training-export` | The export as a ZIP file, same parameters (Reviewer) |
| `GET /coco-export` | The COCO export, same parameters plus `format=zip` (images and annotations) or `format=json` with `set=all`, `train`, `val` or `test` (Reviewer) |
