Create a component
const url = 'https://example.com/api/v1/components';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"expected_name":"example","label":"example","location":"example","name":"example","parent":"example","product":"example","system":"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/components \ --header 'Content-Type: application/json' \ --data '{ "expected_name": "example", "label": "example", "location": "example", "name": "example", "parent": "example", "product": "example", "system": "example" }'Creates a component, optionally under a parent (a root needs an all-scoped grant), bound to a system and a location, and classified by a product (required; naming a generic is fine until a real product is modeled). Gated by component:create. The location reference resolves within the caller’s location:read scope, because the label this stores is rendered from it, and one outside that scope is refused (422) exactly as :renderLabel refuses to preview it. Naming a system additionally requires system:update, and resolves within that scope, because the component’s primary membership is inserted from it: it is the same row the membership route writes, so the two paths cost the same permission. A system outside that scope is refused with a 403 naming it when the caller may read the system (denying its existence to someone who can GET it would be a lie) and with the non-disclosing 422 when the caller may not.
Request Body required
Section titled “Request Body required ”object
A URL to the JSON Schema for this object.
The name a create form previewed (POST /components:renderLabel returns it). The create is refused with a 409 naming what it would produce instead, rather than silently landing a different name, if the number was taken or the type’s stem moved while the form was open. It does not name the row (the platform still does, and the row is still name_generated): it only asserts what that name will be. Applies only when the platform names the row: sending it beside a name is a 422.
What an operator reads; the name is the address
Location name this component is placed at
Name, unique within its placement (the address; lowercase letters, digits, hyphens). Omit to have the platform generate one from the product’s type.
Parent component name; omit for a root component
Product (catalog SKU) this component is an instance of, by name or uuid. Required: use a generic (generic-device, generic-app, generic-service) until a real product is modeled.
Primary system name this component belongs to. Naming one writes that system’s membership, so it costs the system:update permission and resolves in that scope; omitted, the create costs component:create alone.
Responses
Section titled “ Responses ”Created
object
A URL to the JSON Schema for this object.
The scope-aware actions the caller may perform on this row (create a child, update, delete); a UI hint, the server still enforces.
The resolved effective tags (key -> winning value) that cascade onto this component; for the Tags column. Provenance is in the effective-tags detail view.
object
Whether the platform rendered this label from a label rule rather than an operator typing it. Read-only: write label to claim it, write an empty label to hand it back.
The location’s name, for display
The location’s id, the canonical handle
Whether the platform picked this name (a server-side generator) rather than an operator typing it.
The parent component’s name, for display; absent for a root component
The parent component’s id, the canonical handle
The dotted address (e.g. boi.17c.415a.$comp.display-1): derived from the component’s own placement, never from a system it belongs to. Set on a GET or LIST response; empty on a create/update/move/rename/resetName response (refetch the row to see it).
Path split on ’.’, accessors included, so the round trip through the resolver stays lossless.
The product’s name, for display; the form a body round-trips.
The product (catalog SKU) this component is an instance of, if any; the stable handle that survives a rename.
Two display-only compact forms of path, dash and bare. Neither is accepted back by the resolver: stripping/compacting is lossy.
object
The dash render’s segments concatenated with no separator, with the final stem-ordinal segment compacted to
The path’s non-accessor segments joined with ’-’ (e.g. boi-17c-216b-display-1). Display only; not accepted by the resolver.
Name of the component’s primary system, its default when no system is named. A component may belong to several; read /components/{name}/memberships for all of them.
How many systems this component belongs to; more than one means it is shared.
The primary system’s id, the canonical handle
Example
{ "$schema": "/api/v1/schemas/ComponentBody.json"}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"}