Skip to content

This is the staging environment's documentation. It is a draft and may change at any time.

Conditional requests

Conditional requests do two jobs:

  • Reading only what changed. Send If-None-Match with an ETag you hold, and get 304 with no body if the resource hasn’t changed.
  • Not overwriting someone else’s change. Send If-Match with the ETag you last read when you replace or change a resource, and get 412 if it has changed since.

A response that returns a single resource carries a strong ETag header. It identifies that exact representation, and changes when the representation changes. A POST that creates a resource returns the ETag that a later GET of the same representation returns.

Treat an ETag as opaque. Send it back exactly as you got it, quotes included.

An operation that reads a single resource accepts If-None-Match. The reference lists it for each operation. This sample reads an organization, so the client needs org:read.

Read a resource, then ask again if it changed
API_BASE='https://api-staging.fedwright.com/v1'
ORG_ID='YOUR_ORGANIZATION_ID'
etag=$(curl -sS -D - -o /dev/null "$API_BASE/orgs/$ORG_ID" \
-H "Authorization: Bearer $token" | tr -d '\r' | awk 'tolower($1) == "etag:" {print $2}')
curl -sS -i "$API_BASE/orgs/$ORG_ID" \
-H "Authorization: Bearer $token" \
-H "If-None-Match: $etag"

When the ETag still matches, the answer is 304 Not Modified with the ETag header and no body. Use the copy you already have. When it doesn’t match, the answer is 200 with the new body and a new ETag.

  • If-None-Match can hold several ETag values, separated by commas, or *.
  • The comparison is weak, as HTTP defines it for If-None-Match, so an ETag that a proxy marked weak (W/"...") still matches.
  • A 304 counts toward your rate limits like any other request.

A PUT or PATCH of a resource requires If-Match. Among the operations a machine client can call, replaceSavedSearch is one.

  1. GET the resource and keep its ETag.
  2. Send your change with If-Match set to that ETag.
  3. On 200, use the response body and its new ETag for the next change.

The sample reads the saved search with getSavedSearch, which needs org:read, and replaces it with replaceSavedSearch, which needs searches:write. The ETag must come from the same saved search that you replace.

Replace a saved search
API_BASE='https://api-staging.fedwright.com/v1'
ORG_ID='YOUR_ORGANIZATION_ID'
SAVED_SEARCH_ID='YOUR_SAVED_SEARCH_ID'
etag=$(curl -sS -D - -o /dev/null "$API_BASE/orgs/$ORG_ID/saved-searches/$SAVED_SEARCH_ID" \
-H "Authorization: Bearer $token" | tr -d '\r' | awk 'tolower($1) == "etag:" {print $2}')
curl -sS -X PUT "$API_BASE/orgs/$ORG_ID/saved-searches/$SAVED_SEARCH_ID" \
-H "Authorization: Bearer $token" \
-H "If-Match: $etag" \
-H 'Content-Type: application/json' \
-d '{"name": "Step assemblies, open", "alerting": false, "query": {"q": "step assy"}}'
Answer Meaning
200 The change was made. The body is the new representation, with its ETag.
400 (bad-request) There was no If-Match header. The errors field names it.
412 (precondition-failed) The ETag is stale. Nothing changed.

The match for If-Match is strong. A weak ETag (W/"...") and * don’t match, because the write has to name the exact representation it changes.

On 412, read the resource again, apply your change to what you find, and send it with the new ETag. Don’t retry the same request, because it will fail the same way.

PATCH operations take a JSON Merge Patch (RFC 7396) with the media type application/merge-patch+json.