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

# Get image status

> Poll this endpoint after calling `POST /v1/projects/{projectId}/process`.
Use the `jobId` values from the process response.

Processing typically completes in **60–120 seconds** per job.
HDR merge jobs may take slightly longer.

For HDR jobs, `resultImageUrl` is populated only on the primary image (`jobId`).
The other bracket members in the group will have `status: completed` but no `resultImageUrl`.




## OpenAPI

````yaml GET /v1/images/{imageId}
openapi: 3.1.0
info:
  title: Fotolabs API
  version: 1.0.0
  description: >
    Programmatic access to the Fotolabs image processing pipeline.


    **Base URL:** `https://api.fotolabs.co` (prod) ·
    `https://api-staging.fotolabs.co` (staging)


    **Authentication:** Pass your API key as a Bearer token on every request.

    ```

    Authorization: Bearer fl_<key>

    ```


    **Typical flow:**

    1. `POST /v1/projects` — create a project

    2. `POST /v1/images/upload-url` + `PUT <uploadUrl>` — repeat for each image
    (no grouping needed)

    3. `POST /v1/projects/{projectId}/process` — process the whole project in
    one call

    4. `GET /v1/projects/{projectId}` — poll until `status` is `completed`;
    response includes all images and their result URLs


    **Project lifecycle:** `pending` → `processing` → `completed`

    - Images can only be uploaded to a `pending` project.

    - Processing can only be triggered on a `pending` project.

    - Once processing starts the project is locked — create a new project for
    additional images.


    **Plans:**

    - `free` — API access blocked.

    - `essential` / `ultimate` (PAYG) — charged once per project at the plan
    rate.

    - `essential_monthly` / `ultimate_monthly` — deducts one listing from your
    monthly quota; overage rate applies if quota is exhausted.
servers:
  - url: https://api.fotolabs.co
    description: Production
  - url: https://api-staging.fotolabs.co
    description: Staging
security:
  - ApiKeyAuth: []
paths:
  /v1/images/{imageId}:
    get:
      summary: Get image status
      description: >
        Poll this endpoint after calling `POST
        /v1/projects/{projectId}/process`.

        Use the `jobId` values from the process response.


        Processing typically completes in **60–120 seconds** per job.

        HDR merge jobs may take slightly longer.


        For HDR jobs, `resultImageUrl` is populated only on the primary image
        (`jobId`).

        The other bracket members in the group will have `status: completed` but
        no `resultImageUrl`.
      operationId: getImage
      parameters:
        - name: imageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          example: f3e088d1-33a5-4227-a2f6-c4f75617f847
      responses:
        '200':
          description: Image record.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageStatus'
              examples:
                pending:
                  summary: Queued, not yet started
                  value:
                    imageId: f3e088d1-33a5-4227-a2f6-c4f75617f847
                    status: pending
                    resultImageUrl: null
                    originalImageUrl: https://d1i1ga8jkrbik1.cloudfront.net/...
                    errorMessage: null
                    createdAt: '2026-05-09T18:00:48.421Z'
                    updatedAt: '2026-05-09T18:00:48.421Z'
                processing:
                  summary: Currently processing
                  value:
                    imageId: f3e088d1-33a5-4227-a2f6-c4f75617f847
                    status: processing
                    resultImageUrl: null
                    originalImageUrl: https://d1i1ga8jkrbik1.cloudfront.net/...
                    errorMessage: null
                    createdAt: '2026-05-09T18:00:48.421Z'
                    updatedAt: '2026-05-09T18:01:10.000Z'
                completed:
                  summary: Done — result ready
                  value:
                    imageId: f3e088d1-33a5-4227-a2f6-c4f75617f847
                    status: completed
                    resultImageUrl: >-
                      https://d1i1ga8jkrbik1.cloudfront.net/028584de-.../result/f3e088d1-...jpg
                    originalImageUrl: https://d1i1ga8jkrbik1.cloudfront.net/...
                    errorMessage: null
                    createdAt: '2026-05-09T18:00:48.421Z'
                    updatedAt: '2026-05-09T18:06:00.240Z'
                failed:
                  summary: Failed
                  value:
                    imageId: f3e088d1-33a5-4227-a2f6-c4f75617f847
                    status: failed
                    resultImageUrl: null
                    originalImageUrl: https://d1i1ga8jkrbik1.cloudfront.net/...
                    errorMessage: Gemini API quota exceeded after 5 retries
                    createdAt: '2026-05-09T18:00:48.421Z'
                    updatedAt: '2026-05-09T18:07:00.000Z'
        '401':
          description: Invalid or missing API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Image not found or belongs to a different workspace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Image not found
components:
  schemas:
    ImageStatus:
      type: object
      required:
        - imageId
        - status
        - resultImageUrl
        - originalImageUrl
        - errorMessage
        - createdAt
        - updatedAt
      properties:
        imageId:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
        resultImageUrl:
          type: string
          format: uri
          nullable: true
          description: >-
            CloudFront URL of the processed JPEG. Non-null only when `status` is
            `completed`.
        originalImageUrl:
          type: string
          format: uri
          description: CloudFront URL of the original uploaded image.
        errorMessage:
          type: string
          nullable: true
          description: Human-readable error. Non-null only when `status` is `failed`.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          example: >-
            No payment method on file. Please add one at fotolabs.co before
            processing images.
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: API key with `fl_` prefix, issued from the Fotolabs dashboard

````