---
title: "Fetch lightweight job status and error state."
method: GET
path: "/v1/jobs/{jobId}"
tags: ["Jobs"]
---

# Fetch lightweight job status and error state.

`GET /v1/jobs/{jobId}`

## Request

- Base URL: `https://api.on-page.ai`
- URL: `https://api.on-page.ai/v1/jobs/{jobId}`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/on-page/apis/on-page-ai-api/docs/v1/jobs/:jobId/get.ts> (a function with typed inputs; its response is checked against the schema)

## Path parameters

- `jobId` string, required

## Response `200`

Job status snapshot

- JobStatusResponse: Lightweight status view. Poll this endpoint (or subscribe to webhooks) to observe job progression. When `status` is terminal, fetch `/v1/jobs/:job_id/result` for the payload. Use `jobId` as the canonical job identifier in generated SDKs; the live REST response also includes a deprecated `job_id` alias for backward compatibility. `region` / `locale` echo the canonical scan-region fields; `null` for classify jobs and for legacy scan rows whose stored values fail validation (no fabrication).
  - `jobId` string, required
  - `poweredBy` 'On-Page.ai', required
  - `type` 'classify' | 'scan', required: Job type supplied on creation and echoed in status/result reads.
  - `status` 'queued' | 'waiting' | 'running' | 'processing' | 'completed' | 'failed' | 'cancelled', required: Job lifecycle state. Terminal states are `completed`, `failed`, and `cancelled`.
  - `progress` integer, nullable, required
  - `created_at` string, required
  - `started_at` string, nullable, required
  - `completed_at` string, nullable, required
  - `region` 'US' | 'CA' | 'UK' | 'AU' | 'NZ' | 'ES' | 'DE' | 'IT' | 'FR' | 'IE' | 'NL' | 'CH' | 'SE' | 'NO' | 'DK' | 'FI' | 'ZA' | 'MX' | 'BR' | 'CO' | 'IN' | 'SG' | 'MY' | 'JP' | 'KE' | 'AE' | 'HK' | 'null', nullable, required: Canonical scan region. `null` for classify jobs and for legacy scan rows whose stored region/market values fail the strict 27-region check.
  - `locale` string, nullable, required: BCP-47 locale that was sent (or filled by Phase-2 admission) when the job was created. `null` for classify jobs and for legacy scan rows that did not include a locale.
  - `result` unknown, required
  - `error` object, nullable, required
    - `code` string, required
    - `message` string, required

## Other responses

- `401`: Unauthorized
- `403`: Scope forbidden
- `404`: Job not found
- `429`: Too many requests. Body is a `oneOf` of rate-limit / org-active-limit / org-queued-limit / scan-queue-saturated variants — branch on `error.code`. `Retry-After` is present when the limiter emits it; `X-RateLimit-*` is present on rate-limit-middleware 429s; `X-Concurrency-*` is present on concurrency-limit 429s (ORG_ACTIVE_LIMIT_REACHED / ORG_QUEUED_LIMIT_REACHED).
- `500`: Internal error

---

[API](https://skmtc.dev/on-page/apis/on-page-ai-api.md) - [All operations](https://skmtc.dev/on-page/apis/on-page-ai-api/llms.txt) - [OpenAPI document](https://skmtc.dev/on-page/apis/on-page-ai-api/revisions/a081e8701c19?raw)
