Repo contents
Read-only file/directory access. Mirrors GitHub's
GET /repos/{owner}/{repo}/contents/{path} — one endpoint with
two response shapes depending on whether the path resolves to
a tree (directory) or a blob (file).
Scope: repo:read. Policy gate: ActionRepoRead. See the
common API conventions for JSON errors and rate
limits.
Endpoint
GET /api/v1/repos/{owner}/{repo}/contents/{path}[?ref=]
pathmay contain forward slashes (src/main.go); empty path returns the repo root.refdefaults to the repo'sdefault_branch. Accepts a branch name, tag, or full / unambiguous-prefix commit SHA.
Both /contents (no trailing path) and /contents/ (empty
path) map to "repo root".
The registered path-bearing route literal is
/api/v1/repos/{owner}/{repo}/contents/*.
Directory response
An array of entries, directories first, then files sorted alphabetically:
[
{ "path": "src", "name": "src", "type": "dir", "sha": "5f3a…" },
{ "path": "README.md", "name": "README.md", "type": "file", "size": 132, "sha": "a14b…" },
{ "path": "vendor", "name": "vendor", "type": "submodule", "sha": "9c0d…" }
]
type is one of dir / file / symlink / submodule.
size is only set on file and symlink entries.
File response
{
"path": "README.md",
"name": "README.md",
"type": "file",
"size": 132,
"sha": "a14b…",
"encoding": "base64",
"content": "IyBkZW1vCg==",
"binary": false,
"truncated": false
}
contentis always base64-encoded (matches GitHub). The server detects UTF-8 validity and setsbinary: truewhen the bytes aren't valid UTF-8 — clients can skip rendering binary blobs.- Files larger than 1 MiB return
truncated: truewith an emptycontent. Clients should follow up with the raw blob download path for the full bytes.
Special types
symlinkentries surface their target size and SHA but no body — the bytes are the symlink target string, which the caller can fetch via the file shape if needed.submoduleentries return onlypath/name/type/sha(the recorded commit). Resolving the submodule's tree is the caller's job.
Errors
404— path doesn't exist on the requested ref.403— caller lacksrepo:read(PAT scope) orActionRepoRead(policy) on a private repo.
View source
| 1 | # Repo contents |
| 2 | |
| 3 | Read-only file/directory access. Mirrors GitHub's |
| 4 | `GET /repos/{owner}/{repo}/contents/{path}` — one endpoint with |
| 5 | two response shapes depending on whether the path resolves to |
| 6 | a tree (directory) or a blob (file). |
| 7 | |
| 8 | Scope: `repo:read`. Policy gate: `ActionRepoRead`. See the |
| 9 | [common API conventions](overview.md) for JSON errors and rate |
| 10 | limits. |
| 11 | |
| 12 | ## Endpoint |
| 13 | |
| 14 | ``` |
| 15 | GET /api/v1/repos/{owner}/{repo}/contents/{path}[?ref=] |
| 16 | ``` |
| 17 | |
| 18 | - `path` may contain forward slashes (`src/main.go`); empty |
| 19 | path returns the repo root. |
| 20 | - `ref` defaults to the repo's `default_branch`. Accepts a |
| 21 | branch name, tag, or full / unambiguous-prefix commit SHA. |
| 22 | |
| 23 | Both `/contents` (no trailing path) and `/contents/` (empty |
| 24 | path) map to "repo root". |
| 25 | |
| 26 | The registered path-bearing route literal is |
| 27 | `/api/v1/repos/{owner}/{repo}/contents/*`. |
| 28 | |
| 29 | ## Directory response |
| 30 | |
| 31 | An array of entries, **directories first**, then files sorted |
| 32 | alphabetically: |
| 33 | |
| 34 | ```json |
| 35 | [ |
| 36 | { "path": "src", "name": "src", "type": "dir", "sha": "5f3a…" }, |
| 37 | { "path": "README.md", "name": "README.md", "type": "file", "size": 132, "sha": "a14b…" }, |
| 38 | { "path": "vendor", "name": "vendor", "type": "submodule", "sha": "9c0d…" } |
| 39 | ] |
| 40 | ``` |
| 41 | |
| 42 | `type` is one of `dir` / `file` / `symlink` / `submodule`. |
| 43 | `size` is only set on `file` and `symlink` entries. |
| 44 | |
| 45 | ## File response |
| 46 | |
| 47 | ```json |
| 48 | { |
| 49 | "path": "README.md", |
| 50 | "name": "README.md", |
| 51 | "type": "file", |
| 52 | "size": 132, |
| 53 | "sha": "a14b…", |
| 54 | "encoding": "base64", |
| 55 | "content": "IyBkZW1vCg==", |
| 56 | "binary": false, |
| 57 | "truncated": false |
| 58 | } |
| 59 | ``` |
| 60 | |
| 61 | - `content` is always base64-encoded (matches GitHub). The |
| 62 | server detects UTF-8 validity and sets `binary: true` when |
| 63 | the bytes aren't valid UTF-8 — clients can skip rendering |
| 64 | binary blobs. |
| 65 | - Files larger than **1 MiB** return `truncated: true` with an |
| 66 | empty `content`. Clients should follow up with the raw blob |
| 67 | download path for the full bytes. |
| 68 | |
| 69 | ## Special types |
| 70 | |
| 71 | - `symlink` entries surface their target size and SHA but no |
| 72 | body — the bytes are the symlink target string, which the |
| 73 | caller can fetch via the file shape if needed. |
| 74 | - `submodule` entries return only `path`/`name`/`type`/`sha` |
| 75 | (the recorded commit). Resolving the submodule's tree is the |
| 76 | caller's job. |
| 77 | |
| 78 | ## Errors |
| 79 | |
| 80 | - `404` — path doesn't exist on the requested ref. |
| 81 | - `403` — caller lacks `repo:read` (PAT scope) or |
| 82 | `ActionRepoRead` (policy) on a private repo. |