Docs
Search docs

Get a workspace's storage usage

GET/api/owners/{handle}/storage/usage

getOwnerStorageUsage

The owner's workspace storage: `bytes_used` is the larger of the counters the storage quota gates charge and `bytes_quota` the allowance they compare against; the workspace is full once `bytes_used` reaches it. Branch tips (deleted, overwritten or reverted) whose objects are still retained (and counted in `bytes_used`) are `retained_branch_count`; the first can be released from `earliest_retention_expiry` on. `retained_bytes` is the stored size only those tips hold, as last measured (already inside `bytes_used`), or null while one of them is not measured yet. Requires workspace membership (non-members get 404).

Authentication is not described for this operation in the spec — that does not mean it is public. Check tokens and scopes.

curl

curl -X GET 'https://neosource.dev/api/owners/HANDLE/storage/usage'

fetch

fetch("https://neosource.dev/api/owners/HANDLE/storage/usage", {
  method: "GET",
});

Path parameters

handlerequired

Handle of the owner — either a user account or an organization.

string

Responses

200Storage usage

application/json

OwnerStorageUsageResponse

object

`GET /api/owners/{handle}/storage/usage` — the workspace's storage against its allowance, with retained branch tips as their own line.

bytes_quotarequired

integerint64

The workspace's storage allowance in bytes. Each gate refuses a write that would take its own counter past it, so once `bytes_used` reaches it some writes that add data are refused; which ones depends on the counter that is full.

bytes_usedrequired

integerint64

Bytes the workspace is charged for. Different writes are admitted against `bytes_quota` on different counters: pushes and mirror fetches on the repositories' logical bytes and on the stored bytes the workspace owns; packages, CI artifacts, releases, imports and forks on the stored bytes owned alone; issue and pull-request attachments on the stored bytes owned plus attachments. This is the larger of the logical bytes and owned-plus-attachments, so it reaches `bytes_quota` whenever at least one of those gates is full, which need not be the gate a given write passes through. Includes the bytes retained branch tips still hold.

earliest_retention_expiry

integer | nullint64

When the first of those retentions ends (Unix epoch milliseconds), from which its bytes can be released. Not a promise that they are: they leave `bytes_used` only once compaction rewrites the packs holding them, and not at all while anything else still reaches them. `None` when `retained_branch_count` is 0. May lie in the past: an expired retention is dropped by a background sweep, and is counted until it is.

retained_branch_countrequired

integerint64

Abandoned branch tips (a branch deleted, overwritten on a mirror, or removed by reverting the push that created it) whose objects are retained and still counted in `bytes_used`. One per distinct tip per repository: two deleted branches on one commit count once. Tips another branch still reaches retain nothing and are not counted once the compactor has classified them. Their size is `retained_bytes`.

retained_bytes

integer | nullint64

Stored (compressed) bytes that only those retained tips still hold, as the compactor last measured them: objects no branch, tag or other retention reaches. Already counted in `bytes_used`, not charged on top of it. 0 when `retained_branch_count` is 0. `None` while one of the counted tips has not been measured yet (a branch deleted since the compactor last looked at its repository, say). Measured, not live: after a retention ends, or a branch moves, the figure stays as measured until the compactor next looks at that repository.

403Forbidden — one of: forbidden, needs_scope

application/json

one of
  • ErrorForbidden
  • NeedsScopeError

    object

    `403` body returned when a classic OAuth token is asked for something its granted scopes do not cover — an explicit private listing without `repo`, or the one-click GitHub mirror without `admin:public_key`. `scope` names the missing grant so the client can say exactly what the token lacks. There is no elevation route to widen it any more (a re-link goes through the GitHub App, whose tokens carry no scopes), so the client's answer is to say so, never to start a handshake.

    errorrequired

    string

    Always `needs_scope` — this body exists to carry the extra fields that kind needs.

    "needs_scope"

    scoperequired

    string

    The provider scope to request via elevation (e.g. `"repo"`).

Standard errors

Bodies documented once for the whole API — see standard errors.

  • 400Bad Request — one of: invalid_input
  • 404Not Found — one of: not_found
  • 429Rate limited — retry after the `Retry-After` header
  • 500Internal server error
  • 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
  • 504Gateway timeout — the request exceeded the server's handling budget