Skip to content
OperadeDocs

Search documentation

Type to search documentation.

Documentation
Copy page
Open raw Markdown

Idempotency and concurrency

The Operade API does not support a general Idempotency-Key header. Safe repetition depends on the individual operation and, for branch history, on explicit concurrency fields.

Retry classification#

GET requests are normally safe to repeat. A failed validation request can be corrected and submitted again. Do not blindly repeat create, publish, merge, rebase, reconcile, revert, deployment, or delete operations after an unknown network result. First fetch current state or history and determine whether the intended change already occurred.

Telegram update handling is deduplicated by provider update identity, so receiving the same update twice does not create a second agent turn. That provider behavior is not a general customer-API idempotency contract.

Preview-bound operations#

Merge and rebase execution bind the reviewed result to the source tip, target tip, selected options, and preview_hash. If a tip or option changes, create a new preview and review it again. A branch_preview_stale response is protection against executing a result different from the one the caller saw.

Draft reconciliation similarly binds the base, current branch tip, and draft state. Submit a resolution for every reported conflict. If any bound state changes, reload and reconcile the new state rather than replaying old choices.

Expected state fields#

Revert-to-draft uses expected_tip_version_id and can use expected_draft_hash when replacing an existing draft. Publish rejects a draft whose recorded base is older than the Branch tip with conflict_stale_draft. These values are comparisons, not locks held by the client.

Endpoint-specific behavior#

Concurrency behavior is not universal across mutations:

  • Preview-bound mutations: merge and rebase execution return HTTP 409 with branch_preview_stale when the submitted tips, options, or preview hash no longer match. Reconciliation returns HTTP 409 with draft_reconcile_stale when its base, tip, or draft hash changed. These operations require a fresh preview.
  • Expected-state revert: revert-to-draft returns HTTP 409 when the Branch tip changed, a draft already exists without explicit replacement, or the replacement hash changed. Fetch the latest Branch and Draft before deciding whether to submit again.
  • Publish: a stale Draft returns HTTP 409 and remains available for reconciliation. A Draft identical to the current version also returns a conflict code instead of creating another Version.
  • Draft saves: saving a Draft uses a per-user, per-Agent, per-Branch upsert without a caller-supplied revision field. Concurrent accepted saves are serialized internally, but a later accepted save can overwrite the earlier Draft configuration. Read the Draft after an uncertain result before sending more edits.
  • Branch metadata: accepted changes are applied under server-side locks, but the request has no caller revision token. Two accepted updates to the same mutable field can therefore leave the later committed value visible.
  • Deployment updates: traffic changes lock the relevant server records and reject archived, unpublished, or invalid Branch targets. Repeating an already-current distribution is a no-op; different valid concurrent requests are serialized, and the last accepted write becomes the current distribution. There is no client revision field for this endpoint.
  • Creates and deletes: these operations do not expose a general replay key. A repeated create may produce another resource or a validation conflict, while repeating a delete can observe that the resource is already absent. Inspect current state after an unknown network result.

Telegram update handling remains the narrow idempotent exception described above; it does not change these customer API contracts.

Recovery after uncertainty#

After a timeout, fetch the Agent, Branch, Version history, Deployment history, or Draft that the mutation would have changed. Compare returned immutable identifiers and timestamps with the intended result. Retry only when current state proves the first mutation did not apply and the operation remains valid.

Surface a returned conflict for fresh review. Where an endpoint has overwrite semantics, do not assume the absence of HTTP 409 preserved an earlier value: read the resource again. Never hide either case behind an unlimited automatic retry loop.

See Merge and rebase, Reconcile and revert, and API errors.

On this page
  1. Retry classification
  2. Preview-bound operations
  3. Expected state fields
  4. Endpoint-specific behavior
  5. Recovery after uncertainty