neosourceDocs
Search docs

Get current import/ingest job status

GET/api/repos/{owner}/{repo}/import-status

getRepositoryImportStatus

Returns the repo's lifecycle status plus a snapshot of the most recent import activity: the newest ingest job when one exists (`phase = "ingest"`, live object counters), else the fetch-phase state synthesized from the import job (`phase = "fetch"`). Sister surface to the `import-progress` SSE stream — same source of truth, single-shot rather than streamed, for first-paint fetches and non-streaming clients (CLI probes, tests). Live updates come from the SSE stream, not from polling this endpoint.

Authentication optional — this operation also accepts anonymous requests. When authenticating, use a bearer token or a session cookie.

curl

curl -X GET 'https://neosource.dev/api/repos/OWNER/REPO/import-status' \
  -H 'Authorization: Bearer $NEOSOURCE_TOKEN'

fetch

fetch("https://neosource.dev/api/repos/OWNER/REPO/import-status", {
  method: "GET",
  headers: {
    Authorization: "Bearer $NEOSOURCE_TOKEN",
  },
});

Path parameters

ownerrequired

Repository owner or organization slug.

string

reporequired

Repository name.

string

Responses

200Import status snapshot

application/json

ImportStatusResponse

object

Response body for `GET /api/repos/{owner}/{repo}/import-status`. `job` is `None` when the repo has no ingest history yet (freshly created, no push ever received). The SPA's polling component uses `repo_status` to decide whether to keep polling. `resolved_fork_of` is `Some` when the import was folded onto an existing canonical (fork-by-reference) — the picker uses it to explain the instant, zero-byte result.

job
one of
  • null

  • ImportJobProgress

    object

    One snapshot of an ingest job's progress. Counters are **object counts** (commits, trees, blobs in the staged pack), not byte counts — the worker writes those as the only progress signal the ingest pipeline exposes today. The field names follow the existing `IngestJobProgress` core type so wire and internal representations match 1:1.

    message

    string | null

    `Some(message)` when `state == Failed` — surfaces the worker's `last_error` to the user.

    objects_processedrequired

    integerint32

    Objects ingested so far. `0` until the worker reports first progress.

    objects_totalrequired

    integerint32

    Total objects in the staged pack. `0` until the pack header has been parsed.

    percentrequired

    numberfloat

    `objects_processed / objects_total`, clamped to `[0.0, 100.0]`. `0.0` until the pack header has been parsed.

    phaserequired
    ImportPhase
    started_at

    integer | nullint64

    When the worker claimed the job. Millis since the Unix epoch. `None` while the job is still `pending`.

    staterequired
    ImportJobState
    updated_at

    integer | nullint64

    Wall-clock time of the most recent progress write. Millis since the Unix epoch. `None` if the job has been claimed but not yet reported.

repo_statusrequired

RepoStatusOutput

string

Repo lifecycle state surfaced by the API. Mirrors `RepoStatus`. See ADR 0012 §2.

"creating""ready""importing""import_failed"

resolved_fork_of
one of
  • null

  • ResolvedForkInfo

    object

    The canonical a GitHub-sync import resolved to a fork of. Present when an import was auto-routed to a fork-by-reference (or the repo is otherwise a fork) — the SPA picker surfaces "this is a fork of `owner/repo` — linked instantly (0 bytes)" instead of implying a full cold import happened.

    ownerrequired

    string

    Canonical owner handle (workspace slug).

    reporequired

    string

    Canonical repo name.

    repo_idrequired

    string

    Canonical repo id (UUID string).

Standard errors

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

  • 400Bad Request — one of: invalid_input
  • 403Forbidden — one of: forbidden
  • 404Not Found — one of: not_found
  • 423Locked — one of: busy
  • 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.

ImportPhase

string

Which part of the import lifecycle a snapshot describes. `Fetch` while the import worker pulls from the source forge (no ingest job yet, counters zero); `Ingest` once the pack is staged and the ingest worker is indexing it; `Metadata` once the git phases are done and a GitHub metadata backfill (issues/comments/labels — plans/github-metadata-import.md) is still in flight — its counters are **issues**, not objects. Plain pushes only ever see `Ingest`; imports without metadata sync never see `Metadata`. Modelled as an enum (not a free `String`) so the generated TS client gets a string-literal union the SPA can switch on exhaustively.

"fetch""ingest""metadata"

ImportJobState

string

Lifecycle of an ingest job mirrored to the wire. Matches `IngestJobStatus` so the SPA can switch on the same set of strings the SSE stream emits.

"pending""running""completed""failed"