Skip to content

API Migration Guide — Entity Merge

This guide is for third-party developers integrating with the Homebox REST API. It covers all breaking changes introduced by the entity merge, where items and locations were unified into a single “entities” API.

Items and locations are now both entities, differentiated by a user-definable entity type. The separate /v1/items/* and /v1/locations/* endpoints have been replaced by a unified /v1/entities/* API. A new /v1/entity-types API lets you manage the types that determine entity behavior.

All of the following endpoints have been removed:

  • GET/POST /v1/items, GET/PUT/PATCH/DELETE /v1/items/{id}
  • GET/POST /v1/locations, GET/PUT/DELETE /v1/locations/{id}
  • GET /v1/locations/tree
  • GET /v1/items/{id}/path, POST /v1/items/{id}/duplicate
  • POST/PUT/DELETE/GET /v1/items/{id}/attachments/*
  • GET/POST /v1/items/{id}/maintenance
  • GET /v1/items/export, POST /v1/items/import
  • GET /v1/items/fields, GET /v1/items/fields/values
MethodPathDescription
GET/v1/entitiesQuery entities. Returns items by default; pass ?isLocation=true for locations.
POST/v1/entitiesCreate an entity. Set entityTypeId to control whether it’s an item or location.
GET/v1/entities/{id}Get a single entity by ID.
PUT/v1/entities/{id}Full update of an entity.
PATCH/v1/entities/{id}Partial update (quantity, parent, tags).
DELETE/v1/entities/{id}Delete an entity.
POST/v1/entities/{id}/duplicateDuplicate an entity.
GET/v1/entities/{id}/pathGet the full hierarchy path to an entity.
GET/v1/entities/treeGet the location/item tree (replaces /v1/locations/tree).
GET/v1/entities/exportExport entities as CSV.
POST/v1/entities/importImport entities from CSV.
GET/v1/entities/fieldsGet all custom field names.
GET/v1/entities/fields/valuesGet all values for a given custom field.
MethodPathDescription
POST/v1/entities/{id}/attachmentsUpload an attachment.
GET/v1/entities/{id}/attachments/{attachment_id}Download an attachment file.
PUT/v1/entities/{id}/attachments/{attachment_id}Update attachment metadata.
DELETE/v1/entities/{id}/attachments/{attachment_id}Delete an attachment.
MethodPathDescription
GET/v1/entities/{id}/maintenanceGet maintenance log for an entity.
POST/v1/entities/{id}/maintenanceCreate a maintenance entry.
MethodPathDescription
GET/v1/entity-typesList all entity types for the current group.
POST/v1/entity-typesCreate an entity type.
PUT/v1/entity-types/{id}Update an entity type.
DELETE/v1/entity-types/{id}Delete an entity type (fails if entities still use it).
ParameterTypeDefaultDescription
isLocationboolfalsetrue returns locations only (with itemCount on each). Omit or false for items only.
filterChildrenboolfalseWhen isLocation=true, return only root locations (those with no parent).
parentIds[]stringFilter by parent entity ID. Replaces the old locations parameter.
qstringSearch query.
tags[]stringFilter by tag IDs.
negateTagsboolfalseExclude entities matching the given tags.
pageintPage number for pagination.
pageSizeintItems per page.
orderBystringSort field (name, createdAt, updatedAt).
includeArchivedboolfalseInclude archived entities.
fields[]stringFilter by custom field values (fieldName=value format).
ParameterTypeDefaultDescription
withItemsboolfalseInclude items (non-location entities) in the tree.
ParameterTypeDescription
fieldstringRequired. The custom field name to get values for.
{
"name": "My Item",
"description": "A description",
"quantity": 1,
"parentId": "uuid-of-parent-location",
"entityTypeId": "uuid-of-entity-type",
"tagIds": ["uuid-1", "uuid-2"]
}

Changes from the old POST /v1/items:

Old FieldNew FieldNotes
locationIdparentIdThe parent entity (typically a location).
entityTypeIdNew. Controls whether this is an item or location. Omit to default to the group’s “Item” type. Pass a location-type entity type ID to create a location.
Old FieldNew Field
locationIdparentId
syncChildItemsLocationssyncChildEntityLocations
entityTypeId (optional — change the entity’s type)
Old FieldNew Field
locationIdparentId
entityTypeId (optional)

Create Entity Type — POST /v1/entity-types

Section titled “Create Entity Type — POST /v1/entity-types”
{
"name": "Shelf",
"isLocation": true,
"icon": "",
"defaultTemplateId": "uuid-or-omit"
}
  • isLocation — if true, entities of this type act as containers (appear in the location tree, can hold other entities).
  • defaultTemplateId — optional. When set, creating an entity with this type will auto-apply the template’s defaults.

The location field has been replaced by parent. A new entityType field is included.

{
"id": "...",
"name": "My Item",
"parent": {
"id": "...",
"name": "Living Room"
},
"entityType": {
"id": "...",
"name": "Item",
"isLocation": false
},
"itemCount": 0,
"tags": [],
"quantity": 1,
"purchasePrice": 0,
"assetId": "001-234",
"insured": false,
"archived": false,
"createdAt": "...",
"updatedAt": "..."
}
  • parent replaces location. It references the parent entity (which is typically a location-type entity for items).
  • entityType is new. It contains the type’s id, name, and isLocation flag.
  • itemCount is populated only when querying with ?isLocation=true. It contains the count of non-location child entities.

The children field now only includes location-type children (sub-containers). To get items inside a location, query GET /v1/entities?parentIds=[locationId].

{
"id": "...",
"name": "Shelf",
"description": "",
"isLocation": true,
"icon": "",
"defaultTemplateId": "...",
"defaultTemplate": {
"id": "...",
"name": "Default Shelf Template",
"description": ""
},
"createdAt": "...",
"updatedAt": "..."
}

All GET /v1/entities responses (both items and locations) return a consistent paginated shape:

{
"page": 1,
"pageSize": 50,
"total": 120,
"items": [],
"totalPrice": 1234.56
}

totalPrice is the sum of purchasePrice * quantity for non-sold items in the result set.

The item.mutation and location.mutation events have been merged into a single event:

{
"event": "entity.mutation",
"data": {
"gid": "group-uuid"
}
}

Subscribe to entity.mutation to be notified of any entity change (create, update, delete) regardless of whether it’s an item or location.

  1. Update all endpoint URLs — replace /v1/items/* and /v1/locations/* with /v1/entities/*
  2. Update create/update payloadslocationIdparentId, syncChildItemsLocationssyncChildEntityLocations
  3. Update response parsingitem.locationitem.parent, and expect entityType on all entity responses
  4. Update query parameters?locations=?parentIds=, use ?isLocation=true to query locations
  5. Update WebSocket listeners — listen for entity.mutation instead of item.mutation / location.mutation
  6. Use /v1/entity-types to query available types if your integration needs to create entities with specific types