> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sprig.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Versioned writes with ETag

> Prevent lost updates by using ETag and If-Match on Study API writes.

The Study API uses optimistic concurrency for writes that change an authored Study definition.
Every such write must prove which Study version it was based on.

## Versioned write flow

1. Read the Study or relevant sub-resource.
2. Save the response's quoted `ETag` value.
3. Send that exact value in `If-Match` with the write.
4. Save the new `ETag` returned by the successful write.

```bash theme={null}
curl "https://api.sprig.com/v2/studies/$STUDY_ID" \
  --header "Authorization: API-Key $SPRIG_API_KEY" \
  --dump-header /tmp/study-headers
```

If the read returns `ETag: "126300"`, send:

```bash theme={null}
curl --request PATCH "https://api.sprig.com/v2/studies/$STUDY_ID" \
  --header "Authorization: API-Key $SPRIG_API_KEY" \
  --header 'If-Match: "126300"' \
  --header "Content-Type: application/json" \
  --data '{"name":"Quarterly product feedback"}'
```

Do not remove the quotes, synthesize an ETag, or reuse an ETag after a successful versioned write.
The `version` field on a Study represents the same version, but using the response ETag avoids
formatting mistakes.

## Conflict responses

| Status | Code | Meaning | Recovery |
| - | - | - | - |
| `400` | `INVALID_VALUE` | `If-Match` is malformed or not a quoted Study version. | Send the exact quoted ETag returned by a read. |
| `428` | `CONCURRENT_UPDATE` | `If-Match` is missing. | Read the resource and retry with its ETag. |
| `412` | `CONCURRENT_UPDATE` | Another writer changed the Study after your read. | Read the latest state, reapply your intended change, and retry once with the new ETag. |

Never retry a `412` with the same body and ETag in a loop. Re-read first so that you do not overwrite
another writer's changes.

## Writes that require If-Match

Versioned writes include:

* Updating or deleting a Study.
* Creating, updating, or deleting Questions and Blocks.
* Creating, replacing, or clearing targeting.
* Replacing, patching, or deleting a translation.

The response to a successful versioned write includes the next ETag, even when the body is empty.

## Operations without If-Match

These operations do not mutate the authored Study version:

* Creating a Study.
* Uploading, listing, reading, or deleting assets.
* Validating a Study.
* Listing or creating invitations.
* Starting, reading, or cancelling a translation job.
* Reading any resource.

Some of these operations still require the Study to be editable or enforce their own idempotency
rules. The absence of `If-Match` does not remove those constraints.

## Coordinate multiple writers

For systems with several workers:

* Serialize writes per Study when practical.
* Pass the latest ETag with the work item.
* Treat a `412` as a signal to reconcile, not as a transient network error.
* Read after an ambiguous timeout before deciding whether to retry.
