Skip to content

Repositories

All routes are under /api/v1/repositories/{repoID}.

Terminal window
export API=https://cavsnode.com/api/v1
export REPO=<repository-uuid>
export H="Authorization: Bearer $CAVS_TOKEN"
Endpoint Permission
GET /repositories/{repoID} repository.pull
PATCH /repositories/{repoID} repository.update
DELETE /repositories/{repoID} repository.admin
Terminal window
curl -sS "$API/repositories/$REPO" -H "$H"
curl -sS -X PATCH "$API/repositories/$REPO" \
-H "$H" -H "Content-Type: application/json" \
-d '{"description": "Production checkpoints only", "visibility": "INTERNAL"}'

Mutable: description, visibility, default branch, storage_group_id. Immutable: storage_mode and storage_connection_id — chosen at creation.

Endpoint Notes
GET /repositories/{repoID}/usage Logical, physical, object count, egress, generation
GET /repositories/{repoID}/objects The raw data-plane view — no index needed
GET /repositories/{repoID}/transfers Measured push/pull benchmarks
GET /repositories/{repoID}/connect Copy-paste setup instructions
Terminal window
curl -sS "$API/repositories/$REPO/usage" -H "$H"
curl -sS "$API/repositories/$REPO/objects?sort=recent&limit=50&skip=0" -H "$H"
curl -sS "$API/repositories/$REPO/objects?sort=size&limit=20" -H "$H"
curl -sS "$API/repositories/$REPO/transfers?kind=push&limit=10" -H "$H"
curl -sS "$API/repositories/$REPO/connect" -H "$H"
Parameter Endpoint Values Default
sort objects recent, size recent
limit, skip objects 50, 0
kind transfers push, pull both
limit transfers 50

Each object: {oid, size, physical_size, chunk_count, created_at, downloads}.

transfers records only exist for transfers the CAVS agent handled. Empty means standard git-lfs or direct API uploads.

These read the Git index. Un-indexed repositories return "indexed": false rather than an error.

Endpoint Parameters
GET /repositories/{repoID}/overview
GET /repositories/{repoID}/tree ref, path
GET /repositories/{repoID}/file ref, path
GET /repositories/{repoID}/file/history path, limit (1–200, default 50)
GET /repositories/{repoID}/commits path, limit (1–200, default 50), before
GET /repositories/{repoID}/commits/{sha}
GET /repositories/{repoID}/branches
Terminal window
curl -sS "$API/repositories/$REPO/tree?ref=main&path=checkpoints/v3" -H "$H"
curl -sS "$API/repositories/$REPO/file?ref=main&path=model.safetensors" -H "$H"
curl -sS "$API/repositories/$REPO/file/history?path=model.safetensors&limit=50" -H "$H"
curl -sS "$API/repositories/$REPO/commits?path=checkpoints&limit=20" -H "$H"
curl -sS "$API/repositories/$REPO/commits?before=2026-07-01T00:00:00Z" -H "$H"
curl -sS "$API/repositories/$REPO/commits/9a3f21c" -H "$H"
curl -sS "$API/repositories/$REPO/branches" -H "$H"

ref defaults to the repository’s default branch; path to the root. before is an RFC 3339 cursor. Branches carry health flags — stale (> 30 days without a commit) and oversized (> 2× the default branch’s footprint).

Permission for all of these: repository.pull.

Endpoint Permission
GET /repositories/{repoID}/releases repository.pull
GET /repositories/{repoID}/releases/{tag} repository.pull
PATCH /repositories/{repoID}/releases/{tag} repository.update
Terminal window
curl -sS "$API/repositories/$REPO/releases?limit=50" -H "$H" # limit 1–200, default 50
curl -sS "$API/repositories/$REPO/releases/v1.4.0" -H "$H"
curl -sS -X PATCH "$API/repositories/$REPO/releases/v1.4.0" \
-H "$H" -H "Content-Type: application/json" \
-d '{"name": "Vision 1.4.0", "notes": "## Changes\n- Retrained\n"}'

Releases come from Git tags during indexing. The tag and commit are immutable; name and notes are editable and notes renders as Markdown. See Releases & snapshots.

Endpoint
GET /repositories/{repoID}/artifacts/{oid}
GET /repositories/{repoID}/artifacts/{oid}/timeline
Terminal window
curl -sS "$API/repositories/$REPO/artifacts/$OID" -H "$H"
curl -sS "$API/repositories/$REPO/artifacts/$OID/timeline" -H "$H"

