Skip to content

Create a component

POST
/components
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.

Media type application/json
object
$schema

A URL to the JSON Schema for this object.

string format: uri
expected_name

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.

string
>= 1 characters <= 100 characters /^[a-z0-9][a-z0-9-]*$/
label

What an operator reads; the name is the address

string
location

Location name this component is placed at

string
name

Name, unique within its placement (the address; lowercase letters, digits, hyphens). Omit to have the platform generate one from the product’s type.

string
>= 1 characters <= 100 characters /^[a-z0-9][a-z0-9-]*$/
parent

Parent component name; omit for a root component

string
product

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.

string
system

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.

string

Created

Media type application/json
object
$schema

A URL to the JSON Schema for this object.

string format: uri
actions

The scope-aware actions the caller may perform on this row (create a child, update, delete); a UI hint, the server still enforces.

Array<string> | null
effective_tags

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
key
additional properties
string
id
required
string
label
string
label_generated
required

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.

boolean
location

The location’s name, for display

string
location_id

The location’s id, the canonical handle

string
name
required
string
name_generated
required

Whether the platform picked this name (a server-side generator) rather than an operator typing it.

boolean
parent

The parent component’s name, for display; absent for a root component

string
parent_id

The parent component’s id, the canonical handle

string
path

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).

string
path_segments

Path split on ’.’, accessors included, so the round trip through the resolver stays lossless.

Array<string> | null
product

The product’s name, for display; the form a body round-trips.

string
product_id

The product (catalog SKU) this component is an instance of, if any; the stable handle that survives a rename.

string
renders

Two display-only compact forms of path, dash and bare. Neither is accepted back by the resolver: stripping/compacting is lossy.

object
bare
required

The dash render’s segments concatenated with no separator, with the final stem-ordinal segment compacted to when the owning type registers one (e.g. boi17c216bdsp1). On a LIST row the substitution is skipped (segments concatenated as-is) to avoid a per-row abbrev resolution; a GET always compacts it. Display only either way; not accepted by the resolver.

string
dash
required

The path’s non-accessor segments joined with ’-’ (e.g. boi-17c-216b-display-1). Display only; not accepted by the resolver.

string
system

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.

string
system_count
required

How many systems this component belongs to; more than one means it is shared.

integer format: int64
system_id

The primary system’s id, the canonical handle

string
Example
{
"$schema": "/api/v1/schemas/ComponentBody.json"
}

Error

Media type application/problem+json
object
$schema

A URL to the JSON Schema for this object.

string format: uri
detail

A human-readable explanation specific to this occurrence of the problem.

string
errors

Optional list of individual error details

Array<object> | null
object
location

Where the error occurred, e.g. ‘body.items[3].tags’ or ‘path.thing-id’

string
message

Error message text

string
value

The value at the given location

instance

A URI reference that identifies the specific occurrence of the problem.

string format: uri
status

HTTP status code

integer format: int64
title

A short, human-readable summary of the problem type. This value should not change between occurrences of the error.

string
type

A URI reference to human-readable documentation for the error.

string format: uri
default: about:blank
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"
}