Update an object (fails with 404 if absent).
const url = 'https://example.com/v1/metadata@example/example/objects/example';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"description":"example","guidance":{"authoring":"example","querying":"example"},"identity":"example","label":"example","rules":{}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://example.com/v1/metadata@example/example/objects/example \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "description": "example", "guidance": { "authoring": "example", "querying": "example" }, "identity": "example", "label": "example", "rules": {} }'Authorizations
Section titled “Authorizations”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters”First path segment: metadata@<branchId>. metadata@main writes to main in instant mode (commit, fast-forward merge, apply) and requires admin.metadata.apply in addition to the operation’s own permission; any other id writes to that cart branch without applying. GET /metadata@main/... redirects to the branch-less read path.
Module key.
Object key.
Request Bodyrequired
Section titled “Request Bodyrequired”Request body for POST/PUT /metadata@{branchId}/{moduleKey}/objects/{objectKey}.
Request body for POST/PUT /metadata@{branchId}/{moduleKey}/objects/{objectKey}.
object
Optional description.
Audience-structured usage guidance for an object or field.
Set on an object definition or on any authorable field kind. Both keys are independently optional, so an author can supply only the one that applies.
Distinct from description: description says what the object or
field is; guidance says how to use it. Synthesized fields (managed
lookups, RelatedRecords inverses, junction objects) carry no
Guidance of their own — the owning relationship’s description is
their meaning.
object
Prose addressed to whoever writes records: conventions, units, when to use this object or field versus another. Absent by default.
Prose addressed to whoever queries records: what filters and aggregates mean, pitfalls to avoid. Absent by default.
Optional visual identity (color + icon), SPEC-UI-0049. Schema pending #812 – shape is metadata::IdentityConfig.
Human-readable label.
Validation rules to apply on this object, keyed by rule name. Schema pending #812 – values are metadata::ValidationRule.
object
Examplegenerated
{ "description": "example", "guidance": { "authoring": "example", "querying": "example" }, "identity": "example", "label": "example", "rules": {}}Responses
Section titled “ Responses ”Successful metadata write response.
pub(crate), not pub(super): named directly in
crate::routes::metadata::mod::write_router’s .response::<CODE, ...>()
OpenAPI response documentation (#814), which sits outside handlers.
Successful metadata write response.
pub(crate), not pub(super): named directly in
crate::routes::metadata::mod::write_router’s .response::<CODE, ...>()
OpenAPI response documentation (#814), which sits outside handlers.
object
The branch the write was committed to (sigil already stripped).
The .json5 file path relative to the metadata directory.
Example
{ "status": "created"}default
Section titled “default”Structured error envelope (SPEC-DATA-0006): {"errors": [{"domain", "scope", "target", "code", "message"}, ...]}. domain (added #950 D9) names the subsystem that produced the entry (data, metadata, apply, git, auth, iam, hfx, or api for a transport-level failure with no domain error behind it) and is always present.
The top-level response body. Wraps a non-empty list of [ErrorEntry].
object
The error entries making up the envelope. Always non-empty.
One entry in the error envelope.
Carries a [Domain] naming the subsystem that produced it, an anchoring
[ErrorScope], an optional target that disambiguates within the
scope, a stable SCREAMING_SNAKE_CASE code, and a human-readable
English message. See SPEC-DATA-0006 for the full envelope contract.
object
Machine-readable, stable, SCREAMING_SNAKE_CASE identifier.
Which subsystem produced this entry. Always serialized.
data::error::DataError – record CRUD, validation, queries.
server::routes::metadata::error::MetadataError – the metadata
write API (module/object/field/screen PUT and POST).
server::apply::ApplyError – the metadata apply/plan pipeline.
server::git::GitError – the git-backed metadata repository.
auth::error::AuthError – JWT and credential authentication.
server::routes::iam::error::IamError – principal and credential
management (IAM handlers still emit Domain::Data for genuine
request-body field validation, which stays DataError).
server::routes::hfx::error::HfxError – HFX parse/emit.
Module packages (.hfmod, #1165): package format, signature and
compatibility refusals, and the install lifecycle that consumes them.
A transport-level ApiError built directly (forbidden,
not_found, internal, service_unavailable), with no
<Domain>Error behind it.
HFX source location for an HFX_PARSE entry.
Emitted as the extra location field on the entry JSON when present.
The line/column are 1-based. The frame is the offending source line
extracted verbatim from the input.
object
1-based column within the line, measured in UTF-16 code units of the prefix so browser-side editors can consume it directly.
The offending source line text, when available.
1-based line number within the source text.
Server-authored English message. Not part of the API contract; may change across releases without notice.
The key of the validation rule that failed, when the code is
RULE_FAILED. None for all other codes. Skipped during
serialization when absent so it does not appear on unrelated
entries (same pattern as location).
Field key for field scope, record id for record scope, null
otherwise. Always serialized, even when null.
Example
{ "errors": [ { "domain": "data", "scope": "field" } ]}