Query entities
GET /v1/inventories/{inventory}/entities lists an inventory's entities, one per HFID.
Filters, sorting and counts apply to the resolved values: the values the response shows, not
the values each source reported.
curl -s 'localhost:8080/v1/inventories/devices/entities?filter.status=active&filter.status=planned&location=eu&sort=-role&limit=50'
Response
{
"inventory": "devices",
"view": { "branch": null, "contributions": [] },
"completeness": { "complete": true, "causes": [] },
"contributions": [
{ "id": "infrahub", "connection": "infrahub-prod", "health": "ok",
"snapshot": "published", "last_published_at": "2026-10-25T09:00:00.000000Z",
"last_error": null },
{ "id": "netbox", "connection": "netbox-prod", "health": "ok",
"snapshot": "published", "last_published_at": "2026-10-25T08:59:12.000000Z",
"last_error": null }
],
"total": 1832,
"entities": [
{
"hfid": "fw-01",
"fields": { "ports": 48, "role": "firewall", "serial": null, "status": "active" },
"location": "eu/par1/r01",
"field_sources": { "location": "netbox", "ports": "netbox", "role": "infrahub",
"serial": null, "status": "netbox" },
"freshness": { "state": "fresh", "oldest_confirmed_at": "2026-10-25T08:59:12.000000Z" }
}
],
"next_cursor": "MTAw"
}
totalis the number of entities that match the filters, on every page.fieldshas every declared field. A field is null when no source supplies it or when the winning source's value could not be used.detail=fulltells the two apart.field_sourcesnames the contribution that supplied each field and the location, or null when the value is null.completeness,contributionsandviewdescribe the whole response, not one entity.
Parameters
| Parameter | Example | Meaning |
|---|---|---|
filter.<field> | filter.status=active | Entities whose resolved value equals this value. |
hfid | hfid=FW-01 | Entities with this HFID, after cleaning. |
location | location=eu/par1 | Entities at this location or below it. |
sort | sort=status,-ports | Sort order. |
limit | limit=500 | Page size. Default 100. |
cursor | cursor=MTAw | The page after the one that returned this next_cursor. |
detail | detail=full | compact (default) or full. |
branch | branch=change-42 | Read a branch view. |
require_complete | require_complete=true | Fail with 409 if the inventory is incomplete. |
Filter on field values
filter.<field>=<value> keeps the entities whose resolved value of <field> equals
<value>. The comparison is exact, including letter case.
- Repeat a field to accept several values:
filter.status=active&filter.status=plannedmatches either. - Filters on different fields must all match:
filter.status=active&filter.role=firewall. - The value is read as the field's type. For a
booleanfield, usetrueorfalse. For anumberfield, use a decimal number such as48or2.5. - A null value never matches a filter.
A filter on an undeclared field, or a value that does not parse as the field's type, returns
400 invalid-query naming the parameter.
Fields with a vocabulary hold canonical values, so a filter uses the canonical spelling whatever each source reported. The inventory definition lists the vocabulary.
Filter on HFID and location
hfid=<value> matches the entity with that HFID. Census cleans the value the same way as the
HFIDs it stores, so hfid=%20FW-01 finds fw-01. Repeat it to match several HFIDs.
location=<path> matches the entities whose location is that declared location or any
location below it: location=eu returns every entity in every site and rack of eu. Repeat it
to match several locations. A path that is not declared returns 400 invalid-query.
GET /v1/inventories/{inventory}/locations lists the declared paths.
Sort
sort takes a comma-separated list of declared fields. A - before a field sorts it in
descending order. sort=status,-ports sorts by status, then by ports from highest to lowest.
- Null values come after the other values, in both directions.
- The HFID is always the last sort key, in ascending order, so the same data always returns the same order.
- Without
sort, entities are sorted by HFID.
Pages
limit sets the page size: 100 by default, at most 1,000, or at most 100 with detail=full.
A larger value returns 400.
To read the next page, send the same query with cursor set to the response's next_cursor.
next_cursor is null on the last page.
Pages are read from the current data. If a refresh or a webhook changes the inventory between two requests, a page can skip or repeat an entity. Census does not hold a snapshot across requests.
Require a complete inventory
By default, a query returns the data Census holds, together with the inventory's
completeness. With require_complete=true, Census answers 409 inventory-incomplete, with
the causes, when the inventory is incomplete. Use it in automation that must not act on a
partial inventory.
Completeness and contribution health lists the causes.