You're viewing the reference. To execute live calls you need a Brubru API key: Start a Professional trial · or contact sales
Response envelope

The canonical response shape

Every paginated endpoint returns the same JSON envelope. Code once against it and swap datasets by changing the path.

Shape

{
  "total": 139,
  "returned": 20,
  "pages": 7,
  "page": 1,
  "limit": 50,
  "has_more": true,
  "next_page": 2,
  "remaining_pages": 6,
  "coverage_complete": true,
  "published_from": "2026-01-01",
  "published_to": "2026-01-31",
  "published_end": "2026-01-31",
  "updated_from": null,
  "updated_to": null,
  "updated_end": null,
  "detail_level": "Full",
  "data": [ ... dataset-specific items ... ]
}

Attribution lives on response headers, not in the body:

X-Powered-By: Brubru
X-Source: brubru.beresol.eu
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Tier: free

Pagination fields

FieldTypeMeaning
totalintTotal matching items across all pages. For live-fetched endpoints where total isn't knowable (MEPs), this is a best-effort hint: offset + items + 1 if the page is full.
returnedintItems in this page. Always equals len(data).
pagesintTotal number of pages given the current limit.
pageintCurrent page, 1-indexed.
limitintItems per page. Default 50, max 100.
has_moreboolTrue if there's at least one more page.
next_pageint | nullNext page number, or null if on last page.
remaining_pagesintPages left after this one.
coverage_completebooltrue for DB-backed endpoints (we've seen everything). false for live-scraped endpoints where upstream pagination is unbounded.

Filter-echo fields

Date-range filters you sent come back in the envelope so you can verify the API interpreted them correctly:

FieldComes from
published_fromYour ?published_from= query param
published_toYour ?published_to= query param
published_endAlias of published_to (GovClipping-compatible). Identical value.
updated_fromYour ?updated_from= query param
updated_toYour ?updated_to= query param
updated_endAlias of updated_to. Identical value.

Date params: semantics. published_to and published_end are aliases of the same upper bound. They mean the same thing. If you send both with different values, the API returns 422 conflicting_params. Prefer published_to; published_end exists for GovClipping partners.

detail_level

Accepted values: Minimal, Summary (default), Full. Lowercase is also accepted (full, summary). The envelope echoes whatever the client sent.

Attribution: response headers, not envelope

Provenance information is on response headers, not in the JSON body. Removed from the envelope on 30 April 2026 after partner feedback: payloads are now leaner and the same data is one HEAD away.

HeaderMeaning
X-Powered-By: BrubruAlways present on /api/v2/* responses.
X-Source: brubru.beresol.euOrigin attribution.
X-RateLimit-LimitPer-minute ceiling for your tier (60 / 300 / 6000).
X-RateLimit-RemainingCalls left in the current 60-second sliding window.
X-RateLimit-TierYour tier: free, pro, or enterprise.

If you display Brubru data in your UI, we ask that you honour the X-Powered-By attribution either visually (a "Powered by Brubru" badge) or structurally in the raw metadata of your storage.

Dataset-specific aggregates

Some endpoints (e.g. /consultations/.../feedback) include a sibling aggregates object alongside data, giving counts by country and user_type in the same response so you don't need a separate summary call.

Specialised EC databases (May 2026): body_threshold + has_body

The specialised database endpoints: the Commission registers (/api/v2/commission/financial-sanctions, /comitology, /trade-defence, /state-aid, /dma-cases, /taric-tariffs), the Council sanctions regimes, and the geographical-indications registers (/api/v2/geographical-indications/*): all return the same envelope, plus a per-row contract that documents whether the full body of each item has been fetched into our local cache:

The live pass-through endpoints (DG COMP state aid and DMA cases, the Combined Nomenclature tariff lookup) are fetched from the upstream registry at request time: on these, has_body is meaningless and the envelope's coverage_complete will be false for the same reason.

Sort order

All list endpoints are sorted most-recent-first by date (adoption, publication, event, or last-updated depending on dataset). Within ties, secondary sort is id descending. Custom sort via ?sort= is on the June 2026 roadmap.

Non-envelope responses

A few endpoints return a flat object instead of the paginated envelope:

Next

Read about Errors next.