Entity Merge Upgrade Guide
This guide covers the breaking changes introduced by the entity merge — the unification of the items and locations
tables into a single entities table. This is primarily relevant to developers integrating with the Homebox API.
Overview of Changes
Section titled “Overview of Changes”The items and locations database tables have been merged into a single entities table. All related tables
have been renamed accordingly. A new entity_types table has been introduced to differentiate between items and
locations using a user-definable type system.
Database Changes
Section titled “Database Changes”| Old Table | New Table |
|---|---|
items | entities |
locations | merged into entities |
item_fields | entity_fields |
item_templates | entity_templates |
tag_items | tag_entities |
Key column renames:
| Old Column | New Column |
|---|---|
group_items / group_locations | group_entities |
item_children / location_children | entity_children |
location_items | removed (absorbed into entity_children) |
item_attachments | entity_attachments |
item_id (maintenance_entries) | entity_id |
sync_child_items_locations | sync_child_entity_locations |
Migration
Section titled “Migration”The migration runs automatically on startup. It:
- Creates the
entity_typestable and seeds default “Item” and “Location” types per group - Renames the
itemstable toentitiesand renames all columns - Inserts all locations into
entitiespreserving their original UUIDs - Re-parents items under their former locations using the unified
entity_childrencolumn - Renames all related tables and their foreign key columns
- Drops the
locationstable - Assigns asset IDs to any entities that don’t have them (including former locations)
API Changes
Section titled “API Changes”Removed Endpoints
Section titled “Removed Endpoints”All /v1/items/* and /v1/locations/* endpoints have been removed. They are replaced by the unified
/v1/entities/* endpoints.
New Endpoints
Section titled “New Endpoints”Entities (replaces both Items and Locations)
Section titled “Entities (replaces both Items and Locations)”| Method | Path | Description |
|---|---|---|
GET | /v1/entities | Query entities (items by default, locations with ?isLocation=true) |
POST | /v1/entities | Create an entity (item or location based on entityTypeId) |
GET | /v1/entities/tree | Get the location/item tree |
GET | /v1/entities/export | Export entities as CSV |
POST | /v1/entities/import | Import entities from CSV |
GET | /v1/entities/fields | Get all custom field names |
GET | /v1/entities/fields/values | Get all values for a custom field |
GET | /v1/entities/{id} | Get a single entity |
GET | /v1/entities/{id}/path | Get the full path to an entity |
PUT | /v1/entities/{id} | Update an entity |
PATCH | /v1/entities/{id} | Partial update an entity |
DELETE | /v1/entities/{id} | Delete an entity |
POST | /v1/entities/{id}/duplicate | Duplicate an entity |
POST | /v1/entities/{id}/attachments | Add an attachment |
PUT | /v1/entities/{id}/attachments/{attachment_id} | Update an attachment |
DELETE | /v1/entities/{id}/attachments/{attachment_id} | Delete an attachment |
GET | /v1/entities/{id}/attachments/{attachment_id} | Get an attachment file |
GET | /v1/entities/{id}/maintenance | Get maintenance log |
POST | /v1/entities/{id}/maintenance | Create maintenance entry |
Entity Types (new)
Section titled “Entity Types (new)”| Method | Path | Description |
|---|---|---|
GET | /v1/entity-types | List all entity types for the group |
POST | /v1/entity-types | Create an entity type |
PUT | /v1/entity-types/{id} | Update an entity type |
DELETE | /v1/entity-types/{id} | Delete an entity type |
Query Parameter Changes
Section titled “Query Parameter Changes”GET /v1/entities
Section titled “GET /v1/entities”| Parameter | Type | Description |
|---|---|---|
isLocation | bool | Filter by entity type. true = locations only (returns array with itemCount), false = items only. Omit for items only (default). |
filterChildren | bool | When isLocation=true, only return root locations (no parent). |
parentIds | []string | Filter entities by parent ID. Replaces the old locations parameter. |
q | string | Search query (unchanged) |
tags | []string | Filter by tag IDs (unchanged) |
page, pageSize | int | Pagination (unchanged) |
orderBy | string | Sort order (unchanged) |
includeArchived | bool | Include archived entities (unchanged) |
Request Body Changes
Section titled “Request Body Changes”Create Entity (POST /v1/entities)
Section titled “Create Entity (POST /v1/entities)”{ "name": "My Item", "description": "A description", "quantity": 1, "parentId": "uuid-of-parent-location", "entityTypeId": "uuid-of-entity-type", "tagIds": ["uuid-1", "uuid-2"]}Key changes from the old POST /v1/items:
locationId→parentId— the parent entity (typically a location)entityTypeId— new optional field. If omitted, defaults to the group’s default “Item” type. To create a location, pass a location-type entity type ID.
Update Entity (PUT /v1/entities/{id})
Section titled “Update Entity (PUT /v1/entities/{id})”locationId→parentIdsyncChildItemsLocations→syncChildEntityLocationsentityTypeId— optional, can change the entity’s type
Response Body Changes
Section titled “Response Body Changes”Entity Summary
Section titled “Entity Summary”The location field has been replaced by parent:
{ "id": "...", "name": "My Item", "parent": { "id": "...", "name": "Living Room" }, "entityType": { "id": "...", "name": "Item", "isLocation": false }, "tags": [...], ...}Entity Out (full detail)
Section titled “Entity Out (full detail)”The children field on an entity now only includes location-type children (sub-containers).
Items inside a location are retrieved separately via GET /v1/entities?parentIds=[locationId].
WebSocket Events
Section titled “WebSocket Events”The item.mutation and location.mutation events have been merged into a single entity.mutation event.
{ "event": "entity.mutation", "data": { "gid": "group-uuid" }}Migration Checklist for API Consumers
Section titled “Migration Checklist for API Consumers”- Replace all
/v1/items/*and/v1/locations/*URLs with/v1/entities/* - Replace
locationIdwithparentIdin create/update payloads - Replace
syncChildItemsLocationswithsyncChildEntityLocationsin update payloads - Replace
item.locationwithitem.parentwhen reading entity responses - Use
?isLocation=trueto query locations,?parentIds=instead of?locations=to filter by parent - Listen for
entity.mutationinstead ofitem.mutation/location.mutationon WebSocket - Use
/v1/entity-typesto manage and query available entity types