Properties and properties versions
Included from Basic tier
A properties document is the database-held JSON property layer of one owner —
a node (project/environment/asset), a template, a change/run override, or a
step — versioned on every write. Two JSON:API types share this page:
properties (the live document) and properties_version (one history row).
The v2 OpenAPI document declares these resources' schemas; the resource-field coverage gate holds this page to them.
Endpoints
| Route | Serves |
|---|---|
GET /api/properties/{id} | Show the live document. Gated on read of the owner node when the owner is a node; documents with other owners are authenticated-only (recorded gap). |
PATCH /api/properties/{id} | Write a new version. Body attributes: data (the full replacement document) and optional version. With version, the write is optimistic-locked: a mismatch answers 422 Version mismatch, the properties are now at version N whilst these modifications were made to version M. Please fetch the latest version of the properties and reapply the edits. Without it, the unsafe variant writes unconditionally. |
GET /api/properties/{id}/versions | History. Default sort version desc; `filter[sorts][]=version |
GET /api/properties/{id}/versions/{version} | One history row by version number (always with data); a non-integer or unknown number is a 404. |
Properties documents are never listed; they are reached through their owner's
properties relationship/links (nodes, templates, template versions, steps,
changes' properties/override_properties). The converged read surfaces
(…/converged_properties on templated nodes, changes and steps) serve the
merged result of the layer stack — a separate converged_properties
resource, not covered here.
properties attributes
| Attribute | Type | Meaning / origin / null semantics |
|---|---|---|
data | object | The current document, decrypted from the stored (possibly ActiveRecord-encrypted) column. |
version | integer | The current version number; each successful PATCH increments it. |
created_at | string | The document row's creation time (ISO8601, six fractional digits). |
Relationships: owner — links-only (links.owner is the owner's API URL for
node owners, null for other owner types — recorded gap until owners are
modelled). Links: self, current_version
(…/versions/{version}), versions.
properties_version attributes
| Attribute | Type | Meaning / origin / null semantics |
|---|---|---|
data | object | The document as stored at that version. Absent (key omitted) on list rows read with exclude_data=true; always present on a show. |
version | integer | The row's version number. |
created_at | string | When the version was written. |
owner_type | string | The parent document's owner, humanized: a node owner reads as its capitalized kind (Project, Environment, Asset), a step STI class as Step, TemplateVersion as Template version, WorkflowRun as Workflow run; other owners pass through verbatim. |
Relationships: properties (the parent document, with its related link).
Links: self (…/versions/{version}), versions, owner (the owner URL or
null). A version may carry a passthrough meta document when the read
model supplies one; the current readers populate none.
Properties history (API v2)
PropertiesService.GetPropertiesHistory(node_path) on /api/v2 computes
the timeline behind the GUI's asset history view — the upstream
GeneratePropertiesHistoryCommand semantics, which the Go v1 facade never
served (the waiver):
- One entry per owner along the node's path, path order: project,
environment, the asset's template, asset. The template-version slot is
folded into the asset's
template_versions, so entrylevelvalues can gap (0, 1, 2, 4 on a fully templated path). - Each entry carries its stored
properties_versionsoldest first as{version, start_date}; a start predating the addressed node clamps to the node's creation (the upstreammax_date). - The templated node also carries
template_versions: the template-version history windows newest first, each window's active properties versions newest first, labelled"<template version> (v<n>)", with the window's own commitsha(falling back to the version's current commit), and clamped boundary duplicates shifted exactly as upstream shifts them. - Version metadata only: no properties
datais read or served. - Authorised as read on the addressed node's path, 404-on-deny;
PostgreSQL-only (the embedded store answers the typed
ERROR_REASON_STORE_POSTGRES_REQUIREDposture).
Versioning, history and reset semantics
- Every PATCH appends a
properties_versionsrow and bumps the document'sversion— history is never rewritten. - Steps pin the exact versions they ran with: a step's
pre_properties_versions/post_properties_versionsrelationships point atproperties_versionrows, which is why old runs stay explainable after later edits (opschain docs resources/step). - Reset is not a delete:
opschain properties reset(repo-scoped CLI) writes a new empty version of the targeted node layer — history and per-step pins are retained, and the repository's committed properties files alone define the next run. There is no destructive reset on this API surface.
Related pages
opschain docs resources/settings— the settings twin of this document family.opschain docs cli/properties-show,opschain docs cli/properties-edit,opschain docs cli/properties-history,opschain docs cli/properties-reset.