Managing inventory
The Inventory API registers and updates your physical inventory — locations (stores) and the devices (screens) deployed in them. A device also carries its own physical placement — its venue classification, zone, and product aisles.
Writing inventory
Section titled “Writing inventory”Locations and devices each have their own endpoints:
| Resource | Upsert | List |
|---|---|---|
| Locations | POST /v1alpha/inventory/locations:upsert |
POST /v1alpha2/inventory/locations |
| Devices | POST /v1alpha/inventory/devices:upsert |
POST /v1alpha/inventory/devices |
Each :upsert takes the bare resource object as its request body — a locations:upsert body is a Location, a devices:upsert body is a Device.
Concepts
Section titled “Concepts”- Location — a physical store.
- Device — a screen deployed at a location. Its physical placement — venue classification, zone, and product aisles — is owned by the device itself (see Venue, zones and aisles).
- Upsert — every write is an idempotent create-or-update keyed on identity, so sending the same payload again simply reconciles state rather than creating duplicates.
Resource identity
Section titled “Resource identity”metadata.id is server-generated and output-only — never send it on a write. metadata.name is yours, though: it follows the same full-replacement rule as any other field, so resend it on every upsert — omitting metadata clears a name already stored. Each resource is keyed on an identity you provide:
- A location’s identity is its top-level
externalIdfield. It is required onlocations:upsert: the platform resolves an existing location by it, or creates one on a miss. Set the raw value — noexternalid:prefix. - A device’s identity is its
identifier(key+playerId); the device’s ownexternalIdis derived from them as"{key}_{playerId}"and can’t be set directly. Bothidentifier(with a non-emptykeyandplayerId) andstatusare required ondevices:upsert.
An upsert response echoes the server-assigned metadata.id (a ULID). Use that ULID, or your own externalId, to reference the resource elsewhere.
Required fields
Section titled “Required fields”The API reference marks required fields on each schema. “Required” is stated from the creating perspective: it is what a resource must carry the first time you upsert it.
Two rules decide whether a value counts as supplied:
- Every enum has an
*_UNSPECIFIEDmember, which is also its default. It means absent, never a value — so sending"status": "STATUS_UNSPECIFIED"on a required enum is rejected exactly as omitting the field is. - An omitted field and an explicitly empty one are the same thing (see write semantics), so an empty array does not satisfy a required repeated field.