Skip to main content

Curation routes

Experimental

The curation subsystem is experimental in v0.6.0. It is real and tested, but backward compatibility across releases is not guaranteed until it graduates. It ships opt-in behind the curation compose profile.

The generated contract, contracts/openapi/curation.json, lists every route and is the source of truth for every path, parameter and schema. This page groups them by area. Request models reject unknown keys (extra='forbid'), so a stale or misspelled field is a 422, never a silent no-op. Consumers should read the mount prefix (OP_API_PREFIX, default /curation) from configuration rather than hardcode it. There is no /v1 twin and no alias.

Projects and scoping​

A project is an isolated dataset workspace with its own indexes, class registry, exports, settings and job state. Every route that reads or writes data lives under /curation/projects/{project}/. There is no unscoped alias: an unscoped data path is a 404. Paths on this page omit that prefix unless they are global.

The routes outside a project:

MethodPathPurpose
GET/curation/healthDeployment facts only: status, Triton, OpenSearch, VLM, versions
GET/curation/eventsServer-sent events with project: null: project.*, combine.*, vlm.changed
GET/curation/projectsList projects (?include_archived=true), shard capacity, slug limits, display labels
POST/curation/projectsCreate a project (slug, display_name, optional description, clone_settings_from, clone_axes). 201
GET/curation/projects/{project}One project: status, revision, counts, resources, flags (writable, deletable, ...)
PATCH/curation/projects/{project}Edit display_name / description; needs expected_revision
POST/curation/projects/{project}/archiveArchive (read-only). /unarchive reverses it
POST/curation/projects/{project}/clone_settingsCopy settings axes from another project
DELETE/curation/projects/{project}?dry_run=true reports what would go; a real delete needs ?confirm=<slug> and answers 202 with status deleting (async: the project answers 404 a few seconds later, and the slug is retired and cannot be reused)
GET/curation/vlm/endpointsThe VLM endpoint registry (see VLM endpoints)
GET/curation/vlm/catalogThe local VLM catalog

A project's status is building, active, archived, deleting, deleted or failed. Only an active project is writable; an archived one answers writes with 409 project_read_only. The default project is an ordinary project that can be archived but never deleted. Lifecycle mutations answer one envelope, {project, warnings}, so a client can adopt the returned summary without a re-read.

Errors from project, config and import routes share one body, {"detail": {"error": "<code>", "message": "...", ...}}, with code-specific extra fields. Read endpoints fail closed: a backend error is an HTTP error, never a silently empty result.

Health, discovery and settings​

MethodPathPurpose
GET/curation/projects/{project}/healthstatus ok / degraded / down plus project, triton, opensearch, vlm, registry, active region_profile, mlflow_public_url
GET/models/statusEvery model the curation pipeline depends on; VLM rows are one per registered endpoint (kind: "vlm", with active)
DELETE/models/{model_name}Unload a promoted model. Models the active profile depends on are refused (403); other core models need ?force=true (409 without it)
GET/models/{model_name}/class_mappingHow a model's classes map by name onto this project's classes
PUT/models/{model_name}/sharingOpt a promoted model into or out of use by other projects
GET/methodsCapability discovery: axes and strategies per axis (cluster, score, sort, overlay, export, detection_profile, prompt_pack, vlm) and feature flags. Gate optional UI on this, never on a probing write
GET/settingsShared per-axis strategy defaults (defaults is an open map keyed by axis id)
PUT/settingsPartial update. defaults.vlm activates an endpoint through the same gate as /vlm/endpoints/{name}/activate; defaults.prompt_pack and defaults.detection_profile delegate to the config store's activation
GET/config/vocabularyOne place every model choice is served: the active VLM, endpoints, and a model_choices table
GET/class_sourcesEvery class_source value this deployment can write, with role and label
GET/statsProject counts
GET/stats/datasetDataset totals (labeled by human / VLM / classifier / import, regions, clusters, in-flight work)
GET/stats/classesPer-class counts
GET/eventsServer-sent events for this project (for example crop.region_verified, config.changed)
POST/events/publishCross-process publish endpoint the workers use
GET/events/statsHub stats for this project's stream
GET/pauseWhether the project's pipeline is paused, and by what
POST/pauseWorkers skip this project's work. /resume clears it

