All /api/* routes require an X-API-Key header, or a valid browser
session (for same-origin UI calls — no header needed when calling from the browser while logged
in).
CORS: Argus includes CORSMiddleware with
allow_origins=["*"], so browser-side calls from other LAN hosts work without a
proxy. Authentication is still enforced via X-API-Key on every request.
To get an API key:
http://localhost:8100
Interactive docs (requires a running instance):
http://localhost:8100/docs
These endpoints require no API key.
# Health — status, version, active provider, loaded models
curl http://localhost:8100/api/health
# Capabilities — detection types, supported formats, pagination limits, integration features
curl http://localhost:8100/api/capabilities
Call /api/capabilities before integrating so a client can adapt instead of
hardcoding what's available.
GET /api/stats
Dashboard counts and storage summary in one round-trip.
curl -H "X-API-Key: argus_..." http://localhost:8100/api/stats
# → {"identities": 12, "face_identities": 8, "object_identities": 4,
# "detections": 348, "face_detections": 210, "object_detections": 138,
# "source_images": 95, "pending_review": 14,
# "storage": "1.2 GB", "storage_free": "45.3 GB",
# "storage_bytes": 1288490188, "storage_free_bytes": 48644997120}
Every detect endpoint accepts exactly one of: a file multipart upload, an
image_url field, or an image_base64 field (raw base64 or a
data:image/...;base64, URI). Zero or more than one is a 400.
Supported formats: JPEG, PNG, WEBP, BMP, GIF (first frame), TIFF, HEIC/HEIF, AVIF, MPO (first frame).
POST /api/detect/faces
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file=@photo.jpg" \
http://localhost:8100/api/detect/faces
POST /api/detect/objects
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file=@photo.jpg" \
http://localhost:8100/api/detect/objects
POST /api/detect/all
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file=@photo.jpg" \
http://localhost:8100/api/detect/all
When label is provided, the highest-confidence face is confirmed as that person
and enrolled immediately, bypassing the review queue. Any other faces are stored as pending.
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"image_url": "http://...", "label": "Noah"}' \
http://localhost:8100/api/detect/faces
Argus deduplicates source images by content hash, so re-detecting the same image reuses its
source_image_id. Pass replace=true to clear prior detections of the
type being run before writing new ones.
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file=@photo.jpg" \
-F "replace=true" \
http://localhost:8100/api/detect/all
Detect faces and/or objects across many images in a single call. Each image can be a URL, file upload, or base64. One bad image never fails the others.
POST /api/detect/bulk
Sync (waits for all results):
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"image_urls": ["http://cam1/snap.jpg", "http://cam2/snap.jpg"], "type": "faces"}' \
http://localhost:8100/api/detect/bulk
Async (returns job id immediately, max 200 images per call):
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"image_urls": ["http://cam1/snap.jpg", "..."], "type": "all"}' \
"http://localhost:8100/api/detect/bulk?async=true"
# → {"job_id": 7, "status": "pending", "total": 50}
Register a job.done webhook to be notified instead of polling.
Add a reference face for a person. The image must contain exactly one face.
POST /api/faces/enroll
curl -X POST \
-H "X-API-Key: argus_..." \
-F "name=Noah" \
-F "file=@noah.jpg" \
http://localhost:8100/api/faces/enroll
# → {"identity_id": 3, "label": "Noah", "embedding_id": 17, "enrolled": true}
Add an additional reference photo to an existing identity (by id).
POST /api/identities/{id}/enroll
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file=@another_noah.jpg" \
http://localhost:8100/api/identities/3/enroll
Promote a stored detection's embedding into the reference set. The detection must already be assigned to an identity; it must be a face type with a stored embedding.
POST /api/detections/{id}/enroll
curl -X POST \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/detections/42/enroll
# → {"detection_id": 42, "identity_id": 3, "embedding_id": 19, "enrolled": true}
Revoke a detection's reference enrollment without deleting the detection itself.
DELETE /api/detections/{id}/enroll
curl -X DELETE \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/detections/42/enroll
# → {"detection_id": 42, "removed": 1}
Enrolled face reference embeddings. A person's identity can have multiple embeddings — one per enrolled photo. Each embedding is tagged with the model that generated it and is only used for matching when that model is active.
GET /api/face-embeddings
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/face-embeddings?identity_id=3"
# → {"items": [{"id": 17, "identity_id": 3, "label": "Noah",
# "model_id": 1, "model_name": "buffalo_l",
# "detection_id": 42, "source_image_id": 7,
# "created_at": "2026-01-10T08:00:00Z",
# "crop_url": "/media/crops/abc.jpg"}]}
Optional query params: identity_id, model_id.
GET /api/face-embeddings/{id}
curl -H "X-API-Key: argus_..." http://localhost:8100/api/face-embeddings/17
Removes a single reference embedding; does not delete the associated detection.
DELETE /api/face-embeddings/{id}
curl -X DELETE \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/face-embeddings/17
# → {"deleted": 17}
Detects faces and matches them against enrolled people without storing anything (no crops, detections, or review entries). Returns best match per face plus ranked suggestions.
POST /api/identify
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file=@group.jpg" \
http://localhost:8100/api/identify
# → {"threshold": 0.5, "faces": [
# {"bbox": {...}, "confidence": 0.99, "identity_id": 2, "label": "Noah",
# "similarity": 0.71, "suggestions": [...], "age": 9, "gender": "M", "pose": [...]}]}
Optional threshold (override) and top_n (suggestion count) via form field, JSON, or query param.
Runs the face and object engines and returns bounding boxes, counts, and for each face the best
matching enrolled person. Stores nothing and enrolls nothing. Also available
as a UI page at /test.
POST /api/test
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file=@photo.jpg" \
"http://localhost:8100/api/test?type=all"
# → {"faces": [{"bbox": {...}, "confidence": 0.95, "label": "Noah", "similarity": 0.87,
# "identity_id": 2, "age": 30, "gender": "F", "pose": [...]}],
# "objects": [{"bbox": {...}, "confidence": 0.9, "class_name": "person", "class_id": 0}],
# "counts": {"faces": 1, "objects": 1},
# "available": {"faces": true, "objects": true}}
?type=faces|objects|all (default all). An engine with no active model is skipped rather than erroring.
Test many images in one call, still storing nothing. Per-image results; one bad image never fails the rest (max 100 per call).
POST /api/test/batch
curl -X POST \
-H "X-API-Key: argus_..." \
-F "type=all" -F "file=@a.jpg" -F "file=@b.jpg" \
http://localhost:8100/api/test/batch
# → {"total": 2, "type": "all", "results": [
# {"index": 0, "filename": "a.jpg", "faces": [...], "objects": [...], ...},
# {"index": 1, "filename": "b.jpg", "error": "..."}]}
Compares two images directly. Stores nothing.
POST /api/verify
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file1=@a.jpg" -F "file2=@b.jpg" \
http://localhost:8100/api/verify
# → {"similarity": 0.83, "match": true, "threshold": 0.5,
# "face1": {"bbox": {...}, "confidence": 0.99, "age": 31, "gender": "F", "pose": [...]},
# "face2": {...}}
Each image is one of file{1,2} / image{1,2}_url / image{1,2}_base64. Optional threshold override.
Face detections include age, gender ("M"/"F"),
and pose ([pitch, yaw, roll] in degrees) when the active model
provides them — all three bundled packs (buffalo_l, buffalo_s,
antelopev2) do. Any value the model doesn't produce comes back as
null. These fields are API-only and not displayed in the UI.
An identity is a named person or object class. Every detection is either unidentified or assigned to an identity. Identities scoped to the caller's user and environment.
GET /api/identities
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/identities?type=face&limit=50"
# → {"items": [{"id": 3, "type": "face", "label": "Alice",
# "external_ref": "person_alice", "cover_detection_id": 101,
# "created_at": "2026-01-10T08:00:00Z"}],
# "next_cursor": "Alice", "has_more": false}
Optional params: type (face | object),
q (name search), external_ref (exact match),
cursor, limit. Omit limit to get all
identities unpaginated.
GET /api/identities/summary
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/identities/summary?type=face"
# → {"items": [{"id": 3, "type": "face", "label": "Alice",
# "external_ref": "person_alice", "cover_detection_id": 101,
# "created_at": "...", "detection_count": 42,
# "embedding_count": 5,
# "thumbnail_url": "/media/crops/abc123.jpg"}],
# "next_cursor": "Alice", "has_more": true, "total": 8}
Same filters as /api/identities. Used by the dashboard grid — includes counts and thumbnail URL per identity.
GET /api/identities/{id}
curl -H "X-API-Key: argus_..." http://localhost:8100/api/identities/3
# → {"id": 3, "type": "face", "label": "Alice", "external_ref": "person_alice",
# "cover_detection_id": 101, "created_at": "...",
# "detection_count": 42, "embedding_count": 5,
# "pending_review_count": 2, "thumbnail_url": "/media/crops/abc123.jpg"}
POST /api/identities
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"label": "Alice", "type": "face", "external_ref": "person_alice"}' \
http://localhost:8100/api/identities
# → 201 {"id": 3, "type": "face", "label": "Alice", "external_ref": "person_alice"}
Returns 409 if a label + type identity already exists in this environment.
PUT /api/identities/{id}
curl -X PUT \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"label": "Alice Smith"}' \
http://localhost:8100/api/identities/3
# → {"id": 3, "label": "Alice Smith"}
PUT /api/identities/{id}/external_ref
curl -X PUT \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"external_ref": "my-app-person-7"}' \
http://localhost:8100/api/identities/3/external_ref
# → {"id": 3, "external_ref": "my-app-person-7"}
PUT /api/identities/{id}/cover
curl -X PUT \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"detection_id": 101}' \
http://localhost:8100/api/identities/3/cover
# → {"identity_id": 3, "cover_detection_id": 101}
The detection must belong to this identity.
Deletes the identity and all its detections, crops, and embeddings.
DELETE /api/identities/{id}
curl -X DELETE \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/identities/3
# → 204 No Content
DELETE /api/identities
curl -X DELETE \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"identity_ids": [3, 5, 7]}' \
http://localhost:8100/api/identities
# → {"deleted": 3}
Combine two identities when the same person was enrolled under different names. All detections and enrolled face references are moved to the target; the source is deleted.
POST /api/identities/{id}/merge
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"into": 5}' \
http://localhost:8100/api/identities/12/merge
# → {"merged_into": 5, "deleted": 12}
Cursor-paginated detection crops for an identity. Used by the identity gallery page.
GET /api/identities/{id}/gallery
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/identities/3/gallery?limit=30"
# → {"items": [{"detection_id": 101, "crop_url": "/media/crops/abc.jpg",
# "source_image_id": 7, "detected_at": "...",
# "confidence": 0.98, "review_status": "confirmed"}],
# "next_cursor": "2026-01-15T10:30:00Z_101", "has_more": true}
Pagination: ?cursor=<detected_at>_<id>&limit=N.
Optional sort: newest (default) | oldest.
Detections that were rejected from this identity (for re-review or deletion).
GET /api/identities/{id}/rejected
curl -H "X-API-Key: argus_..." \
http://localhost:8100/api/identities/3/rejected
# → {"items": [{"detection_id": 88, "crop_url": "...", ...}]}
GET /api/detections/{id}
curl -H "X-API-Key: argus_..." http://localhost:8100/api/detections/42
# → {"id": 42, "type": "face", "source_image_id": 7,
# "bbox": {"x": 120, "y": 80, "w": 60, "h": 75}, "confidence": 0.98,
# "identity_id": 3, "label": "Alice", "review_status": "confirmed",
# "crop_url": "/media/crops/abc.jpg", "detected_at": "..."}
Assign or correct a detection's identity. Works for both face and object detections. This is the single endpoint shared by all "fix this label" UI surfaces.
PUT /api/detections/{id}/label
# Relabel to a name (creates identity if it doesn't exist)
curl -X PUT \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"label": "Sarah"}' \
http://localhost:8100/api/detections/42/label
# Assign to an existing identity by id
curl -X PUT \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"identity_id": 5}' \
http://localhost:8100/api/detections/42/label
Relabel many detections in one call. Per-item results; one bad item never fails the rest.
POST /api/detections/label
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"items": [{"detection_id": 1, "label": "park bench"},
{"detection_id": 2, "identity_id": 5}]}' \
http://localhost:8100/api/detections/label
# → {"results": [{"detection_id": 1, "ok": true},
# {"detection_id": 2, "ok": true}]}
Current state of many detections in one round-trip. Unknown ids are simply absent from the response.
POST /api/detections/query
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"detection_ids": [1, 2, 3]}' \
http://localhost:8100/api/detections/query
# → {"items": [{"id": 1, ...}, {"id": 2, ...}]}
Moves a detection out of the review queue without assigning an identity.
POST /api/detections/dismiss
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"detection_ids": [42, 43]}' \
http://localhost:8100/api/detections/dismiss
# → {"dismissed": 2}
DELETE /api/detections/{id}
curl -X DELETE \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/detections/42
# → {"deleted": 42, "source_image_discarded": false}
If this was the last detection on its source image, the source image (and its file if no other
row references it) is auto-discarded. source_image_discarded is true
in that case.
POST /api/detections/delete
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"detection_ids": [40, 41, 42]}' \
http://localhost:8100/api/detections/delete
# → {"deleted": 3, "source_images_discarded": 1}
Paginated list of face detections with no identity assigned.
GET /api/detections/unknown
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/detections/unknown?limit=30"
# → {"items": [...], "next_cursor": "...", "has_more": true}
The review queue holds face detections that matched an enrolled person but fell below the auto-confirm threshold, or that have no match at all. See Concepts for threshold details.
GET /api/review
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/review?limit=30"
# → {"items": [{"detection_id": 303, "crop_url": "...",
# "source_image_id": 10, "source_image_url": "...",
# "confidence": 0.8514,
# "bbox": {"x": 90, "y": 60, "w": 55, "h": 70},
# "detected_at": "...",
# "current_identity": null,
# "suggested_matches": [
# {"identity_id": 3, "label": "Alice", "similarity": 0.7823}]}],
# "next_cursor": "0.8514_303", "has_more": false}
Pagination: ?cursor=<confidence>_<id>&limit=N. Items are sorted
by confidence descending. Optional has_suggestion=true to show only items with at
least one ranked match.
GET /api/review/count
curl -H "X-API-Key: argus_..." http://localhost:8100/api/review/count
# → {"count": 14}
Optional has_suggestion=true to count only items with a suggested match.
Mark a detection as confirmed, accepting the current or a new identity assignment.
POST /api/review/{id}/confirm
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"identity_id": 3}' \
http://localhost:8100/api/review/303/confirm
# → {"detection_id": 303, "review_status": "confirmed", "identity_id": 3, "enrolled": true}
Human confirmations always enroll the embedding unconditionally, regardless of detection quality.
Remove the current identity assignment without deleting the detection — returns it to the unidentified pool.
POST /api/review/{id}/unassign
curl -X POST \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/review/303/unassign
# → {"detection_id": 303, "review_status": "pending"}
Mark a detection as rejected from its current identity (removes assignment, flags as rejected).
POST /api/review/{id}/reject
curl -X POST \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/review/303/reject
# → {"detection_id": 303, "review_status": "rejected"}
Move a rejected detection back to pending review.
POST /api/review/{id}/restore
curl -X POST \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/review/303/restore
# → {"detection_id": 303, "review_status": "pending"}
Assign a detection to a different identity (or create a new one by name).
POST /api/review/{id}/reassign
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"identity_id": 5}' \
http://localhost:8100/api/review/303/reassign
# → {"detection_id": 303, "review_status": "confirmed", "identity_id": 5}
POST /api/review/bulk
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"detection_ids": [303, 304, 305], "action": "confirm", "identity_id": 3}' \
http://localhost:8100/api/review/bulk
# → {"processed": 3, "failed": 0}
action is one of: confirm, reject,
unassign, restore, reassign.
identity_id is required for confirm and reassign.
Confirmed face detections whose embedding scores poorly against their current identity's representative — likely mislabels. Sorted worst-first.
GET /api/review/mismatches
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/review/mismatches?threshold=0.5"
# → {"items": [{"detection_id": 42, "crop_url": "...",
# "source_image_id": 7, "confidence": 0.91,
# "bbox": {...}, "detected_at": "...",
# "current_identity": {"identity_id": 3, "label": "Alice"},
# "similarity": 0.31}],
# "count": 1, "threshold": 0.5}
Optional threshold override (default: the active face.match_threshold setting).
POST /api/review/mismatches/{id}/dismiss
curl -X POST \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/review/mismatches/42/dismiss
# → {"detection_id": 42, "mismatch_reviewed": true}
POST /api/review/mismatches/dismiss
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"detection_ids": [42, 43, 44]}' \
http://localhost:8100/api/review/mismatches/dismiss
# → {"dismissed": 3}
Unsupervised groupings of unidentified face detections. See Concepts for how clustering works.
GET /api/clusters
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/clusters?threshold=0.5"
# → {"clusters": [{"cluster_id": "cluster_001",
# "size": 12,
# "items": [{"detection_id": 55, "crop_url": "...",
# "confidence": 0.97, "detected_at": "..."},
# ...]}],
# "total_unclustered": 4, "threshold": 0.5}
Optional threshold (default: face.cluster_threshold setting), limit.
GET /api/clusters/count
curl -H "X-API-Key: argus_..." http://localhost:8100/api/clusters/count
# → {"count": 7, "threshold": 0.5}
Async operations (bulk detection, bulk reprocess) run as jobs. Poll for status or register a
job.done webhook.
GET /api/jobs
curl -H "X-API-Key: argus_..." http://localhost:8100/api/jobs
# → {"items": [{"id": 7, "type": "bulk_detect", "status": "done",
# "total": 50, "done": 50, "failed": 0,
# "created_at": "...", "finished_at": "..."}]}
GET /api/jobs/{id}
curl -H "X-API-Key: argus_..." http://localhost:8100/api/jobs/7
# → {"id": 7, "type": "bulk_detect", "status": "running",
# "total": 50, "done": 23, "failed": 1,
# "created_at": "...", "finished_at": null}
status is one of: pending · running · done · failed.
Remove a completed job record. Does not cancel a running job.
DELETE /api/jobs/{id}
curl -X DELETE \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/jobs/7
# → 204 No Content
GET /api/images
See Image filtering for the full query parameter reference.
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/images?type=face&limit=30"
# → {"items": [{"id": 7, "external_ref": "img_abc123",
# "file_path": "abc456.jpg", "width": 1920, "height": 1080,
# "uploaded_at": "...", "detection_count": 3,
# "source_image_url": "/media/sources/abc456.jpg"}],
# "next_cursor": "...", "has_more": true}
All face detections for a source image, including bboxes, labels, embeddings, and attributes.
GET /api/images/{id}/faces
curl -H "X-API-Key: argus_..." \
http://localhost:8100/api/images/7/faces
# → {"source_image_id": 7, "external_ref": "img_abc123",
# "width": 1920, "height": 1080, "uploaded_at": "...",
# "source_image_url": "/media/sources/abc456.jpg",
# "scene_tags": [],
# "faces": [{"detection_id": 101,
# "bbox": {"x": 120, "y": 80, "w": 60, "h": 75},
# "confidence": 0.98, "identity_id": 3, "label": "Alice",
# "crop_url": "/media/crops/abc123.jpg",
# "review_status": "confirmed", "embedding_source": "aligned",
# "age": 32, "gender": "F", "pose": [1.2, -0.3, 0.1]}]}
Add a hand-drawn bounding box to an existing source image. Use this when the automatic detector missed a face or object you want to tag.
POST /api/images/{id}/detections
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"type": "face", "bbox": {"x": 120, "y": 80, "w": 60, "h": 75},
"label": "Alice"}' \
http://localhost:8100/api/images/7/detections
# → {"detection_id": 210, "identity_id": 3, "label": "Alice",
# "crop_url": "/media/crops/manual_xyz.jpg", "is_manual": true}
Re-run detection on a previously stored image using the currently active models. Useful after switching to a better model.
POST /api/images/{id}/reprocess
# Re-detect all (keeps existing)
curl -X POST \
-H "X-API-Key: argus_..." \
"http://localhost:8100/api/images/42/reprocess?type=all"
# Replace existing face detections
curl -X POST \
-H "X-API-Key: argus_..." \
"http://localhost:8100/api/images/42/reprocess?type=faces&replace=true"
# Async
curl -X POST \
-H "X-API-Key: argus_..." \
"http://localhost:8100/api/images/42/reprocess?type=all&replace=true&async=true"
# → {"job_id": 8, "status": "pending"}
Re-run detection on a set of source images, using the currently active models.
POST /api/images/reprocess
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"source_image_ids": [7, 8, 9], "type": "all", "replace": true}' \
"http://localhost:8100/api/images/reprocess?async=true"
# → {"job_id": 9, "status": "pending", "total": 3}
Deletes the source image row, all its detections, and all crops. The source file is only deleted from disk if no other source image row references the same content hash.
DELETE /api/images/{id}
curl -X DELETE \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/images/42
# → {"source_image_id": 42, "detections_deleted": 5, "crops_removed": 5}
Query the source image list with filters. All params are optional and combinable.
| Param | Type | Description |
|---|---|---|
identity_id | int (repeatable) | Images containing this identity (AND across multiple) |
type | face | object | Only images with detections of this type |
external_ref | string | Exact match on the caller's own id |
since / until | ISO timestamp | Upload date range |
no_detections | bool | Images with zero detections |
no_tagged_faces | bool | Images where no face has been identified |
no_crops | bool | Images with no stored crop files |
has_manual_detections | bool | Images with at least one manually drawn detection |
sort | string | newest | oldest | most_detections | fewest_detections |
cursor / limit | string / int | Cursor pagination |
# Images containing identity 5
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/images?identity_id=5"
# Face-detection images from a date range
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/images?type=face&since=2025-01-01T00:00:00&until=2025-12-31T23:59:59"
Companion endpoints: GET /api/images/count returns the matching total;
GET /api/images/ids returns all matching IDs (no pagination, for select-all
operations).
Manage face and object detection models. Models can be downloaded, activated, and hot-swapped without restarting. All model management is also available via the Models page in the UI.
# List all models
curl -H "X-API-Key: argus_..." http://localhost:8100/api/models
# Get one model
curl -H "X-API-Key: argus_..." http://localhost:8100/api/models/1
# Download a model (returns job_id)
curl -X POST \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/models/1/download
# Activate a model (hot-swaps in-process, no restart needed)
curl -X PUT \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/models/1/activate
Activating a model replaces the running engine live. In-flight detection calls are not interrupted — a lock ensures they complete against the old model before the swap.
All settings are live — changes take effect immediately. See the Settings reference for the full list of keys and defaults.
# Get a setting
curl -H "X-API-Key: argus_..." \
http://localhost:8100/api/settings/face.match_threshold
# → {"key": "face.match_threshold", "value": 0.5}
# Update a setting
curl -X PUT \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"value": 0.6}' \
http://localhost:8100/api/settings/face.match_threshold
# List all settings
curl -H "X-API-Key: argus_..." http://localhost:8100/api/settings
HTTP callbacks fired when events occur. Per-environment, filterable by event type. Manage from the UI at Account → Webhooks.
Supported events: detection.created ·
detection.labeled · detection.deleted ·
identity.created · identity.updated ·
identity.deleted · identity.merged · job.done
# Register
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://my-server.local/hooks/argus", "events": ["job.done"],
"label": "job alerts", "secret": "mysecret"}' \
http://localhost:8100/api/webhooks
# List
curl -H "X-API-Key: argus_..." http://localhost:8100/api/webhooks
# Disable temporarily
curl -X PUT \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"is_active": false}' \
http://localhost:8100/api/webhooks/1
# Test ping — returns {ok, status_code, duration_ms, error}
curl -X POST \
-H "X-API-Key: argus_..." \
http://localhost:8100/api/webhooks/1/test
# Delivery history (last 50, newest first)
curl -H "X-API-Key: argus_..." http://localhost:8100/api/webhooks/1/deliveries
When a secret is set, each request carries an
X-Argus-Signature: sha256=<hmac> header computed over the JSON body.
Verify it on your server to confirm the call is from Argus.
GET /api/search
Search enrolled identities by name using FTS5 trigram matching — handles partial names, case-insensitive, near-misses.
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/search?q=alice"
# Faces only, up to 20 results
curl -H "X-API-Key: argus_..." \
"http://localhost:8100/api/search?q=john&type=face&limit=20"
Export recognition data (identities, embeddings, detections, images) and import into another instance. Imports merge by identity name — existing identities receive additional detections and embeddings rather than being duplicated.
POST /api/export
POST /api/import
# Export selected identities
curl -X POST \
-H "X-API-Key: argus_..." \
-H "Content-Type: application/json" \
-d '{"identity_ids": [1, 2, 3]}' \
http://localhost:8100/api/export \
--output argus_export.zip
# Import into another instance
curl -X POST \
-H "X-API-Key: argus_..." \
-F "file=@argus_export.zip" \
http://localhost:8100/api/import
Also available via Account page in the UI.