Updating Assets
An update command is a command object with a from clause and an update
clause. from selects the target — either a single OID token or an asset type
narrowed by where or filter.
Updating a Single Asset
{
"from": "Story:1585",
"update": {
"Name": "Update members",
"Description": "Given I am an admin, when I open a member's profile, I can edit fields."
}
}
{
"assetsCreated": { "oidTokens": [], "count": 0 },
"assetsModified": { "oidTokens": ["Story:1585"], "count": 1 },
"assetsOperatedOn": { "oidTokens": [], "count": 0 },
"commandFailures": { "commands": [], "count": 0 },
"queryResult": { "results": [], "count": -1 }
}
Updating Everything That Matches a Query
Give from an asset type and add a where (attribute equality) or filter
(full query.v1 filter expression) clause — with
variables work in the filter here
exactly as they do in a query, arrays included. Every matching
asset receives the same update.
{
"from": "Workitem",
"where": { "Parent": "Story:1591" },
"update": {
"Owners": ["Member:20", "Member:1575"]
}
}
{
"assetsModified": { "oidTokens": ["Task:1592", "Test:1593"], "count": 2 }
}
from: Story with no where matches every Story the calling identity can see.
Use preview mode to see exactly which assets a
query-scoped update will touch before you run it.
Scalar and Single-Value Relation Attributes
Scalars and single-value relations use the same syntax — assign the value directly. A single-value relation accepts an OID token or a name, optionally qualified with a path; the name must resolve to exactly one asset.
{
"from": "Task:1489",
"update": {
"Description": "TODO -- get details from Andre Agile",
"Status": "In Progress"
}
}
Internally both are projected into the same add / remove shape used for
multi-value relations. That normalisation is visible in
preview mode:
[
{
"@526e8128-41be-44ef-8401-bb3bd19b03ef": {
"oid": "Task:1489",
"update": {
"Description": { "add": ["TODO -- get details from Andre Agile"], "remove": [] },
"Status": { "add": ["In Progress"], "remove": [] }
}
}
}
]
The projection does not distinguish scalar from relation. The processing phase resolves the attribute definition and applies the value appropriately.
For multi-value relations, the add / remove structure becomes meaningful
and gains several convenience forms — see
Updating multi-value relations.
Reordering with The Order Attribute
Order is a Rank attribute, and rank attributes work differently from
every other type in two ways that matter.
The value of a rank attribute is an opaque token whose only meaning is relative to other ranks. It is not a position, not an index, and not a number you can reason about. Reading it, storing it, comparing it arithmetically or trying to compute a "next" value will all mislead you, and the representation is free to change.
The supported way to consume ordering is to sort by the attribute and take the sequence you get back:
from: Story
where:
Scope: Scope:1000
sort:
- +Order
This applies to every Rank attribute, not just Story.Order. Most asset types
have one — Defect.Order, Epic.Order, Issue.Order, and an Order on nearly
every list type, which is what drives the sequence of values in a dropdown.
Writing follows the same principle: you do not assign a rank, you name a
neighbour. The Order attribute takes a positional object rather than a value,
identifying the sibling the asset should sit before or after.
Both
Before and After are supported, and each takes the OID token of a sibling.
from: Story:1002
update:
Order:
Before: Story:1001
{
"from": "Story:1003",
"update": {
"Order": { "After": "Story:1004" }
}
}
Verify with a sorted query:
from: Story
where:
Scope: Scope:1000
sort:
- +Order
Updating a Deleted Asset
Deleted assets are excluded from queries by default. To target one, add
IsDeleted: true to the where clause — even when from is an explicit OID
token.
from: Story:1591
where:
IsDeleted: true
update:
Owners: Member:20
The update succeeds and is reported in assetsModified as normal. The asset
remains deleted.
The same rule applies to operations —
Undelete needs IsDeleted: true to find its target.
Recording a Change Comment
Include ChangeComment inside the update node to attach an audit comment
to the change:
{
"from": "Story:1024",
"update": { "Estimate": "5", "ChangeComment": "Re-estimated after grooming" }
}
ChangeComment is not stored as an attribute — it becomes the change's audit
comment, read back from history as
ChangeComment.
On a create command it goes at the command root instead, alongside
AssetType (see creating assets).
Omit it and the change is stamped Modified through api/asset (creates
get Created through api/asset). The default distinguishes Bulk API writes
from UI edits in the audit trail; rest-1.v1 stamps nothing.
Unknown Attributes
Naming an attribute that does not exist on the target asset type produces a
command failure, not an HTTP error. The snippet below shows only the
commandFailures member of the response — the full envelope still carries
assetsCreated, assetsModified, assetsOperatedOn and queryResult
alongside it, as shown at the top of this page:
{
"commands": [
{
"@update": {
"oid": "Scope:0",
"update": { "MuddleBubble": { "add": ["BubbleMuddle"], "remove": [] } }
},
"error": {
"message": "Unknown AttributeDefinition: Scope.MuddleBubble",
"sourceCommandIndex": 0
}
}
],
"count": 1
}
See Errors and partial failures for the full failure model.