List repositories owned by the given handle
GET/api/owners/{handle}/repos
listOwnerRepos
Returns the repos in the resolved owner's workspace that the caller can read, in `sort` order (`updated` by default). Keyset-paginated: pass a previous response's `next_cursor` back as `cursor`, with the same `q`, `sort`, `type` and `language`, for the next page. `q` narrows to slugs containing it, case-insensitively; `type` and `language` narrow further. The first page also lists the primary languages of every repo the caller can read here. Without `sort`, a `cursor` continues in the order it was issued for. A malformed `cursor`, a `cursor` from another explicit `sort`, or a `q` or `language` holding a NUL, is a 400.
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/repos'fetch
fetch("https://neosource.dev/api/owners/HANDLE/repos", {
method: "GET",
});Path parameters
handlerequiredHandle of the owner — either a user account or an organization.
Query parameters
qCase-insensitive substring of the repository slug. Matched literally: `%` and `_` are not wildcards.
cursorOpaque pagination cursor from a previous response's `next_cursor`.
limitPage size; default 50, max 100.
default
50sortOrdering: `updated` (the default) is most recently updated first, `name` is slug ascending, `stars` is most stars first. Ties break on slug ascending.
typeNarrow by provenance (`sources`: neither a fork nor a mirror, `forks`, `mirrors`) or visibility (`public`, `internal`, `private`). `all`, the default, narrows nothing.
languageOnly repositories whose `primary_language` is exactly this.
Responses
200Repository list
application/json
403Forbidden — one of: forbidden, needs_scope
application/json
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
Schemas
Referenced above. Listed here rather than expanded inline, so the same definition is not repeated at every level.
MergeMethod
How a pull request's commits land on its target branch. A repo carries two settings over this enum (`migrations/20260820120000_repo_merge_methods.sql`): the set it *permits* (`RepoRecord::allowed_merge_methods`, never empty) and the one the merge path reaches for when the request names none (`RepoRecord::default_merge_method`, always a member of that set — enforced by the settings route, which is the only place both columns are visible at once). `Default` is [`MergeMethod::Merge`] to match the column default, which is itself the pre-existing behaviour of every repo: before this setting existed, a merge always minted a two-parent commit. `Rebase` is deliberately absent rather than merely unimplemented — it replays N commits, can conflict per commit, and rewrites the SHAs the stacked-PR re-parent invariant leans on (`plans/archive/pr-merge-methods-2026-08.md` §"Not doing"). Adding it later is one `ALTER TYPE merge_method ADD VALUE` plus an arm here, which is why the stored shape is an enum array and not a pair of booleans.
"merge""squash"
RepoMirrorStatus
[`RepoResponse::mirror_status`]: how current a `_mirror` repository is.
last_synced_atWhen the daily refresh last synced from the upstream (ms since the epoch); absent before the first sync.
latest_ci- one of
RepoParentInfo
Summary of a fork's parent repository.
repo_idrequired
RepoStatusOutput
Repo lifecycle state surfaced by the API. Mirrors `RepoStatus`. See ADR 0012 §2.
"creating""ready""importing""import_failed"
RepoVisibilityInput
"public""internal""private"