---
title: "List offers"
method: GET
path: "/v3/offers"
tags: ["Offers"]
---

# List offers

`GET /v3/offers`

## Request

- Base URL: `https://harvest.greenhouse.io`
- URL: `https://harvest.greenhouse.io/v3/offers`
- Auth: one of:
  - OAuth 2
    - Authorization code: `https://auth.greenhouse.io/authorize`
    - Client credentials
    - Token URL: `https://auth.greenhouse.io/token` scopes: `harvest:offers:list`
  - HTTP bearer

Offers are the formal job offers extended to a candidate's application. Each offer belongs to one application and carries a `status` (`Created`, `Accepted`, `Rejected`, or `Deprecated`), a proposed start date, an optional `opening_id`, and a `custom_fields` map that holds compensation components (base pay, equity, bonus, etc.) alongside any other offer custom fields configured on the hiring plan. Greenhouse versions offers — changing the start date, opening, or a version-triggering custom field creates a new offer row with an incremented `version` for the same application; pass `current_only=true` to filter the list down to the latest version per application. Filter by parent with `application_ids`, `job_ids`, `candidate_ids`, or `opening_ids`; combine `status=Accepted` with the `resolved_at` filter as a hire-date filter. Offer approvals flow through a separate `approval_flow` — see `/v3/approval_flows` for status. Offers carry private compensation data, so reading them is gated separately from the `harvest:offers:list` scope: when the access token includes a `sub` claim, the Site Admin it names must also hold the "See private notes, private fields, salary info, manage offers, request approval, and approve jobs/offers" advanced permission. Without that permission the endpoint returns an empty list rather than an error, even though the token holds the scope. Tokens issued without a `sub` claim act as your integration user and are not subject to it.

## Query parameters

- `cursor` string
- `per_page` integer
- `ids` integer[]
- `created_at` object
  - `gte` string, date-time
  - `lte` string, date-time
  - `gt` string, date-time
  - `lt` string, date-time
- `updated_at` object
  - `gte` string, date-time
  - `lte` string, date-time
  - `gt` string, date-time
  - `lt` string, date-time
- `application_ids` integer[]
- `job_ids` integer[]
- `candidate_ids` integer[]
- `opening_ids` integer[]
- `fields` string[]
- `current_only` boolean
- `custom_field_option_id` integer
- `status` 'Created' | 'Accepted' | 'Rejected' | 'Deprecated'
- `resolved_at` object
  - `gte` string, date-time
  - `lte` string, date-time
  - `gt` string, date-time
  - `lt` string, date-time
- `sent_on` object
  - `gte` string, date
  - `lte` string, date
  - `gt` string, date
  - `lt` string, date
- `starts_on` object
  - `gte` string, date
  - `lte` string, date
  - `gt` string, date
  - `lt` string, date

## Response `200`

Successful

- object[]
  - `id` integer
  - `created_at` string, date-time
  - `updated_at` string, date-time
  - `version` integer: Revision number of this offer within its application. Greenhouse creates a new offer row (incrementing `version`) whenever a tracked field on an existing offer changes — typically `starts_on`, `opening_id`, or a custom field configured to trigger a new version. Pair with `current_only=true` to filter the list endpoint down to the latest version per application.
  - `application_id` integer: Id of the application this offer is extended on. Every offer belongs to exactly one application; the offer is voided if the application is rejected or deleted.
  - `job_id` integer: Id of the job this offer's application is on.
  - `candidate_id` integer: Id of the candidate (person) receiving this offer. Resolved through the offer's application.
  - `opening_id` integer, nullable: Id of the specific opening this offer is being extended for. `null` when the offer has not yet been linked to an opening.
  - `status` 'Created' | 'Accepted' | 'Rejected' | 'Deprecated': Lifecycle status of the offer. `Created` for offers still being drafted or pending approval, `Accepted` once the candidate accepts, `Rejected` if declined or withdrawn, and `Deprecated` for superseded prior versions (a new offer version replaces an earlier one with this status).
  - `starts_on` string, date, nullable: Candidate's proposed start date, in ISO 8601 (YYYY-MM-DD). `null` when no start date has been set on the offer.
  - `sent_on` string, date, nullable: Date the offer was sent to the candidate, in ISO 8601 (YYYY-MM-DD). `null` until the offer has been sent.
  - `resolved_at` string, date-time, nullable: Timestamp the offer was resolved (`Accepted` or `Rejected`), in ISO 8601. Date updates submitted through `PATCH /v3/offers/{id}` are normalized to noon UTC on the supplied date. `null` while the offer is still `Created` or has been superseded as `Deprecated` without a resolution.
  - `custom_fields` object, nullable

---

[API](https://skmtc.dev/greenhouse/apis/harvest-api.md) - [All operations](https://skmtc.dev/greenhouse/apis/harvest-api/llms.txt) - [OpenAPI document](https://skmtc.dev/greenhouse/apis/harvest-api/revisions/822822e3f771?raw)
