Create a product
const url = 'https://example.com/api/v1/products';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"component_type":"example","driver_id":"example","icon":"example","kind":"device","label":"example","label_rule":"example","name":"example","parent_product_id":"example","vendor_id":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/api/v1/products \ --header 'Content-Type: application/json' \ --data '{ "component_type": "example", "driver_id": "example", "icon": "example", "kind": "device", "label": "example", "label_rule": "example", "name": "example", "parent_product_id": "example", "vendor_id": "example" }'Creates a custom (non-official) product, classified under a component_type. kind and component_type are both required; kind refuses vm (retired, folded into app). Gated by product:create.
Request Body required
Section titled “Request Body required ”object
A URL to the JSON Schema for this object.
The component_type this product is classified under (mic, camera, …), by name or uuid; every product must belong to one of the tree’s nodes. The generics (generic-device, generic-app, generic-service) fit anything not yet modeled more specifically.
The driver that talks to it, by handle or uuid
A product-level icon override; unset inherits the component_type’s icon
What class of thing the product is. vm is retired (folded into app); required, no default, so every product states its class explicitly.
What an operator reads in pickers and lists
A Go text/template rendering the label of every component of this product, over a closed map of that component’s facts (Name, Ordinal, TypeName, TypeAbbrev, Stem, ProductName, VendorName, LocationLabel, SystemTypeLabel) and the functions title, upper, lower, slug and words (words turns a kebab or snake name into the words in it, so {{title (words .Name)}} reads north-wing as North Wing). Omit to inherit the component_type chain’s rule, then the global component rule. A template that does not parse is refused here, 422.
The globally unique name; renameable
The parent product, by handle or uuid
The vendor, by handle or uuid
Responses
Section titled “ Responses ”Created
object
A URL to the JSON Schema for this object.
The component_type this product is classified under (mic, camera, …); the taxonomy above product
The component_type’s uuid; the stable form of component_type
The driver’s handle
The driver’s uuid; the stable form of driver
A product-level icon override; unset inherits the component_type’s icon
The product’s uuid, the stable handle that survives a rename
The label template instances of this product get, the most specific tier; unset falls back to the component_type chain, then the global component rule
The name an operator reads and types; renameable
The parent product’s handle
The parent product’s uuid; the stable form of parent_product
The vendor’s handle
The vendor’s uuid; the stable form of vendor
Example
{ "$schema": "/api/v1/schemas/ProductBody.json", "kind": "device"}default
Section titled “default ”Error
object
A URL to the JSON Schema for this object.
A human-readable explanation specific to this occurrence of the problem.
Optional list of individual error details
object
Where the error occurred, e.g. ‘body.items[3].tags’ or ‘path.thing-id’
Error message text
The value at the given location
A URI reference that identifies the specific occurrence of the problem.
HTTP status code
A short, human-readable summary of the problem type. This value should not change between occurrences of the error.
A URI reference to human-readable documentation for the error.
Example
{ "$schema": "/api/v1/schemas/ErrorModel.json", "detail": "Property foo is required but is missing.", "instance": "https://example.com/error-log/abc123", "status": 400, "title": "Bad Request", "type": "about:blank"}