> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mithunai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get an ingestion job and its counters

> Poll one ingestion job's status, attempt and document counters until is_active turns false. The counters update while the job runs and are final once it ends.

Poll this endpoint after [syncing a source](/api-reference/knowledge/sync-source) until `is_active` is `false`. Counters update while the job runs and are final once it ends. See [Ingestion](/knowledge/ingestion) for how runs, retries and cancellation work.

Returns `404` both for an ID that does not exist and for a job in another organization. A malformed ID also returns `404`. Any role in the organization can read a job.

<ParamField path="job_id" type="string" required>
  Job ID (a UUID).
</ParamField>

## Response

<ResponseField name="id" type="string" required>Job ID (a UUID).</ResponseField>
<ResponseField name="collection_id" type="string" required>Collection being ingested into.</ResponseField>
<ResponseField name="source_id" type="string" required>Source being ingested.</ResponseField>

<ResponseField name="status" type="string" required>
  One of:

  * `pending`: created, not yet handed to a worker.
  * `queued`: waiting for a worker. This is the status a sync returns, and the status a job waits in between retry attempts.
  * `running`: a worker is ingesting the source.
  * `succeeded`: the run completed and no document failed. Documents counted in `documents_skipped` do not change this.
  * `partial`: the run completed and at least one document failed.
  * `failed`: the run could not proceed, for example because the source was unreachable, the collection is archived, or a hard limit was exceeded. See `error_code` and `error_message`.
  * `cancelled`: stopped on request. Documents ingested before the stop remain.
  * `skipped`: the source had not changed since its last successful run. A queued run, which includes every run [Sync a source](/api-reference/knowledge/sync-source) starts, always re-reads the source and never ends `skipped`.

  More values may be added. Use `is_active` to decide whether to keep polling.
</ResponseField>

<ResponseField name="trigger" type="string" required>
  What started the run: `manual`, `scheduled` or `api`. Jobs started by [Sync a source](/api-reference/knowledge/sync-source) are `manual`.
</ResponseField>

<ResponseField name="source_version" type="string | null" required>
  The source version the run read, such as a commit SHA for a GitHub source. `null` until the run starts.
</ResponseField>

<ResponseField name="is_active" type="boolean" required>
  `true` while the status is `pending`, `queued` or `running`.
</ResponseField>

<ResponseField name="attempt" type="integer" required>Which attempt this is, starting at `1`.</ResponseField>

<ResponseField name="max_attempts" type="integer" required>
  Total attempts allowed. Only whole-run failures with a transient cause are retried.
</ResponseField>

<ResponseField name="queued_at" type="string | null" required>ISO 8601 timestamp, in UTC, when the current attempt was queued.</ResponseField>
<ResponseField name="started_at" type="string | null" required>ISO 8601 timestamp, in UTC, when the current attempt started. `null` before then.</ResponseField>
<ResponseField name="finished_at" type="string | null" required>ISO 8601 timestamp, in UTC, when the job ended. `null` while it is active.</ResponseField>
<ResponseField name="next_attempt_at" type="string | null" required>ISO 8601 timestamp, in UTC, before which a queued retry will not start. `null` when no retry is waiting.</ResponseField>
<ResponseField name="error_code" type="string | null" required>Stable error code when the run failed, such as `validation_error` or `dependency_failure`. Otherwise `null`.</ResponseField>
<ResponseField name="error_message" type="string | null" required>Readable description of the failure. Otherwise `null`.</ResponseField>

<ResponseField name="counters" type="object" required>
  What happened to the source's documents in this run.

  <Expandable title="properties">
    <ResponseField name="documents_discovered" type="integer" required>Documents the run has taken from the source so far. Each one is then counted as ingested, unchanged, skipped or failed. A file the source refuses while listing, such as an unsupported type or an excluded path, is counted only in `documents_skipped`.</ResponseField>
    <ResponseField name="documents_ingested" type="integer" required>Documents written or updated.</ResponseField>
    <ResponseField name="documents_unchanged" type="integer" required>Documents whose content had not changed.</ResponseField>
    <ResponseField name="documents_skipped" type="integer" required>Documents not ingested and not counted as failed: an unsupported file type, an unsafe path, a file over a size limit, a path your configuration excludes, a document with no indexable text, an uploaded file missing from storage, or a web page that could not be fetched or did not answer `200`.</ResponseField>
    <ResponseField name="documents_failed" type="integer" required>Documents that could not be ingested.</ResponseField>
    <ResponseField name="documents_deleted" type="integer" required>Documents removed because they are no longer in the source.</ResponseField>
    <ResponseField name="chunks_written" type="integer" required>Indexed passages written.</ResponseField>
    <ResponseField name="bytes_fetched" type="integer" required>Bytes read from the source.</ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl --request GET "$MITHUNAI_URL/arukz/api/v1/knowledge/jobs/9a4c2e71-6b0d-4f38-a5e2-1c7d8f3b6e40" \
    --header "Authorization: Bearer $MITHUNAI_API_KEY"
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import os, requests

  job_id = "9a4c2e71-6b0d-4f38-a5e2-1c7d8f3b6e40"
  response = requests.get(
      f"{os.environ['MITHUNAI_URL']}/arukz/api/v1/knowledge/jobs/{job_id}",
      headers={"Authorization": f"Bearer {os.environ['MITHUNAI_API_KEY']}"},
      timeout=60,
  )
  response.raise_for_status()
  print(response.json())
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const jobId = '9a4c2e71-6b0d-4f38-a5e2-1c7d8f3b6e40'
  const response = await fetch(`${process.env.MITHUNAI_URL}/arukz/api/v1/knowledge/jobs/${jobId}`, {
    headers: { Authorization: `Bearer ${process.env.MITHUNAI_API_KEY}` },
  })
  console.log(await response.json())
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "id": "9a4c2e71-6b0d-4f38-a5e2-1c7d8f3b6e40",
    "collection_id": "0b6f2c14-8a3d-4e91-9c77-2f5b1d0a4e88",
    "source_id": "5d1e7a90-3c4b-4f2a-8e61-7b9c0d2f4a13",
    "status": "partial",
    "trigger": "manual",
    "source_version": "4f9c2e7a1b3d5c8e0f2a4b6c8d0e1f3a5b7c9d2e",
    "is_active": false,
    "attempt": 1,
    "max_attempts": 3,
    "queued_at": "2026-09-24T10:20:05.127004+00:00",
    "started_at": "2026-09-24T10:20:06.340918+00:00",
    "finished_at": "2026-09-24T10:22:41.503117+00:00",
    "next_attempt_at": null,
    "error_code": null,
    "error_message": null,
    "counters": {
      "documents_discovered": 214,
      "documents_ingested": 198,
      "documents_unchanged": 0,
      "documents_skipped": 13,
      "documents_failed": 3,
      "documents_deleted": 0,
      "chunks_written": 1873,
      "bytes_fetched": 4718290
    }
  }
  ```

  ```json 404 theme={"theme":{"light":"github-light","dark":"github-dark"}}
  { "code": "not_found", "message": "The ingestion job was not found." }
  ```
</ResponseExample>