Ingest​

Ingest runs the configured item detector, crops each detection into an item, embeds it, rejects duplicates and indexes in bulk. Images are read from configured source roots or uploaded as bytes. To import an already-labeled dataset, use Dataset import.

MethodPathPurpose
POST/ingest/imageIngest one image by path (under a configured source root)
POST/ingest/batchIngest items by path; capped by OP_BATCH_MAX_ITEMS_PER_REQUEST (413 over it)
POST/ingest/uploadMultipart upload of images; bytes are persisted content-addressed under the project's upload root; optional run_id
POST/ingest/path_lookupWhich image paths (or upload identifiers) are already indexed
GET/ingest/configServed upload/batch limits and drain-poll parameters
GET/ingest/statusTotals by source and day (optionally ?run_id=)
GET/ingest/region_drainPending region work, a stability verdict (drained), per-dependency health and a stall_reason

Each image result carries status (success / duplicate / failed), image_id, n_crops, n_regions, and on failure an error_kind (empty, unservable_path, unsupported_type, decode_failed, detector_infer, bulk_index, ...). Byte-identical files are deduplicated within a batch as well as against the index.

Dataset import​

Bring a labeled YOLO or COCO dataset, or an OpenProcessor export, into a project. Classes map by name. The import is chunked, resumable and undoable. See Dataset import.

MethodPathPurpose
GET/datasets/formatsThe formats the importer reads
POST/datasets/uploadsUpload a zip or tar archive (201, 413 upload_too_large)
POST/datasets/previewScan a dataset without writing: classes, counts, issues, and suggestions for the class mapping
POST/datasets/importsStart an import. 202; reused when the same import_key already ran
GET/datasets/importsList imports
GET/datasets/imports/{import_id}Status, progress and the report
GET/datasets/imports/{import_id}/issuesThe scan issues, paged
GET/datasets/imports/{import_id}/entriesPer-image ledger rows, paged
POST/datasets/imports/{import_id}/cancelStop after the current chunk
POST/datasets/imports/{import_id}/resumeContinue an interrupted or cancelled import (202)
POST/datasets/imports/{import_id}/undoReverse the import

