Files — API Reference
Open folders, import, export and convert, move, rename and trash pictures, and the jobs that run them.
Open folders, import, export and convert, move, rename and trash pictures, and the jobs that run them.
53 operations. Generated from the application's own OpenAPI document.
GET /api/batch-jobs
Running jobs
curl -X GET http://127.0.0.1:9100/api/batch-jobs \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The batch jobs the progress panel shows: the auto-crop batch, the denoise batch, a folder moving to another disk
DELETE /api/batch-jobs/{kind}
Stop job
| Parameter | In | Type | Description |
|---|---|---|---|
kind | path | string | auto_crop | denoise | folder_move |
curl -X DELETE http://127.0.0.1:9100/api/batch-jobs/<kind> \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Stopping, as the progress panel's × does (a folder move deletes nothing it has not finished copying)400— Not a batch job404— None of that kind is running
POST /api/batch-rename
Batch rename
Body
| Field | Type | Required | Description |
|---|---|---|---|
start_number | number | ||
template | string | yes | New file name without extension, in the variables import and export use: `{original}`, `{image_date}`/`{image_time}` (capture), `{date}` (today), `{camera}`, `{seq}`/`{seq:N}` (counting from start_number). |
curl -X POST http://127.0.0.1:9100/api/batch-rename \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"template":"text"}'
Responses
200— Batch rename images
POST /api/contact-sheet
Export contact sheet
curl -X POST http://127.0.0.1:9100/api/contact-sheet \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Contact-sheet PDF export started400— No images loaded
POST /api/convert-dng
Convert to DNG
Body
| Field | Type | Required | Description |
|---|---|---|---|
indices | number[] | Image indices to move to trash. If empty/absent, current image is used. |
curl -X POST http://127.0.0.1:9100/api/convert-dng \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"indices":[0]}'
Responses
200— DNG conversion started400— No RAW files in selection
GET /api/editors
External editors
curl -X GET http://127.0.0.1:9100/api/editors \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— List configured external editors
GET /api/editors/detected
Detected editors
curl -X GET http://127.0.0.1:9100/api/editors/detected \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The programs on this machine the external-editor list can pick, as Settings → Launching finds them
POST /api/export
Export
curl -X POST http://127.0.0.1:9100/api/export \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Export selection (or all visible) using an export profile
POST /api/export-gallery
Export HTML gallery
curl -X POST http://127.0.0.1:9100/api/export-gallery \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— HTML gallery export started400— No images loaded
GET /api/export/profiles
Export profiles
curl -X GET http://127.0.0.1:9100/api/export/profiles \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Every saved export profile
POST /api/export/profiles
Save export profile
curl -X POST http://127.0.0.1:9100/api/export/profiles \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Saved400— No name, an unknown field or a value of the wrong type
DELETE /api/export/profiles/{name}
Delete export profile
| Parameter | In | Type | Description |
|---|---|---|---|
name | path | string | The preset's name |
curl -X DELETE http://127.0.0.1:9100/api/export/profiles/<name> \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Deleted404— None by that name
POST /api/export/quick-jpeg
Quick export JPEG
Body
| Field | Type | Required | Description |
|---|---|---|---|
output_dir | any |
curl -X POST http://127.0.0.1:9100/api/export/quick-jpeg \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"output_dir":null}'
Responses
200— Quick JPEG export
GET /api/export/status
Export status
curl -X GET http://127.0.0.1:9100/api/export/status \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Export progress status
POST /api/export/visible
Export visible
curl -X POST http://127.0.0.1:9100/api/export/visible \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Export all visible images using an export profile
POST /api/folders/clear-cache
Clear folder cache
Body
| Field | Type | Required | Description |
|---|---|---|---|
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/clear-cache \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text"}'
Responses
200— The folder's cached previews are gone; an open folder is read again400— No cache is set up
POST /api/folders/close
Close folder
curl -X POST http://127.0.0.1:9100/api/folders/close \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The open folder is closed400— No folder is open
GET /api/folders/favorites
Favorite folders
curl -X GET http://127.0.0.1:9100/api/folders/favorites \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The folder tree's favourites
POST /api/folders/favorites
Add to favorites
Body
| Field | Type | Required | Description |
|---|---|---|---|
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/favorites \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text"}'
Responses
200— Added to the favourites; the list as it is now400— Not a folder
POST /api/folders/favorites/remove
Remove from favorites
Body
| Field | Type | Required | Description |
|---|---|---|---|
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/favorites/remove \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text"}'
Responses
200— Off the favourites; the list as it is now
POST /api/folders/move
Move folder
Body
| Field | Type | Required | Description |
|---|---|---|---|
dest_parent | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/move \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text","dest_parent":"text"}'
Responses
200— Moved (on one disk), or the copy started (across disks: the original is removed only when every file has arrived)400— No such folder, into itself, the name is taken there, or a move is already running
POST /api/folders/move-pictures
Move pictures to folder
Body
| Field | Type | Required | Description |
|---|---|---|---|
dest | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
indices | number[] | Rows to move; empty is the current picture. Sidecars and audio notes go along. | |
on_conflict | "overwrite" | "skip" | The conflict policy: overwrite, skip |
curl -X POST http://127.0.0.1:9100/api/folders/move-pictures \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dest":"text"}'
Responses
200— Moved, as dropping them on a folder does400— No such folder, or nothing to move409— Pictures of those names are there already and on_conflict was left out; nothing moved
GET /api/folders/pictures
Pictures in a folder
| Parameter | In | Type | Description |
|---|---|---|---|
path | query | string | The folder. |
curl -X GET http://127.0.0.1:9100/api/folders/pictures \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The pictures in the folder, by name (not its subfolders)400— Not a folder
GET /api/folders/recent
Recent folders
curl -X GET http://127.0.0.1:9100/api/folders/recent \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The recent folders, newest first
POST /api/folders/recent/remove
Remove from recent
Body
| Field | Type | Required | Description |
|---|---|---|---|
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/recent/remove \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text"}'
Responses
200— Off the recent folders; the list as it is now
POST /api/folders/rename
Rename folder
Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | The new name, no path. |
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/rename \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text","name":"text"}'
Responses
200— Renamed, as Rename… does; an open folder, favourites and recent folders follow400— No such folder, not a folder name, or the name is taken
POST /api/folders/reveal
Reveal folder in Finder
Body
| Field | Type | Required | Description |
|---|---|---|---|
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/reveal \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text"}'
Responses
200— Shown in Finder (Explorer on Windows)400— Nothing at that path
POST /api/folders/subfolder
New subfolder
Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | One folder name, no path. |
parent | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/subfolder \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"parent":"text","name":"text"}'
Responses
200— Made, as New Subfolder… does400— No parent folder, not a folder name, or it is there already
POST /api/folders/trash
Move folder to trash
Body
| Field | Type | Required | Description |
|---|---|---|---|
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/folders/trash \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text"}'
Responses
200— In the Trash, as Move to Trash… does; it can be put back from there400— No such folder, or the Trash refused it
DELETE /api/images
Move to trash
Body
| Field | Type | Required | Description |
|---|---|---|---|
indices | number[] | Image indices to move to trash. If empty/absent, current image is used. |
curl -X DELETE http://127.0.0.1:9100/api/images \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"indices":[0]}'
Responses
200— Images moved to trash400— Invalid indices
POST /api/images/copy-files
Copy pictures as files
Body
| Field | Type | Required | Description |
|---|---|---|---|
indices | number[] | Pictures to copy, by index. Empty or absent: the selection, or the current picture when nothing is selected. |
curl -X POST http://127.0.0.1:9100/api/images/copy-files \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"indices":[0]}'
Responses
200— The files, with their sidecars, are on the clipboard400— Nothing to copy, a picture on a disk that is not connected, or the clipboard refused
POST /api/import
Import
Body
| Field | Type | Required | Description |
|---|---|---|---|
dest_path | string | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). | |
iptc_template | string | Name of a saved IPTC template written into every picture, as the dialog's **Apply IPTC template** does; `""` for none. Omitted: the one the dialog opens with (the last used). | |
preset | string | Name of a saved import preset (Import dialog → Presets). Omitted: the one the dialog opens on (the last used, else the defaults). | |
source_path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/import \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"source_path":"text"}'
Responses
200— The import started; follow it on GET /api/import/jobs or the `import_finished` event400— No source folder, no pictures in it, no destination, or no such preset
GET /api/import/camera-destinations
Camera destinations
curl -X GET http://127.0.0.1:9100/api/import/camera-destinations \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Where an import from each camera model goes
PUT /api/import/camera-destinations
Set camera destinations
Body
| Field | Type | Required | Description |
|---|---|---|---|
destinations | object | yes | Camera model → destination folder. |
curl -X PUT http://127.0.0.1:9100/api/import/camera-destinations \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"destinations":{}}'
Responses
200— The destinations are replaced
GET /api/import/cards
Cards
curl -X GET http://127.0.0.1:9100/api/import/cards \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The camera cards mounted now (a volume with a DCIM folder), as the Import dialog finds them
GET /api/import/jobs
Imports
curl -X GET http://127.0.0.1:9100/api/import/jobs \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Every import this session, running and finished, as the import panel shows them
DELETE /api/import/jobs/{id}
Cancel import
| Parameter | In | Type | Description |
|---|---|---|---|
id | path | number | The import's `job` |
curl -X DELETE http://127.0.0.1:9100/api/import/jobs/<id> \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Cancelled, as the import panel's Cancel does: what was copied stays, the card is not erased404— No such import409— It has finished
POST /api/import/jobs/{id}/dismiss
Dismiss import
| Parameter | In | Type | Description |
|---|---|---|---|
id | path | number | The import's `job` |
curl -X POST http://127.0.0.1:9100/api/import/jobs/<id>/dismiss \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Off the list, as the progress panel's × does404— No such import409— It is still running
POST /api/import/jobs/{id}/eject
Eject card
| Parameter | In | Type | Description |
|---|---|---|---|
id | path | number | The import's `job` |
curl -X POST http://127.0.0.1:9100/api/import/jobs/<id>/eject \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Ejecting the card it copied from400— Its card is not mounted404— No such import409— It has not completed
GET /api/import/presets
Import presets
curl -X GET http://127.0.0.1:9100/api/import/presets \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Every saved import preset
POST /api/import/presets
Save import preset
curl -X POST http://127.0.0.1:9100/api/import/presets \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Saved400— No name, an unknown field or a value of the wrong type
DELETE /api/import/presets/{name}
Delete import preset
| Parameter | In | Type | Description |
|---|---|---|---|
name | path | string | The preset's name |
curl -X DELETE http://127.0.0.1:9100/api/import/presets/<name> \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Deleted404— None by that name
POST /api/jpeg-tool
JPEG tool
Body
| Field | Type | Required | Description |
|---|---|---|---|
dpi | number | Target DPI for op = "dpi" (default 300). | |
indices | number[] | Image indices; empty/omitted = the current image. | |
op | "mirror_h" | "mirror_v" | "trim" | "extract" | "dpi" | yes | The jpeg op: mirror_h, mirror_v, trim, extract, dpi |
curl -X POST http://127.0.0.1:9100/api/jpeg-tool \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"op":"mirror_h"}'
Responses
200— JPEG tool applied400— No images / unknown op
POST /api/open
Open folder
Body
| Field | Type | Required | Description |
|---|---|---|---|
path | string | yes | A path. In an instance started with `--dir` it is in the instance's root: `/` is the root, and a path that leads out of it is refused (403). |
curl -X POST http://127.0.0.1:9100/api/open \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"text"}'
Responses
200— The folder opened, or the picture's folder on it400— Not a folder or a file, or nothing in it the app reads
POST /api/open-in-editor
Open in external editor
curl -X POST http://127.0.0.1:9100/api/open-in-editor \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Opened in the external editor400— No editor configured, or no images loaded
POST /api/quarantine-rejects
Quarantine rejected pictures
curl -X POST http://127.0.0.1:9100/api/quarantine-rejects \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Rejected images quarantined (reversible)400— No rejected images, none could be moved, or no images loaded
POST /api/reveal-in-finder
Reveal in Finder
curl -X POST http://127.0.0.1:9100/api/reveal-in-finder \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Reveal the current image in the system file manager
GET /api/source
What is open
curl -X GET http://127.0.0.1:9100/api/source \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The folder, album, saved search or library search the window works on, and the folders its pictures are in
POST /api/source
Open
curl -X POST http://127.0.0.1:9100/api/source \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Opened: every action and the current-picture routes now work on its pictures400— No such folder, album or saved search, or no pictures in it
POST /api/source/order
Reorder album
Body
| Field | Type | Required | Description |
|---|---|---|---|
before | any | ||
files | string[] | yes | Pictures of the open album, by path, in the order they go. |
curl -X POST http://127.0.0.1:9100/api/source/order \
-H "Authorization: Bearer $CULLING_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"files":["text"]}'
Responses
200— The pictures stand before the one named in the open album's own order, kept with the album — what dragging them in the grid does400— What is open is not an album
POST /api/undo-quarantine
Undo quarantine
curl -X POST http://127.0.0.1:9100/api/undo-quarantine \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— The last quarantine put back, as Edit → Undo does when it was the last step400— Nothing to un-quarantine, or a later step comes first
POST /api/virtual-copies
Create virtual copy
curl -X POST http://127.0.0.1:9100/api/virtual-copies \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Create a virtual copy of the current image
DELETE /api/virtual-copies
Delete virtual copy
curl -X DELETE http://127.0.0.1:9100/api/virtual-copies \
-H "Authorization: Bearer $CULLING_API_TOKEN"
Responses
200— Delete the current virtual copy