Skip to main content
HoundDog API Documentation

Pagination and collections

Every collection response is an envelope:

{
  "data": [ { "...": "..." } ],
  "total": 1234,
  "has_more": true,
  "next_page": 2
}

Single resources are returned bare, without the envelope.

Parameter Default Maximum
page 1 1,000,000
per_page 50 200 for list entities; 50 when include=detail is requested

v2 has no offset parameter: page through a list with page and per_page.

A per_page above the cap, or a page above 1,000,000, is a 400, not a silent clamp. The same values are also sent as headers (X-Total, X-Total-Pages, X-Per-Page, X-Page, X-Next-Page) for clients that prefer them; the body is the contract.

Incremental reads

  • updated_since=<ISO-8601>, on the collections whose page lists it, returns records edited since that time, and MAY also return parties whose compliance was recomputed (some recomputes touch updated_at, others do not). It is not a status feed: for status changes read the events feed or subscribe to webhooks.
  • GET /events?since_id=<id> is a cursor over the account's event log, which is append-only; store the last id you processed and ask for everything after it.
  • GET /requirement_statuses?changed_since=<ISO-8601> returns the rows whose content changed since that time, most recently changed first. It never reports a deleted row (a requirement that no longer applies), and because pages are offsets over a changing order a row can be skipped or repeated: de-duplicate by id, and reconcile with a periodic full re-read: deletions, rows skipped when another row leaves the result mid-read, and rows that return when a party becomes active again are not reported (see Requirement statuses).

Lookups

Lookups by your own identifiers are query filters on the collection, not path segments (external ids often contain dots and slashes):

GET /api/v2/parties?external_id=PO-1234
GET /api/v2/parties?external_id_2=...
GET /api/v2/[email protected]

A filter that matches nothing returns an empty data array, not a 404.