The mapping is a list of {dataset_class, action, ...} rows where action is map (class_id), create (new_class_name, new_class_group), skip or region. Every class that has boxes needs a decision (422 class_mapping_incomplete lists the unmapped names). A COCO layout (images/ next to annotations/*.json) is detected automatically.

Reprocess​

One route re-runs pipeline stages over existing data. See Reprocess.

MethodPathPurpose
POST/reprocesstargets (exactly one of image_ids, crop_ids, filter), scopes (detect, region, vlm, embed), region_mode (redetect / reverify), dry_run (default true)
POST/images/{image_id}/reprocessThe per-image button; applies by default
POST/crops/{crop_id}/reprocessThe per-item button; applies by default
GET/reprocess/jobs/{job_id}Progress of a job (detect or embed beyond OP_REPROCESS_SYNC_MAX images runs as a file-backed job; one live job per project, 409 reprocess_busy)
POST/reprocess/jobs/{job_id}/cancelStop a live job after its current chunk

Locked items and boxes are never written; each scope reports locked_skipped. The filter also selects by provenance: profile_not, profile_revision_below, import_id, dataset_split, region_status, reason, detector, missing_status, missing_provenance.

Combining projects​

POST /curation/projects/combine builds a NEW project from 1 to 8 existing ones. It never writes to a source: the target is created building, filled, then made active (a failed run leaves it failed; deleting the target is a complete undo). These routes are global, not under a project. See Combine projects.

MethodPathPurpose
POST/curation/projects/combine/previewDry run (writes nothing): errors and warnings, suggested_mapping, per-source and target counts, duplicate and conflict counts, bytes to link, and a preview_sha
POST/curation/projects/combineStart with the preview body plus expected_preview_sha (409 preview_stale if a source changed, 422 combine_invalid with a report). 202 {job_id, target}
GET/curation/projects/combine/{job_id}status, phase, done / total images, report, next_steps; also published as combine.progress events
POST/curation/projects/combine/{job_id}/cancelCancel a running job
POST/curation/projects/combine/{job_id}/resumeResume an interrupted or cancelled job from its last finished chunk

A class is its name. class_mapping has one list of map / create / skip / region rows per source, the same rows a dataset import takes; every source class with an included label needs a row (unmapped_class). The target numbers its own classes. Sources are listed in priority order. With dedup: content_hash, an image that is byte-identical in two sources is copied once, from the highest-priority source; boxes of the other copy with IoU of at least dedup_iou and the same target class are merged (the more trusted label wins: human, import, VLM, model), and a box with a different class keeps the priority label and is flagged combine_conflict (the combine_conflict filter on GET /review/{tab} lists them). Clusters are not copied: recluster the combined items. holdout: preserve_union keeps anything that was test in any source as test; recompute picks a new split and warns. A live combine marks its sources and target project_busy.

Items (crops) and labeling​

MethodPathPurpose
GET/cropsBrowse and filter items, including import_id, dataset_split, on_negative_frame, proposed_by_import. n_unembedded is returned only for order=diverse or core_first (null otherwise; use GET /stats/dataset embedding to watch an embed drain)
GET/crops/{crop_id}One item
GET/crops/{crop_id}/thumbnailItem crop thumbnail
GET/crops/{crop_id}/imageThe clean source image of the item's frame
GET/crops/{crop_id}/region_thumbnailOne region box's crop; box_id is required
GET/crops/{crop_id}/contextThe item's source image and the other items on it
GET/crops/{crop_id}/historyLabel/edit history
PUT/crops/{crop_id}/labelSet the class (class_id, label_source human or human_confirmed)
DELETE/crops/{crop_id}/labelClear a human label
PUT/crops/batch_labelLabel many; returns updated_ids and per-item conflicts
POST/crops/{crop_id}/label/undoUndo the last human class write
POST/crops/label/undo_batchBatch undo
POST/crops/moveMove items to another cluster
POST/crops/batch_excludeExclude from datasets (with a reason)
POST/crops/batch_unexcludeRestore excluded items
POST/crops/{crop_id}/discardDiscard an item
POST/crops/discard_batchDiscard many
POST/crops/flag_new_classFlag items as a class the registry lacks
POST/crops/{crop_id}/review_dismissHide from every review queue
POST/crops/{crop_id}/review_undismissReturn an item to the queues
POST/crops/{crop_id}/vlm_dismissReject the VLM's class suggestion
POST/crops/{crop_id}/vlm_dismiss/undoUndo that

The lock rule. A human-set class, a validated imported label, an item in the frozen test holdout, and a human-owned or imported-and-settled region box are locked. No automated writer (worker, VLM batch, re-ingest, reprocess, import over an existing item) changes a locked value. A human label always writes class_source: "human"; a client cannot make a human write look machine-made. An item serves label_locked.

Classes​

Class identity is the name. A project's registry assigns its own ids; a dataset, a combined source or a promoted model is matched to it by name.

MethodPathPurpose
GET/classesList with counts, thresholds and reserved hotkeys
POST/classesCreate (name must match ^[a-z0-9_]+$)
GET/classes/{class_id}One class
PUT/classes/{class_id}Rename, regroup, bind or clear a hotkey
GET/classes/{class_id}/cropsItems of a class
POST/classes/mergeMerge source_id into target_id; ?dry_run=true previews
POST/classes/{class_id}/deprecateRetire a class that has no data yet
POST/classes/{class_id}/restoreRestore it
POST/classes/sync_to_opensearchRe-sync the JSON registry into the classes index

The registry is a JSON file in the project's data directory; the first POST /classes creates it with dense ids starting at 0. A hotkey that the project's keymap reserves answers 422 hotkey_reserved; one that another class holds answers 409 hotkey_taken.

Keymap​

Each project stores its own keyboard map; a project with no stored map serves the built-in defaults (is_default: true). Writes use optimistic concurrency (expected_revision).

MethodPathPurpose
GET/keymapThe action registry, grammar and this project's bindings
PUT/keymapReplace the overrides. A clash with a class hotkey is 409 class_hotkey_conflict unless unbind_conflicting_class_hotkeys is set
POST/keymap/validateDry run of a PUT; always 200 with a report
POST/keymap/resetReset all or the listed actions

See Keymaps.

MethodPathPurpose
GET/clustersCluster cards: cluster_kind, dominant class, purity (geometry), label_agreement (label share), validated count, sub-clusters, representatives
GET/clusters/representativesRepresentatives only
POST/clusters/refine/{cluster_id}Split one cluster into sub-clusters
POST/clusters/auto_promoteValidate classifier-labelled items in high-purity clusters. Gated on the accuracy audit: 409 audit_required / 409 audit_precision_low (with classes) unless force=true; promote_min_precision defaults to 0.95; dry_run is never gated
POST/cluster/umap/rebuildRebuild the residual reducer
GET/viz/projectionCached 2-D coordinates for plotting; never fits inline
POST/viz/projection/rebuildStart the projection fit job
GET/viz/projection/statusJob status. /viz/projection/cancel stops it
POST/scores/computeMistakenness, uniqueness and near-duplicate scores (OP_SCORES_ENABLED)
GET/scores/statusStatus. /scores/coverage reports field coverage and /scores/cancel stops a run
POST/select/diversek-center-greedy diverse sampling (OP_SELECT_DIVERSE_ENABLED)
GET/select/statusStatus of a backgrounded selection. /select/cancel stops it
GET/search/textPE-Core text-to-image semantic search (OP_SEMANTIC_SEARCH_ENABLED)

Review queues and holdout​

MethodPathPurpose
GET/review/tabsThe tab catalog with each tab's label, filters, defaults and empty-state hints
GET/review/{tab}One queue. Tabs: all, mismatches, vlm_low_conf, detector_disagreements, outliers, uncertainty, model_disagreements, regions, primary_low_conf, classifier_blind_spots, new_class_proposals, imported
GET/review/{tab}/locatePosition of one item within a queue
GET/review/new_class_proposals/summaryVLM-proposed class names, grouped
POST/review/new_class_proposals/resolveAccept or reject a proposed name for every item that proposes it
GET/review/raw_label_clustersRaw VLM answers that matched no class, clustered
GET/review/unmatched_termsThe same answers, aggregated by term
POST/test_holdout/freezeFreeze a per-class test split before exporting
GET/test_holdout/statsPer-class test counts
POST/audit/startDraw a stratified accuracy-audit sample of machine-labelled crops (min_per_class, sample_size); 409 audit_no_candidates when none are eligible
GET/audit/queueDrawn crops still waiting for a human label (batch_id, page, page_size)
GET/audit/reportDetector and VLM precision per class with Wilson 95% intervals, the confusion matrix and insufficient_sample flags (min_per_class)
POST/probe/runActive-learning probe predictions (feeds model_disagreements and uncertainty)
GET/probe/statusProbe status. /probe/cancel stops it

Queue filters include on_negative_frame and combine_conflict.

Regions of interest​

Regions are meaningful once a region profile is active. An item carries a list of boxes (region_boxes), each with a box_id and its own state, verdict, text, cluster and embedding; see Multi-box regions. A profile's max_regions_per_item caps the list (default 1).

MethodPathPurpose
GET/regionsBrowse region rows: one row per matching box, or per item. total counts items, total_rows rows. Filters include box_state
GET/regions/statusesThe status catalog, the per-box state vocabulary and which are human-writable
GET/regions/vocabularyDetector, segmenter and verifier vocabulary for the active profile, with limits.max_boxes_per_write
PUT/crops/{crop_id}/regionsSet a crop's box list (frame source or parent). A box with only a box_id is left untouched; box_id: null adds a box. A stale expected_region_revision is 409 region_conflict; an empty list means "no region visible"
PUT/crops/batch_regionsAdd the same new boxes to many crops
PATCH/crops/{crop_id}/regions/{box_id}Patch one box's state or text without touching its siblings
POST/regions/batch_box_stateSet one state on many {crop_id, box_id} targets
PATCH/crops/{crop_id}/region_metaEdit region_status and the rejection reason
POST/regions/batch_statusSet a human-writable whole-item status on many items
POST/crops/{crop_id}/region/undoUndo a region write (restores the box list)
POST/crops/region/undo_batchBatch undo
POST/regions/clusterCluster region boxes (background job; a cluster card's size is items, box_count boxes)
GET/regions/cluster/statusJob status
GET/regions/clustersRegion cluster cards
POST/regions/clusters/refine/{cluster_id}Refine one region cluster
POST/regions/fp_centroids/buildBuild false-positive sub-centroids from false-positive boxes
GET/regions/fp_centroids/statusBuild status
GET/regions/suspected_false_positivesNon-false-positive boxes ranked by similarity to the false-positive sub-centroids, one row per box
GET/regions/training_candidatesCurated cohorts for training the next region detector

Per-box states are proposed, accepted, rejected and false_positive. An item's region_status is derived from its boxes (accepted, then false positive, then proposed, then rejected, then empty).

Config store: prompt packs and region profiles​

A prompt pack (the VLM's prompts) and a region profile (what to detect and how) are named, versioned documents stored per project. Every save is a new immutable revision. Exactly one pack and one profile are active at a time, and activation is checked against the other settings before it applies.

MethodPathPurpose
GET/prompt_packsList stored packs and templates
POST/prompt_packsCreate a pack
GET/prompt_packs/schemaField specs and placeholders, for a form
POST/prompt_packs/validateValidate a draft without saving
POST/prompt_packs/testRun one call of a pack, saved or draft, over stored crops and preview each item's write
GET/prompt_packs/activeThe active pack, with what each worker applied
POST/prompt_packs/active/rollbackRe-activate the previous pack
GET/prompt_packs/{name}One pack
PUT/prompt_packs/{name}Save a new revision (needs expected_revision)
DELETE/prompt_packs/{name}Delete a pack
POST/prompt_packs/{name}/activateActivate a revision
POST/prompt_packs/{name}/cloneCopy a pack, optionally from another project (read-only)
GET/prompt_packs/{name}/revisionsRevision history; /revisions/{revision} returns one
GET/region_profilesList stored profiles and templates
POST/region_profilesCreate a profile
GET/region_profiles/schemaField specs, for a form
POST/region_profiles/validateValidate a draft without saving
POST/region_profiles/validate_segmenter_promptCheck a segmenter text prompt
POST/region_profiles/testRun a profile's detector and segmenter legs over one stored crop, with every candidate and why it was kept or dropped
GET/region_profiles/activeThe active profile
GET/region_profiles/active/impactWhat activating or deactivating would affect, with a suggested_reprocess request
POST/region_profiles/active/rollbackRe-activate the previous profile
POST/region_profiles/deactivateTurn region detection off for the project
GET/region_profiles/{name}One profile
PUT/region_profiles/{name}Save a new revision
DELETE/region_profiles/{name}Delete a profile
POST/region_profiles/{name}/activateActivate a revision
POST/region_profiles/{name}/cloneCopy a profile
GET/region_profiles/{name}/revisionsRevision history; /revisions/{revision} returns one

| GET | /open_vocab | List open-vocabulary prompt sets and templates | | POST | /open_vocab | Create a set | | GET | /open_vocab/schema | Field specs, ranges and defaults, for a form | | POST | /open_vocab/validate | Validate a draft without saving | | POST | /open_vocab/test | Try one unsaved target on one image; writes nothing | | GET | /open_vocab/active | The active set | | POST | /open_vocab/active/rollback | Re-activate the previous set | | POST | /open_vocab/deactivate | Turn the pass off for the project | | GET | /open_vocab/{name} | One set | | PUT | /open_vocab/{name} | Save a new revision | | DELETE | /open_vocab/{name} | Delete a set | | POST | /open_vocab/{name}/activate | Activate a revision | | POST | /open_vocab/{name}/clone | Copy a set or template, optionally from another project | | GET | /open_vocab/{name}/revisions | Revision history; /revisions/{revision} returns one |

The test routes read stored crops and write nothing. They are limited to 2 concurrent VLM runs and 4 concurrent segmenter calls (429 test_busy), a 60 s bound (504 test_timeout) and a crop cap (422 too_many_crops). See Test on a crop, Prompt packs, Open-vocabulary detection and Settings and config store.

VLM endpoints​

The endpoint registry is deployment-wide; which endpoint a project runs is per project. The registry is global, so these routes are not under a project. Keys are never stored or served: an endpoint holds an api_key_ref such as secret:<slug>. See VLM selection.

MethodPathPurpose
GET/curation/vlm/endpointsEvery endpoint (the read-only env built-in first) with where each is active
POST/curation/vlm/endpointsRegister an endpoint
GET/curation/vlm/endpoints/schemaForm field specs
POST/curation/vlm/endpoints/validateValidate a draft; ?probe=true also tests it
GET/curation/vlm/endpoints/{name}One endpoint
PUT/curation/vlm/endpoints/{name}Save a new revision (needs expected_revision); changes nothing until activated
DELETE/curation/vlm/endpoints/{name}Delete; 409 in_use while any project runs it
POST/curation/vlm/endpoints/{name}/cloneCopy an endpoint
POST/curation/vlm/endpoints/{name}/probeTest with synthetic images and record the served model, context length, image cap and JSON-mode support
GET/curation/vlm/endpoints/{name}/revisionsRevision history
GET/curation/vlm/catalogThe local model catalog with fits, serving and desired per entry
GET/curation/vlm/localThe local VLM's served and desired model
POST/curation/vlm/local/selectRecord the desired local model (202). The API never restarts vLLM; the host applies it with openprocessor vlm apply
DELETE/curation/vlm/local/selectClear the desired model
GET/curation/projects/{project}/vlm/endpoints/activeThis project's active endpoint (active.name: null = off)
POST/curation/projects/{project}/vlm/endpoints/{name}/activateActivate name for the project, with optional revision, force, acknowledge_external
POST/curation/projects/{project}/vlm/endpoints/active/rollbackRe-activate the previous endpoint
POST/curation/projects/{project}/vlm/endpoints/deactivateVLM off for the project

VLM and auto-label pipeline​

Every VLM route takes an optional ?vlm=<name> or <name>@<revision> and ?acknowledge_external=; an unknown name is 422 unknown_vlm, and a project with the VLM off is 409 vlm_not_configured.

MethodPathPurpose
POST/vlm/label_batchVLM class suggestions for up to 64 crop_ids
POST/assist/runsVLM suggestions for a crop, a selection, a cluster, a sub-cluster or a filter, as a background run (dry run by default)
GET/assist/runsThe newest assist runs for a cluster or sub-cluster, each with scope_now
GET/assist/runs/{run_id}State, progress, result (with the cluster proposal) and scope_now of one assist run
POST/assist/runs/{run_id}/cancelStop a live assist run after its current chunk
POST/assist/runs/{run_id}/applyLabel the scope's current members with the proposed class, as a human would (dry run by default)
POST/vlm/verify_region_batchThe same in batches per upstream call
POST/vlm/region_visible_batch"Is a region visible at all?" pre-filter
GET/vlm/policyThe VLM scope policy: scope (all, uncertain, representatives, off), conf_max, per_cluster, max_crops_per_day, sample_frac, revision
PUT/vlm/policyReplace it (needs expected_revision; 409 revision_conflict when stale). Limits the VLM worker and the auto_label VLM stage; see VLM selection
POST/pipeline/auto_label/startQueue a job for the auto-label worker (run_vlm, vlm_scope, train_clusters, ...). Clusters only unless run_vlm=true
GET/pipeline/auto_label/statusCurrent or last job
GET/pipeline/auto_label/status/{job_id}One job
POST/pipeline/auto_label/cancelCancel
POST/pipeline/auto_labelRun the pipeline in-process (synchronous)
GET/pipeline/eventsPipeline progress events

A VLM reply with no usable answer is omitted, not written as a negative verdict, so the item can be retried.

Export​

MethodPathPurpose
POST/export/yoloMulti-class YOLO export (always every class); require_fully_labeled_images, seed, max_images, dedup_threshold
POST/export/single_classSingle-class or class-subset export with background and hard-negative frames and frozen_test_sha
GET/export/statusLast export
GET/export/single_class/statusLast narrowed export for a profile
GET/export/datasetsEvery export (kind, dataset_sha, split counts, is_current)
GET/export/registry/{artifact}Download a frozen artifact of the current export (whitelisted names only)
GET/training_cohortsPer-class training cohorts (?class_id=)

Training and model comparison​

MethodPathPurpose
POST/train/preflightBlocking and warning checks for a spec (dataset, classes, GPUs, trainer reachability)
POST/train/startSubmit one run (?force=true bypasses blocking checks)
POST/train/start_campaignSubmit a progressive multi-size campaign
GET/train/statusLatest run: epochs, eval block, comparison
GET/train/status/{job_id}A specific run
GET/train/runsPast runs
GET/train/log/tail/{job_id}Log tail
GET/train/manifest/{job_id}Lineage manifest
GET/train/artifacts/{job_id}/{name}A whitelisted run artifact
POST/train/cancel/{job_id}Cancel a run. /train/cancel_campaign/{campaign_id} cancels a campaign
GET/train/profilesHyperparameter tables. /train/presets, /train/augmentation_presets and /train/gpus list presets and GPU options
POST/train/promote/{job_id}Promote a finished run into Triton, behind a quality gate. The model is named for the project ({slug}__<requested triton_name>, none for default); the final name is returned as triton_name in the result and the job status, and is the name /detect?model_name= and DELETE /models/{model_name} expect. Returns 202 with a promote_id: use this job and poll it for UIs and anything behind a reverse proxy (proxies time out near 120 s). ?wait=true blocks until loaded and warmed (2-3 minutes) and returns 200; it is for direct API scripting with a client timeout of at least 300 s. A dropped wait=true connection abandons the response, not the promote: the load still finishes. The gate-bypass force may be sent in the JSON body or as ?force=true
GET/train/promote/{job_id}/jobs/{promote_id}Phase of a background promote: queued, exporting, loading, building, warming, done or failed
POST/train/reload_promotedReload promoted models after a Triton restart
GET/bakeoff/eval_datasetsEval sets: exports with a labelled test split and frozen external sets. /bakeoff/trained_models, /bakeoff/baseline_models and /bakeoff/profiles list the rest of what can be compared
POST/bakeoff/runQueue a comparison for the evaluator
GET/bakeoff/runsComparison jobs
GET/bakeoff/status/{job_id}Job status
GET/bakeoff/results/{job_id}Ranked comparison on one dataset (schema v2)
GET/bakeoff/matrix/{job_id}The model by dataset matrix

POST /train/start does not merge profile defaults: copy the hyperparameters from GET /train/profiles into the request's own hyperparameters object. See Training, bake-off and promote.

Images​

MethodPathPurpose
GET/images/serveServe a source image by path (confined to configured roots)
GET/images/root/{alias}Serve from a named extra root (OP_SOURCE_PATH_ALIASES)
GET/images/cache/statsThumbnail cache stats