API docs

Change events

GET /v1/events returns one event for each change to a permit's status or to one of its dates, oldest first. Keep a cursor and you can pick up exactly where you stopped.

Start from a time

Your first call names a start time with since, an ISO 8601 time with a zone, no older than 400 days and not in the future.

curl "https://api.pullerdata.com/v1/events?since=2026-10-01T00:00:00Z&limit=1000" \
  -H "x-api-key: YOUR_KEY"
{
  "events": [
    { "id": 81234, "region": "henderson", "permit_number": "...", "event_type": "status",
      "from_value": "in_review", "to_value": "active", "occurred_on": "2026-10-20",
      "detected_at": "2026-10-21T06:12:09Z", ... }
  ],
  "next_cursor": "eyJ...",
  "poll_cursor": "eyJ..."
}

Each event names its permit by region and permit_number, the field that changed in event_type, and the values before and after. Every field is described on the permit event fields page.

Follow the cursors

Every call takes exactly one of since and cursor, and answers with two cursors:

next_cursor
The next page. Pass it back as cursor until it comes back null.
poll_cursor
Where the last page ended. Store it, and when you next want changes, pass it as cursor to get only the events written since.
curl "https://api.pullerdata.com/v1/events?cursor=eyJ..." \
  -H "x-api-key: YOUR_KEY"

A cursor older than 400 days gets a 400: events are deleted after 400 days.

Parameters

Parameters of /v1/events.
ParameterValue
sinceA time within the last 400 days.
cursorA next_cursor or poll_cursor from an earlier call.
regionOne region id. Without it, every region in one sequence.
event_typeOne of the types below.
limit1 to 1,000, default 200.
Event types.
event_typeWritten when
first_seenA permit appeared in the data.
statusThe permit's status changed, including a change of the agency's own status wording.
applied_dateThe application date changed.
issue_dateThe issue date changed.
expires_dateThe expiry date changed.
completed_dateThe completion date changed.
certificate_of_occupancy_dateThe certificate of occupancy date changed.
last_inspection_dateThe date of the last inspection changed.

When events appear

An event is written when Puller refreshes a region's records and finds a change, so detected_at is the time of that refresh and occurred_on is the agency's own date of the change, where it gives one. How often a region is refreshed is agreed with each customer.

A region's events start after its first copy is taken: permits already held then have no first_seen event. A change made and undone between two refreshes leaves no event.

If an agency stops publishing a permit, its events are held back. When the permit returns, they are served again with the same id, so keep the ids you have seen and skip repeats.

To re-sync whole permit records instead, filter /v1/permits with updated_since; see the API overview.