Stage ops
Proposes a change: stages a batch of ops into the project's open changeset, opening one if none is open.
POST /context/v1/changeset/ops
Proposes a change: stages a batch of ops into the project's open changeset, opening one if none is open. It writes no version and publishes nothing, and a customer key cannot publish. Send expected_revision and expected_release, both read from the changeset just before you computed the batch; if either has moved the call is refused with 409 so you can re-read and recompute. A batch holds at most 100 ops. An invalid op, an unknown target or an oversized batch is a 422. Send an Idempotency-Key header to make a retry safe: a repeat of the same key and batch replays the first result, and reusing the key for a different batch is a 409. The response lists the whole open changeset; the last entries are the ones this call staged.
Requires the context:assets scope.
Parameters
| Parameter | Location | Required | Description |
|---|---|---|---|
Idempotency-Key | header | no | Optional. Repeating a call with the same key and batch replays the first result instead of staging again; the same key with a different batch is a 409. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
expected_release | integer or null | no | The release number the changeset was opened against, from GET changeset. Required: without it, or if it has moved, the call is refused with 409. |
expected_revision | integer or null | no | The changeset revision you read, from GET changeset; 0 when nothing was open. Required: without it, or if the changeset has moved, the call is refused with 409. |
ops | array of object | yes | The ops to stage, in order, at most 100. Each is an object whose op field names what it does: upsert_asset, patch_asset, delete_asset, add_link, remove_link or update_link. Every op carries base_version, the version of what it changes that you read, or 0 when it creates. Wherever an op names an asset (asset_id, from_id, to_id) it may give the id or the canonical name. |
provenance | object or null | no | Who is proposing the change and why. |
Responses
| Status | Meaning |
|---|---|
200 | The request succeeded. |
401 | The token is missing, expired or invalid. |
403 | The token does not carry the scope this operation requires. |
404 | No such project, or the token belongs to a different project. |
422 | The request was not valid: a parameter or the body failed validation. |
The 200 response body:
| Field | Type | Required | Description |
|---|---|---|---|
base_release | integer | yes | The release the changeset was opened against. Send it back when staging. |
base_repository_revision | string | yes | A fingerprint of the repository state the changeset was opened against. |
batch_ops | array of ChangesetOp | yes | The ops this call staged. They are also the last entries of ops. |
changeset_id | string | yes | The changeset's id. |
decision_summary | DecisionSummary | yes | How many ops have been decided. |
invalidated_by_release | integer or null | no | The release that made this changeset impossible to merge, if one did. |
merge_claimed_at | string or null | no | When a publication claimed the changeset, while one is in progress. |
next_seq | integer | yes | The position the next staged op will take. |
opened_at | string | yes | When the changeset was opened. |
opened_by | object | yes | Who opened it and why. |
ops | array of ChangesetOp | yes | Every op staged so far, in order. |
project_id | string | yes | The project the changeset belongs to. |
published_release | integer or null | no | The release it produced, once published. |
revision | integer | yes | The changeset's revision. It changes every time the changeset does; send it back when staging. |
settled_at | string or null | no | When it was published or abandoned. |
settled_by | object or null | no | Who settled it. |
status | string | yes | Whether the changeset is open or how it was settled. |
superseded_op_ids | array of string | yes | Ops that a later op overwrote. |
Shapes
The named shapes used above.
ChangesetOp
One staged op and what has been decided about it.
| Field | Type | Required | Description |
|---|---|---|---|
carried_from | string or null | no | The changeset the op was carried over from, if it was. |
carried_to | string or null | no | The changeset the op was carried over to, if it was. |
cascaded_from | string or null | no | The op whose rejection caused this one to be rejected, if any. |
conflict | string or null | no | Why the op cannot merge as it stands, when something it depends on has moved; null otherwise. |
decided_at | string or null | no | When it was decided. |
decided_by | object or null | no | Who decided and why, once someone has; null while the op is undecided. |
decision | string | yes | Where review stands: undecided, approved or rejected. |
decision_history | array of object | yes | Every decision made about the op, oldest first. |
op | object | yes | The op as it was sent; its op field names the kind. GET changeset leaves out an upsert's content and the value of a patch's edit, which GET changeset/ops returns. |
op_id | string | yes | The id the service assigned when the op was staged. Use it to remove the op. |
reason | string or null | no | The reason given for a rejection. |
review_key | string | yes | Groups the ops a reviewer decides together. |
seq | integer | yes | The op's position in the changeset, in staging order. |
staged_at | string | yes | When the op was staged. |
staged_by | object | yes | Who staged it and why. |
status | string | yes | The op's state in the changeset. |
DecisionSummary
How many ops review has decided.
| Field | Type | Required | Description |
|---|---|---|---|
approved | integer | yes | Ops approved. |
rejected | integer | yes | Ops rejected. |
undecided | integer | yes | Ops still waiting for a decision. |
Example
A request body (ids and values are placeholders), saved as body.json:
{
"expected_release": 0,
"expected_revision": 0,
"ops": [
{
"base_version": 0,
"from_id": "skill_example",
"op": "add_link",
"predicate": "references",
"to_id": "skill_example"
}
]
}curl -sS -X POST "$API_URL/context/v1/changeset/ops" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @body.json