The detail view is an object seen through the index — sizes, chunk count, downloads, and the paths, commits and releases referencing it. The timeline is its provenance: first appearance, each commit, each release.

Endpoint Permission
GET /repositories/{repoID}/graph repository.pull
POST /repositories/{repoID}/graph/edges repository.update
DELETE /repositories/{repoID}/graph/edges/{edgeID} repository.update
Terminal window
curl -sS "$API/repositories/$REPO/graph" -H "$H"
curl -sS -X POST "$API/repositories/$REPO/graph/edges" \
-H "$H" -H "Content-Type: application/json" \
-d '{
"from_type": "artifact", "from_key": "aa11bb22…",
"to_type": "artifact", "to_key": "9f2c8b0e…",
"relation": "trained-with"
}'

from_type / to_type must be artifact or release. Keys are an oid for artifacts and a tag for releases. relation is free-form and required. Inferred contains edges (release → artifact) have no id and can’t be deleted. See Lineage graph.

Endpoint Permission
GET /repositories/{repoID}/snapshots repository.pull
POST /repositories/{repoID}/snapshots repository.push
Terminal window
curl -sS "$API/repositories/$REPO/snapshots?limit=50" -H "$H"
curl -sS "$API/repositories/$REPO/snapshots?before=2026-07-01T00:00:00Z" -H "$H"
curl -sS -X POST "$API/repositories/$REPO/snapshots" \
-H "$H" -H "Content-Type: application/json" \
-H "Idempotency-Key: monthly-2026-07" \
-d '{"ref": "main"}'

Asynchronous — the call queues the capture and storage.snapshot.created fires when it completes.

Endpoint Parameters
GET /repositories/{repoID}/health
GET /repositories/{repoID}/recommendations status = open | dismissed
POST /repositories/{repoID}/recommendations/{recID}/dismiss repository.update
GET /repositories/{repoID}/activity limit (1–200), skip (0–10000), type, actor
Terminal window
curl -sS "$API/repositories/$REPO/health" -H "$H"
curl -sS "$API/repositories/$REPO/recommendations?status=open" -H "$H"
curl -sS -X POST "$API/repositories/$REPO/recommendations/$REC/dismiss" -H "$H"
curl -sS "$API/repositories/$REPO/activity?limit=50&type=push" -H "$H"
Endpoint Parameters
GET /repositories/{repoID}/storage/summary
GET /repositories/{repoID}/storage/series days (1–365, default 90)
GET /repositories/{repoID}/storage/folders ref, depth (1–5, default 1), limit (1–100, default 20)
Terminal window
curl -sS "$API/repositories/$REPO/storage/summary" -H "$H"
curl -sS "$API/repositories/$REPO/storage/series?days=90" -H "$H"
curl -sS "$API/repositories/$REPO/storage/folders?depth=3&limit=20" -H "$H"

storage/folders walks the indexed tree, so it needs the Git index. summary and series work regardless.

Endpoint Permission
GET /repositories/{repoID}/members repository.members.manage
POST /repositories/{repoID}/members repository.members.manage
DELETE /repositories/{repoID}/members/{userID} repository.members.manage
Terminal window
curl -sS "$API/repositories/$REPO/members" -H "$H"
curl -sS -X POST "$API/repositories/$REPO/members" \
-H "$H" -H "Content-Type: application/json" \
-d '{"user_id": "77bc…", "access": "WRITE"}'
curl -sS -X DELETE "$API/repositories/$REPO/members/$USER_ID" -H "$H"

access is NONE, READ, WRITE or ADMIN, and overrides the org role for this repository. The list shows the org owner (implicit, not editable) plus explicit collaborator rows.

Invite someone by email to this repository only — they never become an org member.

Endpoint Permission
GET /repositories/{repoID}/invitations repository.members.manage
POST /repositories/{repoID}/invitations repository.members.manage
DELETE /repositories/{repoID}/invitations/{invID} repository.members.manage
Terminal window
curl -sS -X POST "$API/repositories/$REPO/invitations" \
-H "$H" -H "Content-Type: application/json" \
-d '{"email": "[email protected]", "access": "READ"}'

See Invitations & collaborators.

Documented separately: