Repositories
All routes are under /api/v1/repositories/{repoID}.
export API=https://cavsnode.com/api/v1export REPO=<repository-uuid>export H="Authorization: Bearer $CAVS_TOKEN"The record
Section titled “The record”| Endpoint | Permission | |
|---|---|---|
| GET | /repositories/{repoID} |
repository.pull |
| PATCH | /repositories/{repoID} |
repository.update |
| DELETE | /repositories/{repoID} |
repository.admin |
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.
Usage, objects, transfers
Section titled “Usage, objects, transfers”| 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 |
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.
Git index reads
Section titled “Git index reads”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 |
— |
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.
Releases
Section titled “Releases”| Endpoint | Permission | |
|---|---|---|
| GET | /repositories/{repoID}/releases |
repository.pull |
| GET | /repositories/{repoID}/releases/{tag} |
repository.pull |
| PATCH | /repositories/{repoID}/releases/{tag} |
repository.update |
curl -sS "$API/repositories/$REPO/releases?limit=50" -H "$H" # limit 1–200, default 50curl -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.
Artifacts
Section titled “Artifacts”| Endpoint | |
|---|---|
| GET | /repositories/{repoID}/artifacts/{oid} |
| GET | /repositories/{repoID}/artifacts/{oid}/timeline |
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.
Lineage graph
Section titled “Lineage graph”| Endpoint | Permission | |
|---|---|---|
| GET | /repositories/{repoID}/graph |
repository.pull |
| POST | /repositories/{repoID}/graph/edges |
repository.update |
| DELETE | /repositories/{repoID}/graph/edges/{edgeID} |
repository.update |
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.
Snapshots
Section titled “Snapshots”| Endpoint | Permission | |
|---|---|---|
| GET | /repositories/{repoID}/snapshots |
repository.pull |
| POST | /repositories/{repoID}/snapshots |
repository.push |
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.
Health, recommendations, activity
Section titled “Health, recommendations, activity”| 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 |
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"Storage analytics
Section titled “Storage analytics”| 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) |
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.
Collaborators
Section titled “Collaborators”| Endpoint | Permission | |
|---|---|---|
| GET | /repositories/{repoID}/members |
repository.members.manage |
| POST | /repositories/{repoID}/members |
repository.members.manage |
| DELETE | /repositories/{repoID}/members/{userID} |
repository.members.manage |
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.
Invitations
Section titled “Invitations”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 |
curl -sS -X POST "$API/repositories/$REPO/invitations" \ -H "$H" -H "Content-Type: application/json" \See Invitations & collaborators.
Data plane
Section titled “Data plane”Documented separately:
- Upload sessions —
/uploads… - Downloads —
/downloads/authorize - Git LFS endpoints —
/lfs… - Git index ingest —
/index…
- Endpoint index — everything in one table.
- Repositories guide — the task-oriented version.

