---
title: "Lists a job's photos, newest first."
method: GET
path: "/api/v1/jobs/{id}/photos"
tags: ["Jobs"]
---

# Lists a job's photos, newest first.

`GET /api/v1/jobs/{id}/photos`

## Request

- Base URL: `https://app.flexonthejob.com`
- URL: `https://app.flexonthejob.com/api/v1/jobs/{id}/photos`
- Auth: HTTP bearer

Returns every `Photo` entry on the job's timeline — photos taken with the Flex field app's
camera and photos added in the web app or with `POST /jobs/{id}/photos`. Signatures are not
photos and are not listed (they stay in the job's `updates`). All photos come back in one
page (`nextCursor` is always null). Also available as CSV (`Accept: text/csv` or
`?format=csv`). Needs `ViewJobs`. Example:
`curl https://app.flexonthejob.com/api/v1/jobs/42/photos -H "Authorization: Bearer flx_live_…"`.

## Path parameters

- `id` integer, required

## Query parameters

- `format` 'csv'

## Response `200`

The job's photos, newest first.

- PagedResponseOfJobPhotoDto: One page of a cursor-paginated /api/v1 collection (API_AND_MCP.md: `?after=<syncId>&limit=`).
  - `items` JobPhotoDto[]: Items of this page in ascending creation order.
    - `id` integer: Photo id — the same number as the entry's `id` in the job's `updates`. Use it to fetch or delete the photo. Example: `77`.
    - `syncId` string, uuid: Stable cross-device identifier of the photo entry (GUID). Example: `3f2c1b9e-8a41-4c55-9d7e-0b6f3f7a1c20`.
    - `caption` string: Caption shown on the job's timeline; `Photo` when none was given. Up to 2000 characters. Example: `Rust on the bottom panel`.
    - `attachmentName` string, nullable: The image's file name, e.g. `J-1042-20260929-143015.jpg`; null when none was recorded.
    - `contentType` string: MIME type of the image: `image/jpeg` or `image/png`.
    - `createdAt` string, date-time: When the photo was added, ISO-8601 UTC. Example: `2026-09-29T14:30:15Z`.
    - `createdByName` string, nullable: Display name (or email) of the person who added the photo, when recorded. Example: `Maria Lopez`.
  - `nextCursor` string, nullable: SyncId of the last item; pass it back as `?after=` to fetch the next page. `null` when this is the last page.

## Other responses

- `304`: Unchanged since the `If-None-Match` ETag.
- `401`: Unauthorized
- `403`: Forbidden
- `404`: No such job in this organization.
- `429`: Too Many Requests

---

[API](https://skmtc.dev/flexonthejob/apis/flex-api.md) · [All operations](https://skmtc.dev/flexonthejob/apis/flex-api/llms.txt) · [OpenAPI document](https://skmtc.dev/flexonthejob/apis/flex-api/revisions/19c8f4d27acf?raw)
