Source: https://www.puesto.dev/docs/api/changes/list-job-changes
Markdown source: https://www.puesto.dev/docs/api/changes/list-job-changes.md
Description: Poll the append-only feed of job change events for incremental sync. Pages forward by a monotonic integer `cursor`; omit the cursor to replay the full history from the beginning (initial sync). Always pass the returned `next_cursor` back on the next poll. When `has_more` is true, keep paging immediately; when false, poll again on your own interval. Set `include=job` to embed the current job record (descriptions omitted) with each change. Use `since` (an ISO-8601 timestamp with offset) as a convenience alternative to `cursor` for starting the feed at a point in time; it is mutually exclusive with a non-zero `cursor`. Snapshot filters (`level`, `workplace`, `employment_type`, `country`, `company_id`, `has_salary`) use before-OR-after matching: an event is delivered if the job matched the filter before the change or after it — so you also see jobs leaving your scope (e.g. filtering `level=senior` still delivers the event where a job moves out of the senior level). Different filter dimensions are ANDed together. The `changed_fields` attribution filter delivers only events that changed at least one of the named content fields; `created` events carry no field-level attribution and are always delivered.

# List job changes

`GET /api/v1/changes`

Poll the append-only feed of job change events for incremental sync. Pages forward by a monotonic integer `cursor`; omit the cursor to replay the full history from the beginning (initial sync). Always pass the returned `next_cursor` back on the next poll. When `has_more` is true, keep paging immediately; when false, poll again on your own interval. Set `include=job` to embed the current job record (descriptions omitted) with each change. Use `since` (an ISO-8601 timestamp with offset) as a convenience alternative to `cursor` for starting the feed at a point in time; it is mutually exclusive with a non-zero `cursor`. Snapshot filters (`level`, `workplace`, `employment_type`, `country`, `company_id`, `has_salary`) use before-OR-after matching: an event is delivered if the job matched the filter before the change or after it — so you also see jobs leaving your scope (e.g. filtering `level=senior` still delivers the event where a job moves out of the senior level). Different filter dimensions are ANDed together. The `changed_fields` attribution filter delivers only events that changed at least one of the named content fields; `created` events carry no field-level attribution and are always delivered.

## Parameters

### Query parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | string | No | Resume the feed after this change id. Omit to replay the full history from the beginning. Always pass back the `next_cursor` from the previous response. Mutually exclusive with `since` (a non-zero `cursor` alongside `since` is rejected). |
| `types` | string[] | No | Filter to specific change kinds. Repeat the parameter or comma-separate values (e.g. `types=created,closed`). A change matches if it is any of the given kinds. |
| `level` | string[] | No | Filter by seniority level. Repeat the parameter or comma-separate values. Matches before-OR-after: an event is delivered if the job was at any of these levels before the change or is at one after it (jobs leaving your scope are still delivered). |
| `workplace` | string[] | No | Filter by workplace arrangement. Repeat the parameter or comma-separate values. Matches before-OR-after: delivered if the job matched any of these before the change or matches one after it. |
| `employment_type` | string[] | No | Filter by employment type. Repeat the parameter or comma-separate values. Matches before-OR-after: delivered if the job matched any of these before the change or matches one after it. |
| `country` | string[] | No | Filter by ISO 3166-1 alpha-2 country code(s). Repeat the parameter or comma-separate values (e.g. `country=us,de`). Up to 20 values; case-insensitive. Matches before-OR-after: delivered if the job was tagged with any of these countries before the change or matches its current location. |
| `company_id` | integer | No | Filter to changes for jobs belonging to this numeric company id. |
| `has_salary` | boolean | No | When `true`, deliver events where the job had a salary before the change OR has one after it; when `false`, the inverse. Matches before-OR-after state. |
| `changed_fields` | string[] | No | Attribution filter: deliver only events that changed at least one of these content fields. Repeat the parameter or comma-separate values (e.g. `changed_fields=salary_min,salary_max`). `created` events are always delivered (they have no field-level attribution). |
| `since` | string | No | Start the feed at this ISO-8601 timestamp, including a UTC offset (e.g. `2024-01-01T00:00:00+00:00`). A convenience alternative to `cursor` for starting from a point in time; resolved to a cursor server-side. Mutually exclusive with a non-zero `cursor`. |
| `limit` | integer | No | Maximum number of changes to return. Defaults to 100; values above 500 are clamped to 500. |
| `include` | string | No | When set to `job`, attach the current job record (descriptions omitted) to each change. |

## Response

A page of change events.

### Response fields

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The page of change events, ordered by ascending `id`. |
| `next_cursor` | string | ALWAYS present — pass it back as `cursor` on the next poll. Echoes your cursor when no new events are available. |
| `has_more` | boolean | Whether more events may be immediately available. Keep paging while true. |
| `limit` | integer | The effective page size applied to this response. |

## Authentication

Send your secret API key (prefixed `sk_`) as a bearer token in the `Authorization` header. See [Authentication](https://www.puesto.dev/docs/authentication.md).

## Errors

Errors use the RFC 7807 `application/problem+json` format. See [Errors](https://www.puesto.dev/docs/errors.md).

## Example request

```bash
curl -X GET "https://www.puesto.dev/api/v1/changes" \
  -H "Authorization: Bearer sk_your_key_here"
```

Full spec: https://www.puesto.dev/api/v1/openapi.json

