14 Datasets
27 operations.
14.0.1 getCocoAutoMapperInfo
GET /api/coco-auto-mapper
Shows usage instructions for the annotation-import tool below.
Why it exists. † Describe how the COCO import expects to be called. A self-documenting response for an endpoint driven by hand rather than by the interface.
Unauthenticated — returns static self-documentation (usage, options, examples) for the COCO auto-mapper endpoint.
Authentication: none
Returns — message · description · usage · options · examples
Field names as the handler returns them; the source states no types for them.
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Usage documentation. |
14.0.2 mapCocoAnnotations
POST /api/coco-auto-mapper
Imports externally produced (COCO-format) annotations onto a dataset’s images by matching filenames.
Why it exists. † Match a COCO annotation file’s images to a dataset’s images by filename and import the annotations against them. Runs in analyse mode to report what it would match, or execute mode to write it.
Analyzes (default) or executes mapping of COCO images/annotations onto an existing dataset’s images, matching by exact filename and/or DJI-filename timestamp. Execute mode batch-inserts into coco_image_mappings and annotations with de-duplication; the caller must have RLS access to the dataset (404 otherwise), while the mapping itself runs with service-role privileges. Execute-mode failures are returned as 200 with success:false.
Authentication: CookieAuth, SupabaseAuth
Returns — not readable from the source: the handler returns a value assembled at run time rather than a literal.
Effect — writes (insert) annotation_categories · annotations · coco_image_mappings · datasets · images
Request body
| Field | Type | Required |
|---|---|---|
datasetId |
string | yes |
mode |
string — one of analyze, execute |
no |
mappingStrategy |
string — one of exact, timestamp, all |
no |
timestampPattern |
string | no |
batchSize |
integer | no |
cocoData |
object | no |
cocoFilePath |
string | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Analysis report (mode=analyze) or execution stats (mode=execute; failures also return 200 with success:false). | |
400 |
Missing datasetId or invalid mode. | Error |
401 |
Unauthorized. | Error |
404 |
Image or dataset not found, or outside the caller’s organizations. | Error |
500 |
COCO load failure or database error. | Error |
14.0.3 listDatasets
GET /api/datasets
Lists your datasets, optionally just those in one organization.
Why it exists. ‡ List the campaign datasets the caller may see, each carrying its image count and whether this caller may edit it, so the dataset browser can render the grid and disable controls without a second round trip.
Called by — app/(authenticated)/w/data-explorer/anomalies/map/page.tsx · components/create-note-dialog.tsx
Reached from — /w/data-explorer/anomalies/map · /w/data-explorer/insights
Retrieves all datasets for the current user, optionally filtered by organization.
Authentication: SupabaseAuth
Returns — not readable from the source: the handler returns a value assembled at run time rather than a literal.
Effect — reads datasets · images · organization_members · organizations
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
organization_id |
query | no | string (uuid) |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
List of datasets | Dataset |
400 |
Invalid organization_id. |
Error |
401 |
Not authenticated | Error |
500 |
Server error | Error |
14.0.4 createDataset
POST /api/datasets
Creates a new dataset.
Why it exists. † Register a dataset that already exists in a customer’s own object storage, recording where it lives and the credentials to reach it. Accepts a bearer token because it was built for callers outside the browser.
Creates a new dataset with the specified configuration.
Authentication: SupabaseAuth
Returns — not readable from the source: the handler returns a value assembled at run time rather than a literal.
Effect — writes (insert) datasets
Request body
| Field | Type | Required |
|---|---|---|
name |
string | yes |
description |
string | no |
organization_id |
string (uuid) | yes |
visibility |
string — one of private, organization |
no |
provider |
string — one of aws, azure, gcp |
yes |
storage_path |
string | yes |
credentials |
object | no |
Responses
| Status | Meaning | Body |
|---|---|---|
201 |
Dataset created successfully | Dataset |
400 |
Invalid request | Error |
401 |
Not authenticated | Error |
500 |
Server error | Error |
14.0.5 createDatasetAsAdmin
POST /api/datasets/create
Creates a dataset in one of your organizations (membership enforced by the database’s row rules).
Why it exists. † Insert a dataset row directly, bypassing row-level security. A minimal creation path kept for internal and scripted use; the tenant checks the ordinary create path performs are absent here.
Called by — app/datasets/create/page.tsx
Reached from — /datasets/create
Inserts the request body via the caller’s RLS-scoped client — the datasets INSERT policy requires ownership or membership of the target organization (403 otherwise). owner_id defaults to the caller; fields are not otherwise validated.
Authentication: CookieAuth, SupabaseAuth
Returns — data
Field names as the handler returns them; the source states no types for them.
Effect — writes (insert) datasets
Request body
| Field | Type | Required |
|---|---|---|
name |
string | no |
description |
string | no |
organization_id |
string | no |
provider |
string | no |
storage_path |
string | no |
credentials |
object | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Dataset created | Dataset |
400 |
Bad request | Error |
401 |
Unauthorized. | Error |
403 |
Forbidden — not a member of the target organization. | Error |
500 |
Server error | Error |
14.0.6 previewOnboardingBucket
POST /api/datasets/list-bucket
Previews the files inside an Azure storage container during onboarding (first 200 items).
Why it exists. ‡ List the containers available under a set of storage credentials, so the onboarding wizard can offer the customer a choice rather than asking them to type a container name.
Called by — modules/dataset-onboarding/services/onboarding-api.ts
Reached from — /w/data-explorer/new-dataset
Lists up to 200 media/data objects under an optional prefix in a caller-supplied Azure container, for the onboarding wizard preview. Credentials come from the request body and are not persisted. Azure only.
Authentication: CookieAuth
Returns — ok · files · truncated
Field names as the handler returns them; the source states no types for them.
Request body
| Field | Type | Required |
|---|---|---|
provider |
string — one of azure |
yes |
accountName |
string | yes |
accountKey |
string | yes |
containerName |
string | yes |
prefix |
string | no |
maxFiles |
no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Matching files (filtered to media/data extensions). | |
400 |
Missing storage fields. | Error |
401 |
Unauthorized. | Error |
422 |
Unsupported provider (only Azure). | Error |
500 |
Listing failed. | Error |
14.0.7 createDatasetFromOnboarding
POST /api/datasets/onboarding
Creates a dataset from the Data Explorer onboarding wizard, storing its Azure connection details.
Why it exists. ‡ Create a dataset from the storage-connection wizard once its credentials have been validated, so a customer can bring an existing image container into the platform in one step.
Called by — modules/dataset-onboarding/services/onboarding-api.ts
Reached from — /w/data-explorer/new-dataset
Creates a dataset row with Azure credentials embedded, for the Data Explorer onboarding wizard. Requires membership of the target organization. Azure only; indexing is queued, not performed inline.
Authentication: CookieAuth
Returns — ok · dataset
Field names as the handler returns them; the source states no types for them.
Effect — writes (insert) datasets
Request body
| Field | Type | Required |
|---|---|---|
name |
string | yes |
description |
string | no |
organization_id |
string (uuid) | yes |
provider |
string — one of azure |
yes |
account_name |
string | yes |
container_name |
string | yes |
account_key |
string | yes |
visibility |
string — one of private, organization |
no |
path_prefix |
string | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Created dataset (returned with status 200). | |
400 |
Missing required fields. | Error |
401 |
Unauthorized. | Error |
403 |
Not a member of this organization. | Error |
422 |
Unsupported provider (only Azure Blob). | Error |
500 |
Failed to create dataset. | Error |
14.0.8 updateDatasetAsAdmin
POST /api/datasets/update
Updates a dataset’s settings (dataset editor) or its saved 3D camera position (3D viewer), dispatching on request content type. Requires a session; the caller must own the dataset or hold an admin/owner role in its organization.
Why it exists. ‡ Update a dataset’s stored details from the dataset editor, including re- pointing it at different storage.
Called by — app/(authenticated)/datasets/[slug]/settings/dataset-settings-form.tsx · modules/photo-map-3d/core/hooks/use-3d-asset-handlers.ts
Reached from — /datasets/<slug> · /datasets/<slug>/settings · /w/data-explorer/anomalies/map · /w/data-explorer/assets · /w/integrity/assets · /w/integrity/evidence-explorer
Dispatches on request Content-Type: multipart/form-data updates the dataset editor’s settings (name, description, visibility, regenerating the slug from a new name) and redirects to the dataset’s page on success; application/json updates only the 3D viewer’s saved camera position. Runs as the caller under RLS — the caller must own the dataset or hold an admin/owner role in its organization, not a service-role bypass.
Authentication: CookieAuth
Returns — message · data
Field names as the handler returns them; the source states no types for them.
Effect — writes (update) datasets · organization_members
Request body
| Field | Type | Required |
|---|---|---|
slug |
string | yes |
default_camera |
object | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Camera updated (application/json mode); data is present only when a change was applied. |
Dataset |
307 |
Settings updated (multipart/form-data mode) — redirects to the dataset’s page; empty body. | |
400 |
Bad request | Error |
401 |
Unauthorized. | Error |
403 |
You don’t have permission to edit this dataset. | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.9 verifyOnboardingStorage
POST /api/datasets/verify-storage
Checks that the Azure storage credentials entered in the onboarding wizard actually work, without saving them.
Why it exists. ‡ Check that a set of storage credentials actually works before a dataset is created against them, so the wizard fails at the point the operator can still fix it.
Called by — modules/dataset-onboarding/services/onboarding-api.ts
Reached from — /w/data-explorer/new-dataset
Validates Azure Blob account-key credentials and container read/list access with live Azure calls. Nothing is persisted; credential or network failures return 400, not 500.
Authentication: CookieAuth
Returns — ok · displayUrl · canList
Field names as the handler returns them; the source states no types for them.
Request body
| Field | Type | Required |
|---|---|---|
provider |
string — one of azure |
yes |
accountName |
string | yes |
accountKey |
string | yes |
containerName |
string | yes |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Credentials valid and container listable. | |
400 |
Missing fields, or verification failed (bad credentials/network). | Error |
401 |
Unauthorized. | Error |
403 |
Could not list blobs (missing read permission). | Error |
404 |
Container not found. | Error |
422 |
Unsupported provider (only Azure Blob). | Error |
14.0.10 getDataset
GET /api/datasets/{slug}
Shows one dataset’s details.
Why it exists. ‡ Fetch one dataset by its slug, together with the name of the organisation that owns it, for the dataset detail page header.
Called by — hooks/useDatasetName.ts · lib/services/thumbnail-service.ts
Reached from — /w/data-explorer/assets · /w/data-explorer/categories · /w/data-explorer/new-dataset · /w/data-explorer/storage · /w/integrity/actions · /w/integrity/assets …and 7 more
Retrieves details for a specific dataset by slug.
Authentication: SupabaseAuth
Returns — not readable from the source: the handler returns a value assembled at run time rather than a literal.
Effect — reads datasets · organizations
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Dataset details | Dataset |
400 |
Dataset slug is required | Error |
401 |
Not authenticated | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.11 updateDataset
PATCH /api/datasets/{slug}
Edits a dataset’s name, description, visibility, or cover image.
Why it exists. ‡ Rename a dataset, change its description or visibility, or set its cover image, from the dataset settings panel.
Called by — components/notes/components/promote-note-dialog.tsx · modules/gallery/overlays/components/image-viewer.tsx
Reached from — /datasets/<slug> · /w/data-explorer/anomalies/map · /w/data-explorer/assets · /w/data-explorer/insights · /w/integrity/assets · /w/integrity/evidence-explorer
Updates dataset fields (name, description, visibility, cover image).
Authentication: SupabaseAuth
Returns — not readable from the source: the handler returns a value assembled at run time rather than a literal.
Effect — writes (update) datasets · organizations
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Request body
| Field | Type | Required |
|---|---|---|
name |
string | no |
description |
string | no |
visibility |
string — one of private, organization |
no |
cover_image_id |
string (uuid) | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Updated dataset | Dataset |
400 |
Bad request | Error |
401 |
Not authenticated | Error |
403 |
Access denied | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.12 deleteDataset
DELETE /api/datasets/{slug}
Deletes a dataset and its image records.
Why it exists. ‡ Delete a dataset and the images, annotations, notes and groups hanging off it. Restricted to the dataset’s owner or an administrator of its organisation, since it is not recoverable.
Called by — components/dashboard-client-wrapper.tsx · components/dataset-table.tsx
Reached from — /datasets/org/<id>
Deletes a dataset and its associated images (by slug).
Authentication: SupabaseAuth
Returns — message
Field names as the handler returns them; the source states no types for them.
Effect — writes (delete, update) annotations · coco_image_mappings · data_groups · datasets · images · location_notes · organization_members
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Dataset deleted successfully | |
400 |
Dataset slug is required | Error |
401 |
Not authenticated | Error |
403 |
Access denied | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.13 getDataset3dConfig
GET /api/datasets/{slug}/3d-config
Fetches the dataset’s saved 3D scene setup (models, camera position).
Why it exists. ‡ Return the saved camera position, layer visibility and display settings for a dataset’s 3D scene, so the viewer reopens where the user left it.
Called by — modules/photo-map-3d/core/hooks/use-camera-initialization.ts · modules/photo-map-3d/services/use-supabase-3d-gaussian-splats.ts
Reached from — /datasets/<slug> · /w/data-explorer/anomalies/map · /w/data-explorer/assets · /w/integrity/assets · /w/integrity/evidence-explorer
Returns the stored 3D scene configuration (gaussian splats, 3D tilesets, default camera, loading message) for a dataset.
Authentication: CookieAuth, SupabaseAuth
Returns — not readable from the source: the handler returns a value assembled at run time rather than a literal.
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
3D configuration. | |
400 |
Dataset slug is required | Error |
401 |
Not authenticated. | Error |
404 |
Dataset not found or no 3D configuration. | Error |
500 |
Internal server error. | Error |
14.0.14 replaceDataset3dConfig
PUT /api/datasets/{slug}/3d-config
Saves the dataset’s 3D scene setup.
Why it exists. ‡ Save the 3D scene’s camera position and display settings for a dataset, so a view worth returning to can be preserved.
Called by — modules/photo-map-3d/core/photo-map-3d.tsx
Reached from — /datasets/<slug> · /w/data-explorer/anomalies/map · /w/data-explorer/assets · /w/integrity/assets · /w/integrity/evidence-explorer
Validates and overwrites the dataset’s 3D configuration. All four fields are written on every update; any authenticated user may currently update any dataset’s 3D config (no ownership check).
Authentication: CookieAuth, SupabaseAuth
Returns — success
Field names as the handler returns them; the source states no types for them.
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Request body
| Field | Type | Required |
|---|---|---|
gaussian_splats |
array of object | no |
3d_tilesets |
array of object | no |
default_camera |
object | no |
loading_message |
string | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Updated. | |
400 |
Invalid configuration (details lists per-field validation errors) or update failure. | Error |
401 |
Not authenticated. | Error |
500 |
Internal server error. | Error |
14.0.15 listDatasetAnnotationCategories
GET /api/datasets/{slug}/categories
Summarizes which annotation categories appear in the dataset, with counts and sample thumbnails.
Why it exists. ‡ Summarise which annotation categories occur in a dataset and how often, with one sample image each, so the gallery can offer a category filter that shows what it will find.
Called by — modules/gallery/core/dataset-images-with-folders.tsx
Reached from — /datasets/<slug> · /w/data-explorer/assets · /w/integrity/assets · /w/integrity/evidence-explorer
Aggregates annotation categories present in a dataset’s images, with per-category image counts and one sample thumbnail, sorted by image count descending. Requires membership of the dataset’s organization.
Authentication: CookieAuth, SupabaseAuth
Returns — categories
Field names as the handler returns them; the source states no types for them.
Effect — reads annotation_categories · annotations · datasets · images
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Category aggregation. | |
401 |
Unauthorized. | Error |
403 |
Forbidden — not a member of the dataset’s organization. | Error |
404 |
Dataset not found. | Error |
500 |
Failed to load categories. | Error |
14.0.16 searchImagesByContent
POST /api/datasets/{slug}/find-by-content
Finds which of a dataset’s photographs a given picture is — the frame a slide or a report cut it from — by perceptual hash, nearest first, with the Hamming distance stated so a near miss is not read as a hit.
Called by — app/api/mcp/embed/find-by-content/route.ts
Takes a picture (a data: URL or base64 body) and returns the dataset’s images nearest to it by 64-bit DCT perceptual hash (images.metadata.phash, derived when a thumbnail is generated), nearest first, each with its Hamming distance. A re-encoded, resized or mildly recoloured copy of a frame lands within a few bits; an unrelated photograph of the same plant sits around 30; a substantial crop or a rotation is not matched — this answers “which file is this”, not “what shows the same thing”. The response says how many of the dataset’s images carry a hash at all (indexed of total), so an empty answer over an unindexed dataset is not mistaken for absence. Runs under the caller’s RLS: a dataset they cannot see 404s like a missing one.
Authentication: SupabaseAuth
Returns — query_phash · indexed · total · max_distance · matches
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets · images
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Request body
| Field | Type | Required |
|---|---|---|
image |
string | yes |
max_distance |
integer, nullable | no |
limit |
integer | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
The nearest images, nearest first, within max_distance. |
|
400 |
The image could not be decoded, or is over 25 MB. | Error |
401 |
Not authenticated. | Error |
404 |
Dataset not found (or not visible to the caller). | Error |
500 |
Server error. | Error |
14.0.17 listDatasetGeodata
GET /api/datasets/{slug}/geodata
Same GPS listing via the newer route the 3D map uses.
Why it exists. † Return just the positions of a dataset’s GPS-tagged images, paged, so the map view can plot them without downloading image records it will not display.
Retrieves all images in a dataset that have valid GPS metadata, with secure URLs if available — a newer endpoint for the same GPS data, used by the 3D map.
Authentication: SupabaseAuth
Uses a service-role client (row-level security bypassed).
Returns — images · totalImages · currentPage · totalPages · pageSize
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets · images · thumbnails
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string | |
page |
query | no | integer | |
pageSize |
query | no | integer | |
sort |
query | no | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
List of images with GPS data | GpsImage |
401 |
Not authenticated | Error |
403 |
Forbidden | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.18 listDatasetGpsImages
GET /api/datasets/{slug}/gps-images
Lists the dataset’s images that have GPS coordinates (for map views).
Why it exists. ‡ Return a dataset’s GPS-tagged images with time-limited signed URLs, so the map can show real thumbnails at each position without exposing the underlying storage.
Called by — components/main-panel-renderer.tsx · modules/gallery/core/hooks/use-gps-images.ts
Reached from — /datasets/<slug> · /w/data-explorer/assets · /w/integrity/assets · /w/integrity/evidence-explorer
Retrieves all images in a dataset that have valid GPS metadata, with secure URLs if available.
Authentication: SupabaseAuth
Returns — success · images · totalGpsImages · truncated · limit · sasTokensGenerated
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets · images
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string | |
limit |
query | no | integer |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
List of images with GPS data | Image |
400 |
Bad request | Error |
401 |
Not authenticated | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.19 listDatasetImageGroups
GET /api/datasets/{slug}/groups
Lists those photo pairs grouped by location for the paired viewer.
Why it exists. ‡ Group a dataset’s images into related sets by filename and folder, so a survey shot in passes can be browsed by subject rather than as one flat list.
Called by — modules/gallery/core/hooks/use-dataset-gallery-controller.ts
Reached from — /datasets/<slug> · /w/data-explorer/assets · /w/integrity/assets · /w/integrity/evidence-explorer
Retrieves paired RGB and thermal images with geodata from a dataset, organized by base filename.
Authentication: SupabaseAuth
Returns — groups · totalGroups · page · pageSize · totalPages
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets · images
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string | |
page |
query | no | integer | |
categoryId |
query | no | string | |
folder |
query | no | string | |
pageSize |
query | no | integer | |
sort |
query | no | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Grouped images with pagination | GpsImage |
401 |
Not authenticated | Error |
403 |
Forbidden | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.20 createImageUrls
POST /api/datasets/{slug}/image-url
Issues short-lived secure links to view one image — or a batch of them — in Azure storage. The dataset is authorized under the caller’s own scope before any lookup; inaccessible datasets 404 like missing ones, and cross-dataset or unknown image ids are rejected per-id.
Why it exists. ‡ Mint a short-lived signed URL for one image in a dataset, so the viewer can fetch it directly from storage without the platform proxying the bytes.
Called by — components/chat/dataset-list.tsx · components/chronological-overview.tsx · components/dataset-grid.tsx · components/main-panel-renderer.tsx …and 2 more
Reached from — /datasets/<slug> · /datasets/org/<id> · /w/data-explorer/anomalies/map · /w/data-explorer/assets · /w/integrity/assets · /w/integrity/evidence-explorer …and 1 more
Generates read-only Azure Blob SAS URLs (60-minute expiry) for one image or a batch of images. The dataset is first resolved under the caller’s own RLS scope; a dataset the caller cannot access returns 404, indistinguishable from one that does not exist. Images are then checked per id: unknown ids and images belonging to a different dataset are rejected individually. Before issuing URLs it health-checks the storage account with a short-lived test SAS (result cached ~5 minutes); an unreachable or suspended account returns 402.
Authentication: SupabaseAuth
Returns — url · type · results · errors
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets · images
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Request body
| Field | Type | Required |
|---|---|---|
imageId |
string | no |
imageIds |
array of string | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
SAS URL(s) generated. Single mode returns url; batch mode returns per-image results and errors maps. |
|
400 |
Invalid request | Error |
401 |
Not authenticated | Error |
402 |
Storage provider suspended. | Error |
404 |
Dataset or image not found. | Error |
500 |
Server error | Error |
14.0.21 listDatasetImages
GET /api/datasets/{slug}/images
Lists a dataset’s images, page by page, with filters.
Why it exists. ‡ Page through a dataset’s images with the gallery’s filters — folder, category, free-text — applied in the database rather than the browser, because a campaign dataset is far too large to send whole.
Called by — app/(authenticated)/w/integrity/evidence-explorer/evidence-explorer-client.tsx · components/chronological-overview.tsx · components/workspaces/storage-client.tsx
Reached from — /w/data-explorer/storage · /w/integrity/evidence-explorer · /w/integrity/storage
Retrieves images from a dataset with pagination and filtering options.
Authentication: SupabaseAuth
Returns — filenames · totalImages · expectedTotal · rootCount · images · totalPages · currentPage
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets · images
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string | |
pageSize |
query | no | integer | |
filter |
query | no | string — one of all, rgb, thermal |
|
page |
query | no | integer | |
categoryId |
query | no | string | |
folder |
query | no | string | |
folders |
query | no | boolean | |
sort |
query | no | string | |
includeOtherDatasets |
query | no | boolean |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
A paginated list of images | Image |
401 |
Not authenticated | Error |
403 |
Forbidden | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.22 indexDatasetImages
POST /api/datasets/{slug}/index-images
Scans the dataset’s storage container and registers the images it finds.
Why it exists. ‡ Walk the dataset’s storage container and record every image it finds as a row, so a dataset that was registered by pointing at a bucket becomes browsable. Re-runnable as the source container grows.
Called by — app/(authenticated)/datasets/[slug]/components/reindex-button.tsx · app/datasets/create/page.tsx · components/dataset-grid.tsx · components/dataset-table.tsx …and 1 more
Reached from — /datasets/<slug> · /datasets/create · /datasets/org/<id> · /w/data-explorer/new-dataset
Indexes images in the specified dataset by scanning its storage container.
Authentication: SupabaseAuth
Returns — success · message · newImagesCount · removedCount · duplicatesRemoved · totalImagesCount · storageImagesCount
Field names as the handler returns them; the source states no types for them.
Effect — writes (delete, insert) datasets · images
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Request body
| Field | Type | Required |
|---|---|---|
imagesOnly |
boolean | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Indexing result | |
400 |
Bad request | Error |
401 |
Not authenticated | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.23 transitionDatasetLifecycle
PATCH /api/datasets/{slug}/lifecycle
Sends a campaign for review, or returns one for more evidence — the hand-off between Data Explorer and Integrity.
Why it exists. ‡ Let Data Explorer send a campaign for review, and let Integrity return one for more evidence — the hand-off between the two workspaces.
Called by — lib/workspaces/queries/campaign-lifecycle.ts
Reached from — /w/data-explorer/campaigns · /w/integrity/campaigns
Transitions a campaign’s lifecycle state (indexing, ready_for_review, in_review, or closed) and records the transition in an append-only event log, atomically. Authorized by the transition_dataset_lifecycle Postgres function, which admits the dataset’s owner or an organization’s admin or member (not viewers) — not the datasets UPDATE policy, since that table also carries credentials/storage_path/provider/owner_id that a blanket policy would expose. A reason is required when transitioning to indexing and rejected if blank; no reason is required for ready_for_review. Transitioning to the campaign’s current state is a no-op.
Authentication: CookieAuth, SupabaseAuth
Returns — dataset
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Request body
| Field | Type | Required |
|---|---|---|
to |
string — one of indexing, ready_for_review, in_review, closed |
yes |
reason |
string | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
The dataset row after the transition (or unchanged, if it was already at the target state). | Dataset |
400 |
Invalid to value, or a required reason was missing/blank. |
Error |
401 |
Unauthorized. | Error |
403 |
The caller is neither the campaign’s owner nor an editor of its organization. | Error |
404 |
Dataset not found or not visible to the caller. | Error |
500 |
Server error. | Error |
14.0.24 getCampaignLifecycleEvents
GET /api/datasets/{slug}/lifecycle-events
Campaign History’s real transition timeline — who sent or returned the campaign, when, and why.
Why it exists. ‡ Give a caller the campaign’s real lifecycle transition history — who sent it for review or returned it, when, and why — the same events Campaign History renders.
Reads the campaign’s lifecycle-transition history (written only by the lifecycle-transition endpoint) newest first, with each event’s actor resolved to a name — omitted, never a raw id, when the caller cannot see the actor’s profile.
Authentication: CookieAuth, SupabaseAuth
Returns — events
Field names as the handler returns them; the source states no types for them.
Effect — reads dataset_lifecycle_events · datasets · profiles
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
The campaign’s lifecycle transitions, newest first. | |
400 |
Dataset slug is required. | Error |
401 |
Unauthorized. | Error |
404 |
Dataset not found or not visible to the caller. | Error |
500 |
Server error. | Error |
14.0.25 listDatasetImagePairs
GET /api/datasets/{slug}/pairs
Lists matched pairs of regular and thermal photos, page by page.
Why it exists. ‡ Match each thermal image in a dataset to its visual counterpart by filename convention, so the side-by-side comparison view can show both captures of the same subject.
Called by — app/(authenticated)/w/integrity/investigate/investigate-client.tsx
Reached from — /w/integrity/investigate
Retrieves paginated pairs of RGB and thermal images from a dataset.
Authentication: SupabaseAuth
Returns — pairs · totalItems · totalPages · currentPage
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets · images · organization_members
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string | |
page |
query | no | integer | |
forImageId |
query | no | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
A paginated list of image pairs | ImagePair |
401 |
Not authenticated | Error |
403 |
Forbidden | Error |
404 |
Dataset not found | Error |
500 |
Server error | Error |
14.0.26 getCampaignProgress
GET /api/datasets/{slug}/progress
The same per-campaign numbers the /progress dashboard shows — coverage, tagged/anomaly counts, and new/confirmed/dismissed candidates.
Why it exists. ‡ Give a caller the same per-campaign progress numbers the /progress dashboard shows, without needing the dashboard’s own server-only queries.
Composes the same coverage, tagged/anomaly-count, and new/confirmed/dismissed-candidate numbers the /progress dashboard shows, running as the caller under RLS rather than the page’s service-role client.
Authentication: CookieAuth, SupabaseAuth
Returns — datasetSlug · datasetName · totalImages · gpsImages · coveragePct · taggedImages · anomalyRatePct · candidates
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets · equipment_damage_mechanisms · images
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Coverage/tagged/anomaly numbers plus candidate counts for this campaign. | |
400 |
Dataset slug is required. | Error |
401 |
Unauthorized. | Error |
404 |
Dataset not found or not visible to the caller. | Error |
500 |
Server error. | Error |
14.0.27 createDatasetVideoUrl
POST /api/datasets/{slug}/sign-video
Issues a short-lived secure link to play a video from the dataset.
Why it exists. ‡ Mint a short-lived signed URL for one video in a dataset, so it can be streamed straight from storage by a caller who is a member of the owning organisation.
Called by — modules/gallery/overlays/components/image-viewer.tsx · modules/photo-map-3d/core/hooks/use-click-handlers.ts · modules/photo-map-3d/overlays/hooks/use-photo-viewer.ts
Reached from — /datasets/<slug> · /w/data-explorer/anomalies/map · /w/data-explorer/assets · /w/integrity/assets · /w/integrity/evidence-explorer
Mints a short-lived read-only Azure Blob SAS URL for a video blob in the dataset’s container. Requires membership of the dataset’s organization; the dataset’s storage_path/credentials supply the Azure account and key.
Authentication: CookieAuth
Returns — url
Field names as the handler returns them; the source states no types for them.
Effect — reads datasets
Parameters
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
slug |
path | yes | string |
Request body
| Field | Type | Required |
|---|---|---|
blobName |
string | yes |
expiryMinutes |
number | no |
Responses
| Status | Meaning | Body |
|---|---|---|
200 |
Signed URL. | |
400 |
Missing slug or blobName. | Error |
401 |
Unauthorized. | Error |
403 |
Forbidden — not a member of the dataset’s organization. | Error |
404 |
Dataset not found. | Error |
500 |
Invalid storage configuration or signing failure. | Error |