TeamGriddeveloper
TeamGrid Developer

Resource concurrency

Use strong ETags and If-Match, and verify the owning cell has qualified concurrency enforcement.

The qualified API v1 concurrency contract uses explicit preconditions for protected writes. Read the resource, retain the strong ETag response header, and send that value unchanged as If-Match with the mutation. Never derive an ETag from an ID, timestamp, or another resource.

Deployment qualification

As of 29 September 2026, the resource-revision rollout gates for the core project, task and project-template contracts are disabled in the hosted DE and US cells. In this compatibility mode, the API requires a correctly formed If-Match header, but the App can discard its expected revision. Receiving an ETag or a successful API readiness response therefore does not prove that a stale mutation will be rejected. Do not rely on these core revisions for unattended concurrent writes until the owning cell’s server-side CAS qualification has been confirmed.

The intended contract below applies once that rollout is qualified. The new MCP write profile remains unreleased while the server-side conflict tests are open. Other resource families retain their separate domain-specific contracts listed below.

Projects, tasks, and project templates

The 1.2.0 contract exposes developerRevision and developerUpdatedAt on projects, tasks, and project templates. Their item reads and synchronous mutation responses include a strong ETag and Cache-Control: private, no-store, no-transform.

Exactly 18 core mutations require If-Match:

Resource Protected mutations
Projects Update, replace sharing, complete, reopen, archive, and restore
Tasks Update, duplicate, move, replace checklist, archive, restore, complete, and reopen
Project templates Update, archive, restore, and instantiate

Project lifecycle commands and template instantiation are asynchronous. Their accepted operation contains the immutable sourceRevision; a successful terminal operation contains resultRevision. Operation reads created before revision tracking return 410 rather than silently weakening the concurrency guarantee.

project=$(teamgrid projects get "$PROJECT_ID" --output json)
revision=$(printf '%s' "$project" | jq -er '.attributes.developerRevision')

teamgrid projects update "$PROJECT_ID" \
  --data '{"name":"Reviewed project"}' \
  --if-match "prj1-$revision"

The SDK also accepts the strong ETag returned in transport metadata:

const task = await teamgrid.tasks.get('task-id')
await teamgrid.tasks.update(
  task.data.id,
  { name: 'Reviewed task' },
  { ifMatch: task.transport.headers.etag },
)

Duplication also requires an idempotency key because it creates a new resource. Its precondition is the exact source revision, so retrying the same request cannot silently copy a newer task:

await teamgrid.tasks.duplicate(
  task.data.id,
  { copyChecklist: true, name: 'Reviewed task copy' },
  {
    idempotencyKey: 'review-copy-2026-07-27',
    ifMatch: task.transport.headers.etag,
  },
)

After a successful mutation, retain the newly returned ETag before making another change. Do not reuse the pre-mutation validator.

Other protected resources

Another 48 operations retain their domain-specific compare-and-set contracts:

Resource family Protected mutations
Appointments and absences 6
Comments 2
Documents and files 6
Custom-field values 2
Planned work 1
Recurring-task series, versions, templates, occurrences, and task detachment 13
Members, invitations, roles, and groups 8
Service-account resource grants 1
Time-entry billing 1
Automation definitions and runs 4
Workspace settings 1
Webhook configuration and secret rotation 2

Revision formats are intentionally resource-specific. Always use the validator returned by the corresponding read operation.

Failure contract

Status and code Meaning Action
400 invalid_precondition The validator is malformed, weak, duplicated, or belongs to another resource contract Correct the request using the latest endpoint response
412 precondition_failed The resource changed after it was read Re-read, reconcile, and retry only after a new decision
428 precondition_required A protected mutation omitted If-Match Read the resource and send its latest strong validator
503 service_unavailable The owning cell cannot currently prove the concurrency contract Keep the precondition and retry later with bounded backoff

Never respond to 412 or 503 by removing If-Match. Concurrency qualification is cell-local. API readiness can be healthy in compatibility mode, so it must not be used by itself as evidence that core-resource compare-and-set enforcement is active.

Stable documentation · Developer Platform · Reviewed 2026-09-29Edit this page ↗
Documentation feedbackWas this page useful?
Esc

Search TeamGrid Developer

Find guides, concepts and every API operation.