Skip to main content
Version: 2025-05-27

Understanding If-Match and ETag headers

Our API uses optimistic locking to prevent you from accidentally overwriting changes made by another user. We do this using a combination of the ETag and If-Match HTTP headers. An ETag is a unique identifier for a specific version of a resource.

By sending the ETag back to us when you're updating a resource, you can ensure that you're working with the most recent version.

To illustrate, imagine two users attempting to update the same project simultaneously. Without optimistic locking, the last user to save would overwrite the changes made by the first. With optimistic locking, the second user's update would be rejected because the ETag associated with their version of the project no longer matches the current version on the server.

The ETag approach is advantageous because it assumes conflicts are rare. Instead of locking resources preemptively (pessimistic locking), it allows concurrent operations to proceed and only checks for conflicts at the time of update. This can lead to improved performance and responsiveness, particularly in systems with high concurrency. However, it's important to handle potential update failures gracefully, typically by prompting the user to refresh their data and re-apply their changes.

Working with If-Match and ETag

The workflow is straightforward:

  1. GET a resource to retrieve its current state and ETag.
  2. PUT or PATCH the resource, passing the retrieved ETag in the If-Match header.
  3. Handle the API response based on the status code.

Step 1: Retrieve a resource and its ETag

First, make a GET request for the resource you want to update. The server's response will include an ETag header. You'll need to store this value.

Example response for a GET request

HTTP/1.1 200 OK
Content-Type: application/json
ETag: "17b355d5032729494348496464522071"

{
... resource data ...
}

Step 2: Send an update with the If-Match header

Next, when you send your PUT or PATCH request to update the resource, include the If-Match header with the ETag value you received in the previous step.

Example PUT request with the If-Match header

PUT /resource HTTP/1.1
Host: api.example.com
Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/json
If-Match: "17b355d5032729494348496464522071"

{
... updated resource data ...
}

Step 3: Handle the API response

On success

If the ETag you provided in the If-Match header matches the current version on the server, your update will be successful. You'll receive a 200 OK response.

On conflict

If another user or process has updated the resource since you fetched it, the ETags won't match. The server will reject your update and return an HTTP 412 Precondition Failed error. This prevents you from accidentally overwriting the other changes.

When this happens, you should:

  1. Alert your user that the data has changed.
  2. Fetch the resource again to get the latest version and the new ETag.
  3. Allow the user to re-apply their changes if they wish.

Example error response if the ETag doesn't match

HTTP/1.1 412 Precondition Failed
Content-Type: application/json

{
"error": {
"code": "conflict",
"message": "The resource was modified by another request. Please retrieve the latest version and try again."
}
}