Skip to main content
GET
Get Workspace Stats

Authorizations

X-API-Key
string
header
required

Headers

X-Workspace-Id
string | null

Path Parameters

workspace_id
string<uuid>
required

Cookies

riftmap_access
string | null

Response

Successful Response

Per-connected-org stats payload (scoped to one connected org).

Artifact-count semantics. Every count is a raw artifact-row count — no canonical-name dedup — restricted to first-party artifacts: rows a forked repo produces only because it kept the upstream project's package identity are excluded and counted separately (issue #258; is_first_party_artifact in src/resolver/fork_alias.py is the single source of truth, cached on artifacts.is_first_party). Consumption is computed by the single source of truth src/graph/artifact_stats.py (the type-matched union), so an artifact's orphan status here always matches its is_orphan on GET /connected-orgs/{id}/artifacts:

  • total_artifact_rows — first-party artifact rows. Equals the X-Total-Count header of GET /connected-orgs/{id}/artifacts with its default include_upstream_aliases=false.
  • upstream_alias_artifact_count — the rows that filter excludes. Add it to total_artifact_rows for every row the org has, which is what ?include_upstream_aliases=true returns and what a disconnect deletes.
  • orphan_artifact_count — first-party rows with zero consumers (consumer_count == 0). Equals the count of is_orphan==true rows on the artifacts endpoint and the Artifacts page "Hide orphans (N)" toggle.
  • consumed_artifact_count — first-party rows with at least one consumer (== total_artifact_rows - orphan_artifact_count).
  • artifact_type_breakdownfirst-party artifact rows grouped by artifact_type (includes every type present; never drops one). Invariant: sum(artifact_type_breakdown.values()) == total_artifact_rows.

total_declarations vs total_dependencies: the former counts every manifest-context dependency declaration parsed out of the org's repos, the latter counts the deduped cross-repo edges those declarations resolved to. The gap between them is the org's coverage story — Patrimore parsed 4,390 and got 9 edges — and naming both numbers is what lets a near-empty graph explain itself instead of reading as a broken product (issue #225).

declaration_outcomes breaks that gap down: it partitions the same total_declarations population into why each declaration did or did not become an edge, so a large gap can be read as the ~99% correct rejections it usually is rather than as a failure count (issue #264). It replaced health, whose unresolved_declarations was that misreadable number and whose other two fields were hardcoded zeros; the real on-latest / lagging figures live on GET /artifacts/{id}/consumers.

artifact_type_breakdown
Artifact Type Breakdown · object
required
consumed_artifact_count
integer
required
declaration_outcomes
DeclarationOutcomes · object
required

What became of every dependency declaration parsed from the org (issue #264).

Five mutually exclusive buckets over the same population as total_declarations — manifest-context declarations, scoped per repo to its current_scan_id. They sum to total_declarations.

Replaces health.unresolved_declarations, which counted every unresolved declaration regardless of why, named the result as if it were a failure count, and — because it was computed over all reference contexts while total_declarations is manifest-only — could exceed the total it was shown against (cloudposse: 13,225 unresolved against 6,374 total).

Only unresolved_in_org means "Riftmap may have missed something". The other three non-resolved buckets are correct rejections: a third-party package is supposed to stay unresolved, a workspace: dependency lives in the same repo by definition, and a repo importing its own subpackage is not a cross-repo edge. Measured across all 321,445 production declarations on 2026-09-12: 86.13% external, 4.73% resolved_in_org, 4.46% local_reference, 3.86% self_reference, 0.81% unresolved_in_org. Those are platform shares — a single org can sit far from them, so do not read the platform figure as a per-org expectation. They predate v1.25.0, which counts every repeated declaration of a reference (a second uses: of one action in a workflow, a package listed as both a dev and a peer dependency), so every bucket rises for an org once it is rescanned.

resolved_in_org is normally larger than total_dependencies, and that is not a bug: it counts declarations, while total_dependencies counts deduped graph edges. A declaration is not an edge — read-time DISTINCT ON collapses declarations that share a (source, target, dependency_type) key, self-edges are excluded from the graph, and an artifact target with no producing repo renders no edge.

Classification is owned by src/graph/declaration_outcomes.py — the single source of truth, which also documents what these buckets structurally cannot see (a fork-alias rejection lands in external).

dependency_type_breakdown
Dependency Type Breakdown · object
required
last_scan
LastScanSummary · object | null
required

Summary of the most recent scan.

orphan_artifact_count
integer
required
total_artifact_rows
integer
required
total_declarations
integer
required
total_dependencies
integer
required
total_repositories
integer
required
upstream_alias_artifact_count
integer
default:0