Submit a bulk change
Use a batch when your source supplies several changes together. Read Writing in bulk for policies and limits.
- Read the target workspace’s model and capabilities. Decide whether changes go live or into a change set. Keep the model release and current version claims.
- Prepare items in dependency order: parents before children, then relationships that need those records. Use public IDs or declared unique keys. Choose atomic if nothing may apply on a refusal, or independent if valid items may apply separately.
- Submit through the batch operation, with an idempotency key saved beside the exact request. Choose background preview if you need to review the changes, including cascading deletion impact. Inline execution cannot preview.
- Follow the returned job. In a preview, inspect proposed outcomes, the policy result and whether coverage is complete. A sample does not prove the remaining items are valid. Confirm through the job confirmation operation, or cancel without applying changes.
- After execution, page every item outcome. Record committed IDs and versions, correct rejected source items and inspect why unprocessed items stopped. A successful HTTP response alone does not mean the batch applied completely.
- If the response was lost, replay the exact keyed request. If data was refused for stale versions or changed deletion impact, reread or preview before building a corrected request with a new key. Never change a request under an existing key.
For independent work, retain earlier committed outcomes when a job fails or is cancelled. For an atomic refusal, nothing from the batch applied. Check which case occurred before planning a retry.
Keep a reconciliation ledger
Section titled “Keep a reconciliation ledger”For each submitted batch, save the exact request, idempotency key, workspace, model release, job ID and your source-row references. Record the policy and whether it was preview or execution. Keep the credentials separately. The batch and job operations define the request and result fields.
After confirmation, wait for a final job state and page item outcomes until there is no continuation. Separate applied changes, unchanged applied items, rejected items and unprocessed items. For example, if an independent batch loads a parent but refuses a child, keep the committed parent’s ID. Correct the child and any dependent relationships without blindly recreating that parent.
A correction is a new request with a new key. A network retry is the same saved request with the same key. If the old key has expired, first reconcile IDs, unique keys and versions against current data: the server can no longer recognise it as a replay. Cancel a pending job when abandoning it, then inspect what committed before cancellation. Cancelling or deleting your local ledger does not undo those changes.
Change relationship values from a grid selection
Section titled “Change relationship values from a grid selection”Use this sequence when an integration needs to set one scalar value across many connections, possibly linking missing pairs. It uses the synchronous grid-change operation, not the job submission and confirmation sequence above. Read Relationships and their values for the read models, permissions and version rules.
- Read the model and the grid. Keep the workspace, application, relationships-table view and context. Confirm that the binding carries the attribute you intend to change. JSON values cannot use this operation.
- Choose source rows either by
fromObjectIds, or byallMatching: truewith the grid’s search and filters, minusexceptObjectIds. Use exactly one selection method. Search, filters and exceptions belong only to all-matching selection. Each body filter includesfield,operatorand its lexicalvalue; operators have the same meaning as in the grid read. - Choose 1–50
toObjectIds. These are the column records to affect, not every column the workspace could supply. Preserve the intended column IDs when a grid read reports more matching columns than it can show. A relationship-value filter matches through a connection to these selected columns. - Send
dryRun: truewith the value andlinkMissingchoice. Null clears the named attribute; false sets a Yes or no value to No. Missing connections are left alone unlesslinkMissing: trueasks to create them with that value. - Read
change,same,missing,linkedand everyrefuseditem. Use each item’sfromObjectIdandtoObjectIdto identify the pair in your source data, including refusals for existing relationships. A refused new link hasrelationId: null. The preview checks all selected pairs, not a sample. A 200 preview with refusals is not permission to apply a partial result. Correct the selection, model rule or value first. - Send the reviewed selection with
dryRun: false. The operation checks current data again and applies all changes together. It does not accept a saved preview token or a relationship version per pair: an intervening live edit can change what the selection matches. If exact per-connection version claims are required, use the batch sequence below. - Reread the result, including rows hidden by a filter on the old value. For a change set,
supply
changeSetIdandexpectedChangeSetVersionon both requests. Keep the apply’s returnedchangeSetVersion; the dry run does not advance it. Review and publish separately.
Reference-data example: the Network application’s stop-operators grid reads the
stop-to-operator binding. It carries Local name (local-name), Primary contact (is-primary)
and Inspected on (inspected-on). To preview setting Primary contact on Tschamut-Selva’s
connection to Matterhorn Gotthard Bahn (fo):
POST /api/v1/relations/grid-change HTTP/1.1Host: <instance>Authorization: Bearer <management-token>Content-Type: application/json
{ "workspaceKey": "graubuenden", "applicationKey": "network", "viewKey": "stop-operators", "fromObjectIds": ["8d90eede-23cf-47c1-8dac-cb37956f5fd5"], "toObjectIds": ["f94ef862-2a95-4675-9e31-6b1d0a03317f"], "attributeTypeKey": "is-primary", "value": true, "linkMissing": false, "dryRun": true}The reference instance returns this preview: the connection exists and has no Primary contact value.
{ "dryRun": true, "change": 1, "same": 0, "missing": 0, "linked": 0, "refused": [], "changeSetVersion": null}For a filtered selection, replace fromObjectIds with, for example:
{ "allMatching": true, "exceptObjectIds": [], "search": "", "filters": [{"field": "relation:is-primary", "operator": "isNull", "value": "true"}]}This is a selection excerpt, not a whole request: retain the workspace, view, column IDs, attribute, value and preview choice from the request above. It selects source records with an existing connection to one of those columns whose primary value is empty. It does not select unlinked pairs merely because they have no primary value.
An apply refusal is RELATION_BATCH_REFUSED (409 for a stale version, otherwise 422), with
item codes and messages in details.items, and writes nothing. Reconcile each refused pair
using its endpoint IDs, just as in the dry run; keep its relationship ID when present. The
grid-change operation
describes the result fields. 422 INVALID_GRID_CHANGE means the attribute,
value or endpoint type is invalid. Model or request-shape errors must be corrected, not retried
unchanged. 413 BATCH_TOO_LARGE reports the ATOMIC_JOB_MAX_ITEMS ceiling, including during
a dry run. The limit counts values that would change plus missing pairs to link, not source
rows. Narrow rows or columns, or coordinate a limit change with the operator.
Change values on known relationship IDs
Section titled “Change values on known relationship IDs”- Read each relationship’s full attributes and
relationVersion, keeping its workspace or change-set context. Use the relationship’s version, not its endpoint’s or mapping set’s version. - Submit the relationship-value batch
with one item per relationship. Supply its
id,expectedVersionand only the attributes to set or clear. The batch merges these values; null clears a named value and omitted attributes stay. A single relationship PATCH instead replaces the full attribute set. - For Live, name
workspaceKey; for a change set, includechangeSetIdandexpectedChangeSetVersion. On success, retain returned relationship versions and anychangeSetVersion. Results follow input order. - On
RELATION_BATCH_REFUSED, reconciledetails.itemsby index, relationship ID and item error code. Each item also carriesfromObjectIdandtoObjectIdwhen the relationship still exists, so you can identify its pair in your source data. If the relationship cannot be found, use the index and relationship ID instead; endpoint IDs are absent. A stale item makes the response 409, other refusals 422, and nothing applies. Read current values before sending corrected version claims. Repeating an ID isDUPLICATE_BATCH_ITEMS; an oversized request is413 BATCH_TOO_LARGEunderBATCH_MAX_ITEMS.
This direct batch has no background job or job-confirmation step. After a lost response, read the relationships to reconcile their state before sending another write.
Reference names and identities: Source: opentransportdata.swiss, Service Points (Didok), Federal Office of Transport / SBB, snapshot 2026-11-02. Relationship values are sample data; the preview above was captured from the reference instance without applying it.