INTERNET-DRAFT A. Jurkovikj
Intended status: Best Current Practice 16 May 2026
Expires: 17 November 2026
HTTP Profile for Synchronized Resource State
(Agentic State Transfer)
draft-jurkovikj-httpapi-agentic-state-01
Abstract
HTTP resources are frequently exposed in multiple representations
(e.g., text/html for rendering and application/json for
processing) via Content Negotiation. Standard HTTP validators such
as ETags identify selected representations, while many
applications need concurrency control over a shared logical
resource state. This creates a synchronization gap where a client
modifying one representation cannot guarantee consistency with the
underlying state of another representation, leading to race
conditions and "lost updates" in multi-client environments.
This document specifies Agentic State Transfer (AST), an HTTP
profile for managing Canonical Resource State (CRS) across
multiple synchronized representations of the same resource. It
defines a State-Bearing Representation (SBR) whose strong ETag
acts as the AST semantic validator for the CRS. It further
mandates the use of Optimistic Concurrency Control via If-Match
headers for state-changing operations, ensuring that mutations
applied by agents (whether automated clients, scripts, or human-
driven applications) are atomic and consistent across all views.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Revised BSD License text as described in Section 4.e of the
Trust Legal Provisions and are provided without warranty as described
in the Revised BSD License.
Table of Contents
1. Introduction
2. Terminology
3. The AST Profile
4. Discovery of Synchronized Representations
5. Integrity and Transport
6. Computing and Managing Semantic Validators
7. Conformance Requirements Summary
8. Security Considerations
9. IANA Considerations
1. Introduction
The architecture of the World Wide Web allows a single logical
resource
(identified by a URI) to be represented in multiple formats. A
common
pattern in modern systems is to expose:
* a *Rendered Representation* (e.g., text/html) for human agents,
and
* a *Structural Representation* (e.g., application/json) for
automated
agents.
In AST terminology, rendered representations are typically
Projected
Representations, while a structural representation MAY serve as
the
State-Bearing Representation (SBR) when it exposes the full
Canonical
Resource State.
HTTP provides mechanisms for content negotiation [RFC9110], and
defines
validators such as ETag for caching and conditional requests.
However, in most deployments:
* validators are derived from a particular representation's bytes,
and
* concurrency control, if present at all, is scoped to a single
representation.
This creates a synchronization gap: two clients interacting with
different representations of the same logical resource can
unwittingly
overwrite each other's work.
AST addresses this problem by treating the Canonical Resource
State
(CRS) as the primary object of synchronization, and by
standardizing how
the SBR ETag is used as the profile-specific semantic validator
for that
CRS.
1.1. The Synchronization Problem
Consider a resource /article/123 exposed both as HTML and JSON.
1. Client A (Browser) retrieves the HTML representation.
2. Client B (Automated Agent) retrieves the JSON representation.
3. Client A submits an edit (e.g., via the JSON API or a form
handler
that writes to the CRS), updating the underlying database record.
4. Client B, unaware of the change, computes an update based on
its
stale JSON representation and submits a PUT or PATCH request.
In typical HTTP APIs, at least one of the following is true:
* there is no ETag at all;
* the ETag is tied to the bytes of a specific representation
(e.g.,
JSON only); or
* the server does not enforce preconditions (If-Match).
As a result, Client B's request may succeed, even though:
* its view of the resource is stale, and
* the update logically conflicts with Client A's change.
This is the classic Lost Update problem, now exacerbated by the
growing use of automated agents acting as first-class editors.
1.2. Canonical Resource State (CRS)
To address this, AST introduces the concept of Canonical Resource
State
(CRS):
CRS is the authoritative, logical state of the resource,
independent
of any particular representation or serialization.
For example, the CRS might be:
* a database row (or set of rows),
* a document or abstract syntax tree,
* a domain object in application memory, or
* in a WordPress CMS, the post record in wp_posts with fields like
post_content, post_title, post_status, and associated metadata.
Representations such as HTML, JSON, or Markdown are derived from
the
CRS and are considered projections of that state.
AST defines a profile where:
1. Shared Identity -- All HTTP representations of an AST resource
are projections of the same CRS.
2. Semantic Validation -- Validators (ETag values) are derived
from the CRS, not a specific representation's bytes, so that a
change to the CRS invalidates all representations together.
3. Mandatory Concurrency -- State-changing operations on AST
resources MUST provide a precondition (If-Match) based on the CRS
validator.
This enables safe interaction by automated agents and human
clients,
ensuring they participate in the same state transition model.
1.3. Deployment Models
AST accommodates two common deployment patterns:
Single-URI (Content Negotiation): The SBR and Projected
Representations are served from the same URI based on Accept
headers.
The SBR ETag is returned when the structural media type (e.g.,
application/json) is selected; a different representation-specific
ETag MAY be returned for other media types. Discovery of the SBR
media
type is implicit in the content negotiation.
Multi-URI (Separate Endpoints): The SBR is served from a dedicated
API endpoint (e.g., /api/article/123) while Projected
Representations
are served from other URIs (e.g., /article/123). The rel="state"
link header connects Projected Representations to the SBR
endpoint.
In both models, the SBR ETag serves as the Semantic Validator for
the
shared CRS. Clients MUST use the SBR ETag (not any projection-
specific
ETag) for If-Match preconditions on state-changing operations.
In multi-URI deployments, the SBR endpoint and Projected endpoints
MAY
reside on different authorities, base paths, or even different
servers.
The rel="state" link is the canonical connector that allows
clients to
discover the SBR regardless of deployment topology.
AST is defined as a profile - a set of constraints and conventions
layered
on standard HTTP semantics. Conforming implementations remain
fully
interoperable with generic HTTP clients and servers; AST does not
introduce breaking changes to HTTP.
1.4. Relationship to Dual-Native Pattern
This specification defines an HTTP profile of the Dual-Native
Pattern,
an architectural approach where resources provide both human-
optimized and
machine-optimized representations with formal semantic equivalence
guarantees.
The Dual-Native Pattern is defined in the Core Architecture and
Requirements
specification and demonstrated across multiple domains (HTTP,
databases,
streaming systems, healthcare). AST specifically addresses the
HTTP binding
with focus on safe concurrency control for state-changing
operations.
1.4.1. Terminology Mapping
AST terminology aligns with Dual-Native Pattern concepts as
follows:
- AST Term / Dual-Native Term: Description
- State-Bearing Representation (SBR) / Machine Representation
(MR): Canonical, structured representation for programmatic access
- Projected Representation / Human Representation (HR):
Presentation-optimized interface (typically HTML)
- Semantic Validator (SBR ETag) / Content Identity (CID): Version-
specific strong validator for change detection
- Canonical Resource State (CRS) / Underlying resource state:
Authoritative logical state independent of serialization
- Resource URI / Resource Identity (RID): Stable identifier shared
across representations
- If-Match preconditions / Safe writes: Optimistic concurrency
control via validator preconditions
- If-None-Match conditional requests / Zero-fetch reads: Bandwidth
optimization via validator revalidation
- Content-Digest / Integrity digest: Verification of exact byte-
level payload parity
- rel="state" discovery / Dual-Native Catalog (DNC) entry:
Discovery mechanism connecting representations
1.4.2. Critical Properties Coverage
AST implements the critical properties identified in the Dual-
Native Pattern:
1. Canonical MR: The SBR serves as the deterministic, machine-
readable
representation (Section 3.1)
2. Strong CID: The SBR ETag is a strong validator that changes
whenever the CRS changes (Section 3.2)
3. Safe writes: If-Match preconditions provide optimistic
concurrency
control with explicit conflict signals (Section 3.4)
4. Zero-fetch reads: If-None-Match conditional requests enable
bandwidth
optimization when content is unchanged (Section 3.3)
5. Integrity: Content-Digest provides byte-level verification
independent
of semantic validation (Section 5)
6. Discovery: rel="state" links enable clients to discover the SBR
from
Projected Representations (Section 6)
1.4.3. Scope: HTTP-Specific Binding
AST is specifically an HTTP profile. It defines:
- How to map Dual-Native concepts to HTTP headers (ETag, If-Match,
Content-Digest, Link)
- HTTP-specific status codes (412, 428, 304)
- Content negotiation patterns (single-URI vs multi-URI)
- HTTP caching semantics for SBR and Projected Representations
AST does not address:
- Database, streaming, or IoT bindings (see Dual-Native
Implementation Guide)
- Full catalog/registry specifications (DNC is out of scope; AST
covers
point-to-point discovery only)
- Schema evolution or version migration strategies
- Authentication/authorization mechanisms (domain-specific)
For the broader architectural context, see the Dual-Native Pattern
Whitepaper.
For formal cross-domain requirements, see the Core Architecture
and
Requirements specification.
2. Terminology
Note: AST terminology is consistent with the Dual-Native Pattern
specification family. See Section 1.4.1 for detailed mapping.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY",
and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14
[RFC2119] [RFC8174] when, and only when, they appear in all
capitals.
Canonical Resource State (CRS)
: The underlying, authoritative logical state of a resource (e.g.,
the
database record or abstract syntax tree). The CRS is the atomic
unit
of concurrency.
State-Bearing Representation (SBR)
: A specific representation (e.g., application/json) that exposes
the
CRS in a lossless, deterministic format. The SBR serves as the
Concurrency Token for the resource. Its ETag represents the
version of
the CRS.
State-Bearing Endpoint
: The HTTP endpoint (URI) that serves the State-Bearing
Representation.
This is the primary target for state-changing operations and the
authoritative source of the Semantic Validator.
Projected Representation
: A representation derived from the CRS for a specific consumption
pattern (e.g., text/html for rendering, text/csv for analysis).
Projected Representations reflect the CRS but do not govern it.
State-changing operations SHOULD be directed to the State-Bearing
Endpoint; see Write Semantics for handling writes at other
endpoints.
Semantic Validator
: The strong ETag associated with the SBR. It MUST change whenever
the
CRS changes. It SHOULD NOT change when the CRS has not changed,
although implementation factors (for example, canonicalization or
hashing algorithm changes, migrations, or salting strategies) may
occasionally cause validator changes without CRS changes. In this
document, "Semantic Validator" means the AST profile's SBR ETag.
The
separate Semantic-ETag field defined in
[I-D.jurkovikj-http-semantic-validator] is a related HTTP
extension but
is not required by this profile.
AST Resource
: A logical Canonical Resource State (CRS) that may be exposed via
one or
more HTTP endpoints (URIs). Endpoints that share the same CRS
share the
same Semantic Validator (SBR ETag) for concurrency purposes.
3. The AST Profile
This section defines the Agentic State Transfer (AST) profile. It
specifies how clients synchronize state across multiple
representations
by pivoting on the State-Bearing Representation (SBR).
3.1. Representation Roles
For a given AST Resource, the server MUST designate exactly one
representation as the State-Bearing Representation (SBR). All
other
representations are considered Projected Representations.
* The SBR acts as the source of truth for state synchronization.
* Projected Representations are derivative views. While they MAY
have
their own caching validators (ETags) based on their specific byte
sequences, they MUST NOT be used as the basis for state-changing
preconditions on the CRS.
Endpoints that expose distinct CRS values (i.e., different logical
resources) MUST use distinct Semantic Validators. Conversely,
endpoints
that share the same CRS MUST be bound to the same Semantic
Validator for
concurrency control, meaning they MUST direct clients to the same
SBR
ETag for If-Match preconditions. Projected endpoints MAY emit
their
own representation-specific ETags for caching purposes, but these
MUST
NOT be used for CRS concurrency control.
3.2. Semantic Validators (The SBR ETag)
The server MUST assign a Strong ETag to the SBR. This ETag serves
as the
AST Semantic Validator for the resource. Because If-Match uses the
strong comparison function [RFC9110], weak entity-tags are not
suitable
for AST concurrency control; a weak ETag will never satisfy an
If-Match precondition.
* Determinism: The SBR ETag MUST change whenever the CRS changes.
* Scope: The SBR ETag MUST NOT be reused as the ETag for Projected
Representations, as this would confuse standard HTTP caches.
Canonicalization: Implementations SHOULD compute the SBR ETag from
a
deterministic canonical serialization of the CRS. When the SBR
uses
JSON, servers MUST canonicalize using the JSON Canonicalization
Scheme
([RFC8785]) or a profile-specified, equivalently deterministic
canonicalization before computing the validator. This ensures that
logically identical states produce identical validators,
regardless of
field ordering or formatting variations. See the Canonicalization
subsection in Computing and Managing Semantic Validators for
detailed
guidance.
3.2.1. ETag Computation (Informative)
The SBR ETag MUST be a strong validator as defined in [RFC9110].
Implementations MAY compute the SBR ETag using any method that
satisfies
both the determinism and strong validator requirements. Common
approaches
include:
* Content Hash: SHA-256 or similar cryptographic hash over the
canonicalized SBR bytes (e.g., "sha256-YWJjMTIz..."). This is
RECOMMENDED for deployment predictability, as it supports
reproducible
validator generation and naturally produces strong validators.
* Version Counter: Monotonic version number from the data store
(e.g., "v42" or "rev-1234"). This is simple but requires
centralized version tracking. The version must increment on every
CRS
change to maintain strong validator semantics.
The content hash approach provides the strongest guarantee that
identical
CRS values produce identical ETags within the same
canonicalization and
validator-construction regime, which aids debugging and
distributed
deployments.
3.2.2. Relationship to Semantic-ETag
This profile uses the standard ETag field on the SBR as the AST
Semantic Validator because If-Match and If-None-Match already
define
strong validator behavior for state-changing and conditional
requests.
The separate Semantic-ETag extension
[I-D.jurkovikj-http-semantic-validator] defines an HTTP field for
carrying a server-defined semantic validator independently of the
selected representation. Deployments that support both profiles
can
expose Semantic-ETag on Projected Representations as an additional
signal for clients that understand it. Such use does not replace
the AST
requirement that CRS mutations use the SBR ETag, discovered
through the
SBR endpoint, as the If-Match precondition unless a later AST
revision
explicitly defines otherwise.
A future revision of AST might define If-Semantic-Match as an
alternative to SBR discovery for deployments that expose
Semantic-ETag; this revision does not define that alternative.
3.2.3. Encodings and ETags
SBR endpoints MUST NOT apply content-codings to SBR responses; the
Content-Encoding header field MUST be absent. (The identity token
is reserved in HTTP and MUST NOT appear in Content-Encoding
[RFC9110].)
This requirement ensures the SBR ETag remains a single, stable
strong
validator suitable for If-Match concurrency control.
SBR endpoints SHOULD include Cache-Control: no-transform to
prevent
intermediaries from applying transformations in transit.
Clients SHOULD indicate that no content-codings are acceptable
when
retrieving the SBR, for example by sending Accept-Encoding:
identity
or by omitting Accept-Encoding entirely if the client does not
support
any codings.
Deployments that cannot avoid content-coding at a given URI (for
example,
due to platform or intermediary constraints) SHOULD NOT designate
that URI
as the SBR. Instead, they SHOULD expose a separate SBR endpoint
that can
be served without content-coding and link to it using rel="state".
The
content-coded URI MAY be treated as a Projected Representation.
3.3. Read Semantics
3.3.1. Reading the SBR
Clients SHOULD use the SBR ETag for conditional requests
(If-None-Match) on the SBR URI. The server MUST return 304 Not
Modified if the CRS has not changed. On a 304 response, the server
SHOULD include the current SBR ETag in the response headers.
Clients SHOULD NOT use the SBR ETag as If-None-Match against
Projected
endpoints. Projected endpoints have their own byte-specific
validators;
using the SBR ETag would result in unnecessary cache misses and
conflates
semantic validation with byte-level caching.
Example: HEAD Request to Fetch SBR Validator
Clients MAY use HEAD to obtain the current SBR ETag without
transferring
the full representation body:
HEAD /api/article/123 HTTP/1.1
Host: example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
Content-Length: 4521
This allows clients to check for state changes with minimal
bandwidth
usage before deciding whether to fetch the full representation.
3.3.2. Reading Projections
Clients MAY cache Projected Representations using their specific
ETags.
However, clients MUST recognize that a Projected Representation
may be
stale relative to the CRS if the SBR ETag has changed.
3.3.3. Low-Overhead Change Detection (Informative)
Clients monitoring resources for changes (e.g., polling for
updates) can
minimize bandwidth by using conditional requests with HEAD or GET.
Pattern 1: HEAD + If-None-Match (Minimal Overhead)
HEAD /api/article/123 HTTP/1.1
Host: example.com
Accept: application/json
If-None-Match: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
HTTP/1.1 304 Not Modified
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
If the resource has changed:
HEAD /api/article/123 HTTP/1.1
Host: example.com
Accept: application/json
If-None-Match: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
HTTP/1.1 200 OK
ETag: "sha256-NEWVALIDATOR456"
Content-Length: 4721
The client detects the ETag change without transferring the body,
then
performs a GET to retrieve the updated representation only when
needed.
Pattern 2: GET + If-None-Match (Conditional Transfer)
GET /api/article/123 HTTP/1.1
Host: example.com
Accept: application/json
If-None-Match: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
HTTP/1.1 304 Not Modified
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
This pattern combines checking and fetching in one request. If
unchanged,
the server returns 304 with no body. If changed, it returns 200
with
the new representation, saving a round trip compared to HEAD-then-
GET.
Recommendation for Polling: Use Pattern 2 (GET + If-None-Match)
when
the client expects frequent changes and will fetch the body most
of the
time. Use Pattern 1 (HEAD + If-None-Match) when changes are
infrequent
and the client needs the ETag for other purposes (e.g., preparing
an
If-Match precondition for a future write).
3.4. Write Semantics (The Safe Write Protocol)
To modify the Canonical Resource State, clients MUST perform the
mutation against the SBR Endpoint (or an endpoint explicitly bound
to
the SBR's validator).
Clients MUST NOT use a Projected Representation's ETag as an
If-Match precondition for CRS mutations. Only the SBR's own ETag
is
valid for concurrency control.
1. Precondition: The client obtains the current SBR ETag (via GET
or HEAD on the SBR URI).
2. Mutation: The client sends the state-changing request (PUT,
POST, PATCH, DELETE) including the If-Match header set to
the SBR ETag.
3. Verification:
* If the If-Match header is missing, servers SHOULD respond with
428 Precondition Required [RFC6585]. Servers MAY respond with
400 Bad Request if 428 is not supported by the implementation
environment, provided the error body clearly indicates the missing
precondition requirement.
* If the provided ETag does not match the current CRS version, the
server MUST respond with 412 Precondition Failed.
* If the provided ETag matches the current CRS version, the server
MAY perform the write if the request is otherwise authorized and
valid. If the server performs the write, it MUST update the CRS
and ensure subsequent Projected Representation responses are
derived from the updated state. Projected validators SHOULD change
when the projection bytes change.
Note: HTTP provides no general mechanism for servers to actively
invalidate cached Projected Representations in shared caches or
CDNs.
Clients that perform CRS mutations SHOULD invalidate their own
locally
cached projections; intermediary caches will expire based on their
Cache-Control directives.
Note: For endpoints that do not implement AST semantics,
servers MAY accept unconditional writes as in traditional HTTP
APIs.
See the "Non-AST Resources and Fallback Behavior" section for
guidance on mixed deployments.
4. Response: Upon a successful write, the server SHOULD convey
the
new SBR ETag to allow the client to chain subsequent updates. The
mechanism depends on the response type:
* If the response body is the SBR representation (e.g., the server
returns 200 OK with Content-Type: application/json containing
the updated state): include ETag: <new-sbr-etag> in the response
headers.
* If the response body is a Projected Representation or empty:
convey
the updated SBR validator via the Link header's state-etag
parameter, the 204 No Content with Content-Location pattern,
or the 303 See Other redirect pattern (see "Returning the Updated
Validator from Non-SBR Endpoints" below).
The ETag header in a response MUST describe the selected
representation in that response [RFC9110]; it MUST NOT be used to
convey the SBR validator when the response body is not the SBR.
3.4.1. Normative Foundations
The AST safe write protocol builds on standard HTTP conditional
request
semantics and status codes:
* Entity Tags and Strong Comparison [RFC9110] Section 8.8.3 and
Section 13.1.1: Define entity-tag syntax and the strong comparison
function used by If-Match. AST requires strong validators because
weak entity-tags never satisfy If-Match preconditions under strong
comparison.
* If-Match Precondition [RFC9110] Section 13.1.1: Defines
precondition
evaluation. The server MUST perform strong comparison between the
provided entity-tag(s) and the current validator. If none match,
the
server MUST respond with 412 Precondition Failed.
* 428 Precondition Required [RFC6585] Section 3: Defines the
status
code for requests that require a precondition but lack one. AST
servers
SHOULD use 428 when If-Match is missing on state-changing
operations.
* 412 Precondition Failed [RFC9110] Section 15.5.13: Indicates
that
precondition evaluation failed. AST servers MUST return 412 when
If-Match does not match the current SBR ETag.
* Problem Details [RFC9457]: Defines application/problem+json for
machine-readable error responses. AST servers SHOULD return
Problem
Details bodies for 412, 428, and 400 (missing precondition)
responses to assist automated conflict resolution.
This normative alignment ensures AST concurrency control
integrates
cleanly with existing HTTP implementations and intermediaries.
3.4.2. Error Handling
For 412, 428, and 400 (when used for missing preconditions)
responses, servers SHOULD return a Problem Details body [RFC9457]
to
assist automated clients in resolving the conflict.
When rejecting a request due to Digest Fields validation failures
(unsupported algorithm, malformed digest value, or digest
mismatch),
servers MAY return 400 Bad Request with a Problem Details body
using
the problem types defined in
[I-D.ietf-httpapi-digest-fields-problem-types]. Servers SHOULD NOT
include the server-computed digest value in error responses to
avoid
potential oracle attacks.
3.4.3. Write Location
State-changing operations SHOULD be performed against the State-
Bearing
Endpoint. Projected endpoints (e.g., HTML rendering URIs) SHOULD
reject
state-changing requests with 405 Method Not Allowed and include a
Link header with rel="state" pointing to the SBR endpoint.
A server MAY designate additional endpoints as accepting state-
changing
operations (e.g., for compatibility with existing form submissions
or
legacy APIs). Such endpoints MUST:
* enforce If-Match against the same Semantic Validator as the SBR,
* advertise the SBR via a Link header with rel="state", and
* return the updated Semantic Validator in a manner consistent
with HTTP
semantics (see below).
Returning the Updated Validator from Non-SBR Endpoints:
In HTTP, the ETag header in a response describes the selected
representation returned in that response [RFC9110]. If a non-SBR
endpoint
returns a Projected Representation (e.g., HTML) after a successful
write,
the ETag header MUST describe that projection, not the SBR.
To provide the updated SBR validator without violating HTTP
semantics,
servers SHOULD use one of the following patterns:
* 303 See Other Redirect (RECOMMENDED): Return 303 See Other with
Location pointing to the SBR URI. The client obtains the updated
ETag from the subsequent GET. This adds a round-trip but is
unambiguous and widely understood.
http
HTTP/1.1 303 See Other
Location: /api/article/123
Link: </api/article/123>; rel="state"; type="application/json"
* 204 No Content with Content-Location: Return 204 No Content with
Content-Location set to the SBR URI and the ETag header set to
the updated Semantic Validator. Because Content-Location
identifies
the representation described by the response metadata, this
approach
is semantically defensible, though some implementations may find
it
unusual.
http
HTTP/1.1 204 No Content
Content-Location: /api/article/123
ETag: "sha256-NEWVALIDATOR123"
Link: </api/article/123>; rel="state"; type="application/json"
* Projection Response with Link Metadata: Return the projection
with
its own ETag, and convey the updated SBR validator via the Link
header using an extension parameter:
http
HTTP/1.1 200 OK
Content-Type: text/html
ETag: "html-v2"
Link: </api/article/123>; rel="state"; type="application/json";
state-etag="\"sha256-NEWVALIDATOR123\""
In this pattern, the response ETag describes the HTML projection,
while the Link header's state-etag parameter conveys the SBR
validator.
Clients MUST use the state-etag parameter value (not the response
ETag) for subsequent If-Match preconditions.
Definition of state-etag Link Extension Parameter:
The state-etag parameter is an extension parameter as permitted by
[RFC8288] Section 3.4.2. Its value is an RFC 8288 quoted-string
whose
decoded content is an HTTP entity-tag as defined in [RFC9110]
Section
8.8.3 (including the surrounding DQUOTE characters). The backslash
escaping is required because Link parameters use the quoted-string
production.
For example, if the SBR ETag is "sha256-ABC123", the Link
parameter
is serialized as state-etag="\"sha256-ABC123\"". Clients
extracting
the entity-tag MUST:
1. Parse the parameter value as an RFC 8288 quoted-string
(removing
outer quotes and unescaping backslashes), yielding
"sha256-ABC123".
2. Use this value directly in If-Match or If-None-Match headers
without additional quoting changes.
This ensures that regardless of which endpoint processes the
write, all
clients can obtain the updated Semantic Validator while
maintaining
correct HTTP semantics.
3.4.4. Patch Formats (Informative)
When using PATCH [RFC5789] for partial updates, servers SHOULD
support one or
more of the following standard patch formats:
* JSON Merge Patch ([RFC7396]): application/merge-patch+json for
simple field-level merging. Suitable for most partial updates.
* JSON Patch ([RFC6902]): application/json-patch+json for
operation-based updates (including array manipulation).
Servers SHOULD document which patch formats they accept. Clients
SHOULD
use the Accept-Patch header (if provided) to discover supported
formats.
Example: 428 Response for Missing Precondition
When a client attempts a state-changing operation without If-
Match, the
server SHOULD return a 428 response:
PATCH /api/article/123 HTTP/1.1
Host: example.com
Content-Type: application/json
HTTP/1.1 428 Precondition Required
Content-Type: application/problem+json
{
"type": "https://example.com/errors/precondition-required",
"title": "Precondition Required",
"status": 428,
"detail": "If-Match header is required for CRS mutations"
}
Alternative: 400 Response When 428 Is Not Available
If the server environment does not support 428, it MAY use 400
with a
clear error message:
PATCH /api/article/123 HTTP/1.1
Host: example.com
Content-Type: application/json
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{
"type": "https://example.com/errors/missing-precondition",
"title": "Missing Required Precondition",
"status": 400,
"detail": "If-Match header is required for state-changing
operations on AST resources"
}
Example: 412 Response with Problem Details
When a client's If-Match precondition fails, the server SHOULD
return a
Problem Details response indicating the current state:
PATCH /api/article/123 HTTP/1.1
Host: example.com
Content-Type: application/json
If-Match: "sha256-ABC123OLDVALUE456789STALE0123"
HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json
Link: </api/article/123>; rel="state"; type="application/json";
state-etag="\"sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F\""
{
"type": "https://example.com/errors/precondition-failed",
"title": "Precondition Failed",
"status": 412,
"detail": "The resource state has changed since you last read
it.",
"current-etag": "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F",
"provided-etag": "sha256-ABC123OLDVALUE456789STALE0123"
}
The current SBR validator is conveyed via both the state-etag Link
parameter (for header-level access) and the current-etag member in
the Problem Details body. This allows clients to immediately retry
with the correct If-Match value or refetch the latest state.
3.4.5. Conflict Resolution (Informative)
When a client receives a 412 Precondition Failed response, it
SHOULD
follow one of these resolution strategies:
1. Refetch and Retry: Fetch the current SBR to obtain the new ETag
and state, then reapply the intended mutation and retry with the
updated ETag.
2. Three-Way Merge: If the client maintains the original state it
read, the changes it intended to make, and can obtain the current
server state, it MAY attempt an automatic merge (similar to
version
control systems). This is only appropriate when changes affect
non-overlapping fields or can be deterministically combined.
3. User Intervention: Present the conflict to the user (human or
automated decision system) for manual resolution, showing both the
client's intended changes and the server's current state.
4. Abort: Abandon the update if the conflict indicates the
client's
view is too stale or the changes are incompatible.
Servers MAY assist conflict resolution by including the current
state or
a conflict diff in the 412 response body (see Problem Details
example
above). This reduces round trips and provides clients with
immediate
context for resolution.
Retry Example:
Client receives 412:
HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json
Link: </api/article/123>; rel="state"; type="application/json";
state-etag="\"sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F\""
Client immediately refetches:
GET /api/article/123 HTTP/1.1
If-None-Match: "sha256-ABC123OLDVALUE456789STALE0123"
HTTP/1.1 200 OK
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
{ ...current state... }
Client reapplies mutation with fresh ETag:
PATCH /api/article/123 HTTP/1.1
If-Match: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
3.4.6. Idempotency
Servers MAY support an Idempotency-Key header for POST and PATCH
to
allow safe retries by automated agents. When a duplicate request
is
received with the same idempotency key and identical semantics,
servers
SHOULD respond with the original status code, headers (including
ETag),
and, if applicable, response body.
Example: Idempotency-Key Usage for Resource Creation
POST /api/articles HTTP/1.1
Host: example.com
Content-Type: application/json
Idempotency-Key: client-txn-abc123
{"title": "New Article", "body": "..."}
HTTP/1.1 201 Created
Location: /api/articles/456
ETag: "sha256-NEWVALUE789XYZ"
Note on Resource Creation: The If-Match requirement applies to
mutations of existing resources. For creating new resources,
clients
typically cannot use If-Match on the target URI (which does not
yet
exist). Servers MAY support creation patterns such as:
* POST to a collection endpoint, returning the new resource URI
and
SBR ETag in the response (as shown above), or
* PUT with If-None-Match: * to create a resource only if it does
not already exist at that URI.
Once created, subsequent mutations to the resource follow the
standard
If-Match protocol.
Note: Idempotency-Key is an opaque token. Per HTTP header grammar,
both
token and quoted-string forms are acceptable; the exact format is
implementation-defined.
Idempotency-Key behavior is intentionally profile-neutral.
Deployments that support this header SHOULD document replay windows,
storage scope, and duplicate-detection semantics.
3.4.7. Asynchronous Updates
For mutations that cannot complete synchronously, servers MAY
respond with
202 Accepted and a Location header pointing to a status resource.
When the mutation completes:
* The status resource SHOULD indicate completion and provide the
URI of
the updated resource.
* A subsequent GET on the updated resource MUST return the new SBR
ETag.
* Clients SHOULD poll the status resource or use server-sent
events /
webhooks if available.
The original If-Match precondition applies at the time the 202 is
issued; the server MUST reject the operation with 412 Precondition
Failed if the precondition fails at that point, even if processing
is
deferred.
3.5. SBR Endpoint Headers
To ensure correct caching and transfer behavior, SBR endpoints
SHOULD
include the following headers:
* Cache-Control: SBR responses SHOULD include Cache-Control:
no-transform to prevent intermediaries from modifying the
representation (which would invalidate the Semantic Validator).
* Vary: For single-URI deployments serving multiple media types
via
content negotiation (e.g., JSON and HTML from the same URI), set
Vary: Accept to ensure caches differentiate by requested media
type.
Since SBR endpoints MUST NOT apply content-coding (per Encodings
and ETags),
Vary: Accept-Encoding is not applicable to the SBR itself.
Note on Content Codings: The Semantic Validator (SBR ETag) is
computed from the canonical, uncompressed representation bytes.
SBR
endpoints MUST NOT apply content-coding; the Cache-Control: no-
transform
directive prevents intermediaries from introducing encoding in
transit.
* Accept-Ranges: SBR endpoints SHOULD include Accept-Ranges: none
if range requests would break the semantic integrity of the
representation (e.g., partial JSON structures).
Example SBR Response Headers:
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
Cache-Control: no-cache, no-transform
Vary: Accept
Accept-Ranges: none
Content-Digest:
sha-256=:RK63H5GH1GQJQM8A7LN7RP8VNR7FVXWH1TQKJM8QZH4=:
3.6. Caching Considerations
3.6.1. SBR Caching
AST caching behavior follows HTTP caching semantics [RFC9111].
SBR endpoints SHOULD follow these caching practices:
* Non-Negotiated SBR: Prefer a single canonical media type for the
SBR to avoid cache fragmentation.
* Strong ETag: The SBR MUST expose a strong ETag as the Semantic
Validator.
* Cache-Control: Use Cache-Control: no-cache, no-transform to
require revalidation while allowing storage. If the SBR contains
sensitive or user-specific data, use Cache-Control: private or
no-store as appropriate.
* Vary: For single-URI deployments serving multiple media types
via
content negotiation, set Vary: Accept to ensure caches
differentiate
by media type. Since SBR endpoints MUST NOT apply content-coding
(per
Encodings and ETags), Vary: Accept-Encoding is not applicable to
the SBR.
* Accept-Ranges: Consider Accept-Ranges: none to prevent
partial-byte range requests that could create ambiguity in state
validation.
* 304 Revalidation: Support conditional requests with If-None-
Match
and respond with 304 Not Modified when the SBR ETag matches.
* ETag Scope: Do NOT reuse the SBR ETag on Projected endpoints, as
this would conflate semantic and byte-level validation.
3.6.2. Projected Representation Caching
Projected Representations SHOULD be cached using standard HTTP
caching
mechanisms:
* Representation-Specific ETags: Use their own ETags based on the
byte content of each projection.
* Standard Cache-Control: Apply appropriate Cache-Control
directives (e.g., max-age, public, private) based on the
projection's volatility and sensitivity.
* Client-Side Invalidation: Clients that perform CRS mutations
SHOULD invalidate their own cached Projected Representations after
a
successful write or upon receiving a 412 Precondition Failed
response. Note that shared caches and intermediaries will not
automatically invalidate projections based on SBR changes.
4. Discovery of Synchronized Representations
To enable agents to discover different representations of the same
AST
resource, servers SHOULD expose relationships between
representations
using the HTTP Link header [RFC8288].
4.1. The state Relation (SBR Discovery)
Projected Representations SHOULD include a Link header with
rel="state"
pointing to the State-Bearing Representation (SBR). This allows
clients
consuming a Projected Representation to discover the SBR for
synchronization or editing.
The state relation identifies the authoritative SBR for
concurrency
control purposes. Clients MUST use the ETag from the state target
(the
SBR) for all If-Match and If-None-Match preconditions on
state-changing operations.
Example (Projected Representation response):
HTTP/1.1 200 OK
Content-Type: text/html
ETag: "html-v1"
Link: </api/article/123>; rel="state"; type="application/json"
4.2. The alternate Relation (General Cross-Representation Navigation)
The alternate link relation type is RECOMMENDED for general
navigation between synchronized representations of the same AST
resource.
When providing an alternate link:
* the type attribute MUST be present to indicate the media type of
the target representation (for example, application/json,
text/html); and
* the profile attribute MAY be used to indicate a specific schema
or capability set of the target representation.
Example (SBR response linking to Projected):
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
Link: </article/123.html>; rel="alternate"; type="text/html"
Note: The state relation specifically identifies the SBR for
concurrency control purposes. In contrast, rel="alternate" is for
general cross-representation navigation and does not imply
concurrency semantics. Clients MUST NOT assume that a
representation
linked via alternate participates in the AST concurrency protocol.
4.3. Bidirectional Linking
To ensure agents can navigate between representations regardless
of
their entry point, linking SHOULD be bidirectional.
* If Representation A links to Representation B, then
Representation B
SHOULD link back to Representation A (or to a canonical URI that
resolves to A).
This ensures that an agent encountering a structural
representation
(for example, JSON) can identify the corresponding rendered
representation (for example, HTML) for attribution, verification,
or
human inspection.
4.4. Profile Advertisement
To enable clients to detect whether a resource implements AST
semantics,
servers SHOULD advertise this using the profile link relation
[RFC6906]
via one of the following mechanisms:
Link Header with Profile Relation:
HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://datatracker.ietf.org/doc/draft-jurkovikj-
httpapi-agentic-state/>; rel="profile"
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
Content-Type Profile Parameter:
HTTP/1.1 200 OK
Content-Type: application/json;
profile="https://datatracker.ietf.org/doc/draft-jurkovikj-
httpapi-agentic-state/"
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
This allows clients to detect AST resources and apply appropriate
concurrency control workflows (If-Match preconditions, 412
handling,
etc.) instead of assuming traditional HTTP semantics.
Implementations MAY advertise either a versioned profile URI
(e.g.,
.../draft-jurkovikj-httpapi-agentic-state-01) or the versionless
profile URI (e.g., .../draft-jurkovikj-httpapi-agentic-state/).
Clients
SHOULD accept both as equivalent identifiers for the purposes of
feature
detection.
5. Integrity and Transport
In standard HTTP usage, ETags often serve a dual purpose:
validating the
semantic state for caching/concurrency, and validating the
integrity of
the response bytes (to detect transport corruption).
In the AST profile, the State-Bearing Representation (SBR) ETag
serves
as the Semantic Validator for the Canonical Resource State (CRS).
Projected Representations MAY have their own representation-
specific
ETags for caching purposes, but these MUST NOT be used as Semantic
Validators for concurrency control.
5.1. Separation of State and Integrity
To allow clients to verify the integrity of the payload bytes
independently of the semantic state, AST servers SHOULD use the
Content-Digest header field defined in [RFC9530].
* ETag (SBR): validates the *Canonical Resource State* (logical
truth) and is used with If-Match and If-None-Match for concurrency
control.
* ETag (Projected): MAY be used for caching individual
representations, but MUST NOT be used for state-changing
preconditions.
* Content-Digest: validates HTTP content according to [RFC9530],
independently of CRS validation.
Clients MUST NOT send If-Match or If-None-Match preconditions
using a Projected Representation's ETag when interacting with the
SBR
endpoint. Only the SBR's own ETag participates in concurrency
control
logic.
Example Response (SBR):
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F"
Content-Digest:
sha-256=:RK63H5GH1GQJQM8A7LN7RP8VNR7FVXWH1TQKJM8QZH4=:
Example Response (Projected):
HTTP/1.1 200 OK
Content-Type: text/html
ETag: "html-v1"
Link: </api/article/123>; rel="state"; type="application/json"
Content-Digest: sha-256=:X8Z9Y7W6V5U4T3S2R1Q0P9O8N7M6L5K4=:
This separation allows intermediaries and clients to detect
payload
integrity failures without conflating them with state changes.
In AST, the SBR ETag serves as a semantic validator for the
Canonical
Resource State. Clients SHOULD use Content-Digest for verifying
HTTP
content integrity. Outside of AST contexts, traditional ETag
usage for caching and integrity remains unchanged.
When content-coding is applied to non-SBR (Projected)
representations,
servers MAY include Content-Digest and/or Repr-Digest [RFC9530]
according to the Digest Fields content-coding rules. Clients that
need
to verify the unencoded representation MAY use Unencoded-Digest
and
express preferences with Want-Unencoded-Digest
[I-D.ietf-httpbis-unencoded-digest], if provided/supported by the
server.
5.2. Request Integrity (Client-Sent Digests)
Clients MAY include Content-Digest or Repr-Digest [RFC9530] on
state-changing requests to allow servers to verify payload
integrity
before processing.
Servers that choose to validate request digests:
* SHOULD document which digest algorithms they accept;
* MUST reject requests with unsupported algorithms or malformed
digests
with an appropriate error response; and
* SHOULD NOT echo the server-computed digest in error responses to
avoid
potential oracle attacks.
When returning errors for digest validation failures, servers MAY
use
the problem types defined in [I-D.ietf-httpapi-digest-fields-
problem-types].
These problem types will be registered in the HTTP Problem Types
registry
upon publication of that specification; servers SHOULD use the
type
member of the Problem Details response to reference the
appropriate URI
as defined in that specification.
Example digest validation error:
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{
"type": "https://iana.org/assignments/http-problem-
types#digest-invalid-values",
"title": "Invalid Digest Values",
"status": 400,
"detail": "The sha-256 digest value has incorrect length"
}
Request digest validation is independent of AST concurrency
control;
If-Match remains the mechanism for preventing lost updates, while
digests verify payload integrity.
6. Computing and Managing Semantic Validators
AST does not mandate a single algorithm for computing Semantic
Validators. However, deployment predictability benefits from
consistent
approaches.
6.1. Canonicalization
A common pattern is to derive the Semantic Validator from a
canonical
serialization of the CRS. For example:
1. Serialize the CRS to a structured format (for example, JSON).
2. Canonicalize the serialization (for example, by sorting keys
and
controlling numeric formats).
3. Compute a hash over the canonical form (for example, SHA-256).
4. Encode and prefix the hash to produce the ETag value.
Servers SHOULD ensure that:
* fields that are purely operational or volatile (for example,
last
access timestamps) are excluded from the canonical form; and
* the canonicalization process is deterministic across
deployments.
Servers MAY use [RFC8785] JSON Canonicalization Scheme (JCS) or an
equivalent deterministic procedure. When the SBR is JSON, servers
MUST
use [RFC8785] or a profile-specified, equivalently deterministic
canonicalization prior to computing the SBR validator.
6.2. Storage Models
Servers MAY:
* compute Semantic Validators on demand from the CRS; or
* store precomputed Semantic Validators alongside the CRS.
When validators are stored:
* they SHOULD be updated atomically with the CRS; and
* they MUST be invalidated or recomputed whenever the CRS changes.
When validators are computed on demand, implementations SHOULD
ensure that the cost of computing the validator is small relative
to the
cost of generating the representation.
6.3. Relationship to Application Backends
AST is agnostic to how applications store and manage CRS. For
example:
* a SQL application might treat a row (or set of rows) as CRS,
with the
Semantic Validator derived from a version column and relevant
fields;
* a document store might treat a document body plus metadata as
CRS;
* a CMS might treat a block tree or content graph as CRS.
The only requirement is that the Semantic Validator change
whenever the
logical CRS changes, regardless of how many representations exist.
6.4. Non-AST Resources and Fallback Behavior
Servers MAY implement AST for some resources and not others.
For resources that do not follow AST:
* servers MAY continue to use representation-specific ETags as
byte
validators;
* servers MAY accept unconditional writes (no If-Match required),
as
in traditional HTTP APIs; and
* clients MUST NOT assume AST semantics.
Servers SHOULD clearly document which resources implement AST.
7. Conformance Requirements Summary
This section provides a checklist of normative requirements for
AST
conformance. Implementations MUST satisfy all items marked
MUST/REQUIRED;
items marked SHOULD/RECOMMENDED are strongly advised.
7.1. Server Requirements
7.1.1. State-Bearing Representation (SBR)
- [ ] MUST designate exactly one representation as the SBR for
each
AST resource
- [ ] MUST assign a strong ETag to the SBR that changes whenever
the
CRS changes
- [ ] MUST NOT apply content-coding to SBR responses (Content-
Encoding
MUST be absent)
- [ ] SHOULD compute SBR ETag from canonicalized CRS (using RFC
8785
for JSON)
- [ ] SHOULD include Cache-Control: no-transform on SBR responses
7.1.2. Concurrency Control
- [ ] MUST evaluate If-Match preconditions on state-changing
operations
using strong comparison [RFC9110]
- [ ] MUST respond with 412 Precondition Failed when If-Match does
not match current SBR ETag
- [ ] SHOULD respond with 428 Precondition Required when If-Match
is missing on state-changing operations
- [ ] SHOULD return Problem Details [RFC9457] body for 412, 428,
and 400 (missing precondition) responses
7.1.3. Discovery and Linking
- [ ] SHOULD include Link: rel="state" header on Projected
Representations pointing to the SBR endpoint
- [ ] SHOULD advertise AST profile using Link: rel="profile" or
Content-Type profile parameter
- [ ] SHOULD include bidirectional rel="alternate" links between
representations
7.1.4. Prohibited Actions
- [ ] MUST NOT reuse the SBR ETag as the ETag for Projected
Representations
- [ ] MUST NOT use weak entity-tags for the SBR validator
- [ ] MUST NOT use Content-Encoding on SBR responses
7.2. Client Requirements
7.2.1. Reading State
- [ ] SHOULD use If-None-Match with SBR ETag for conditional
requests to the SBR
- [ ] SHOULD NOT use SBR ETag as If-None-Match against Projected
endpoints
7.2.2. Writing State
- [ ] MUST obtain current SBR ETag before performing state-
changing
operations
- [ ] MUST include If-Match header with SBR ETag on all state-
changing
requests to AST resources
- [ ] MUST NOT use Projected Representation ETags as If-Match
preconditions for CRS mutations
- [ ] SHOULD handle 412 responses by refetching current state and
retrying or resolving conflicts
7.2.3. Discovery
- [ ] SHOULD follow rel="state" links from Projected
Representations
to discover SBR endpoints
- [ ] SHOULD check for rel="profile" links to detect AST resources
7.3. HTTP Status Codes
AST-conforming implementations MUST use these status codes as
specified:
Code - Usage
200 OK - Successful read or write
204 No Content - Successful write with no body (when using
Content-Location pattern)
303 See Other - Redirect to SBR after successful write (optional
pattern)
304 Not Modified - Conditional request matched current ETag
400 Bad Request - Digest validation failure or missing
precondition (if 428 unavailable)
412 Precondition Failed - If-Match precondition did not match
current ETag
428 Precondition Required - If-Match missing on state-changing
operation
7.4. Required Headers
7.4.1. SBR Response Headers
- ETag: Strong validator (e.g., "sha256-ABC123...")
- Cache-Control: Should include no-transform
- Vary: Accept for single-URI negotiated deployments
- Link: rel="alternate" to Projected Representations (recommended)
7.4.2. Projected Response Headers
- ETag: Representation-specific validator (optional)
- Link: rel="state" pointing to SBR endpoint (recommended)
7.4.3. Write Request Headers
- If-Match: SBR ETag for precondition evaluation (required)
- Content-Type: Appropriate media type for request body
- Idempotency-Key: For idempotent POST/PATCH (optional)
This checklist is informative; the normative requirements remain
those
specified in the body of this document using RFC 2119 keywords.
8. Security Considerations
This profile relies on existing HTTP security mechanisms. However,
the
synchronization of multiple representations introduces specific
security
considerations.
8.1. Consistency and Race Conditions
The primary security benefit of AST is the prevention of race
conditions
(Lost Updates). By enforcing If-Match checks against the CRS, the
server ensures that an agent cannot overwrite state changes made
by
another client, even if those changes were made via a different
representation.
Applications SHOULD treat failed preconditions (412,
428) as an expected outcome in concurrent editing scenarios and
provide appropriate conflict resolution mechanisms.
8.2. Information Leakage via Divergence
If the access control policies for different representations
diverge,
there is a risk of information leakage.
* Servers MUST ensure that the authorization requirements for
accessing a structural representation (for example, JSON) are at
least as strict as those for the rendered representation (for
example,
HTML).
* Servers MUST ensure that a structural representation does not
expose sensitive data that is redacted in the rendered
representation,
unless the client is explicitly authorized to see the raw state.
If different audiences see different subsets of the CRS, the
server
SHOULD either:
* maintain separate CRS domains with separate Semantic Validators;
or
* apply view-specific filtering consistently to all
representations
exposed to that audience.
8.3. Validator Guessing
Because Semantic Validators are often derived from content (for
example,
a hash), they may be susceptible to offline guessing attacks if
the
content has low entropy.
Implementations SHOULD ensure that:
* validators have sufficient entropy; or
* validators are combined with a secret salt; or
* validators are derived from internal versioning mechanisms
rather than
directly from plaintext content,
if the content version itself is sensitive.
Validators MUST NOT be treated as authentication or authorization
tokens.
9. IANA Considerations
9.1. Link Relation Type Registration
This document requests registration of the "state" link relation
type in
the "Link Relation Types" registry maintained by IANA per
[RFC8288]:
* Relation Name: state
* Description: Refers to the State-Bearing Representation (SBR) of
the current resource for concurrency control. The target is the
authoritative CRS view and exposes the strong ETag used for If-
Match
and If-None-Match on CRS-affecting operations.
* Reference: This document (Sections 4.1 and 9.1)
* Notes: The target's media type SHOULD be suitable for machine
processing (e.g., application/json). Clients MUST use the target's
strong ETag (not the source representation's ETag) as the
validator
for CRS preconditions. The type attribute SHOULD be present on the
link to indicate the target's media type.
Rationale for Name Selection:
The name state was chosen over alternatives such as edit,
canonical,
or source because:
* edit (defined in [RFC5023]) implies write capability, which may
not
apply to all clients;
* canonical [RFC6596] identifies the preferred URI for a resource,
not specifically its concurrency-control representation;
* source suggests origin content rather than authoritative state.
The term state directly conveys that the target exposes the
resource's
authoritative state for concurrency purposes, aligning with the
"State-Bearing Representation" terminology used throughout this
specification.
Registration Process and Timing:
This registration is requested upon adoption or publication of
this
specification in the IETF stream. Per IANA registration policy,
Link
Relation Type registrations typically occur after Working Group
adoption
or RFC publication, not from unadopted Internet-Drafts.
Interim Usage:
Implementations deploying this profile prior to IANA registration
SHOULD
use the extension relation type URI:
https://datatracker.ietf.org/doc/draft-jurkovikj-httpapi-agentic-
state/rels/state
This URI-based extension relation is immediately usable without
registry
conflicts and follows [RFC8288] extensibility mechanisms. Once the
state
relation type is registered by IANA, implementations SHOULD
migrate to
the registered simple string form (rel="state").
Example using URI-based extension relation:
Link: </api/article/123>;
rel="https://datatracker.ietf.org/doc/draft-jurkovikj-
httpapi-agentic-state/rels/state"; type="application/json"
Appendix A. Implementation Status
Note to RFC Editor: Please remove this section before publication.
This section records the status of known implementations of the
AST
profile at the time of publication. Based on [RFC7942], reviewers
are
invited to report implementation experiences.
WordPress Dual-Native Implementation
Organization: Independent implementation
Description: A WordPress plugin implementing the AST profile for
content management and template synchronization.
Implementation Details:
* SBR Endpoint: Exposes WordPress posts and templates as
application/json representations at /wp-json/dual-
native/v1/posts/{id}
and /wp-json/dual-native/v1/design/templates/...
* Semantic Validators: Uses SHA-256 content hashes as strong
ETags,
formatted as "sha256-{base64}", computed from canonicalized JSON
representation of the CRS.
* Concurrency Control: Enforces If-Match preconditions on all
state-changing operations (POST, PATCH). Returns 412 Precondition
Failed on ETag mismatches and 428 Precondition Required when If-
Match
is missing.
* Projected Representations: HTML rendering at canonical WordPress
URLs with rel="state" Link headers pointing to the SBR endpoint.
* Discovery: Implements rel="state" link relations on HTML
responses and rel="alternate" on SBR responses.
* Multi-Bot Testing: Demonstrated with multiple concurrent agents.
Reported testing showed reduced monitoring bandwidth and no lost
updates in the tested concurrent-agent workload.
Maturity: Experimental implementation reported in active use.
Coverage: Implements all normative requirements of this
specification
including SBR designation, strong ETag generation, If-Match
enforcement,
412/428 error handling with Problem Details (RFC 9457), and Link
header
discovery.
Licensing: Open source
Contact: antunjurkovic@gmail.com
Appendix B. Canonicalization Test Vectors (Informative)
This appendix provides test vectors for implementers to verify
canonicalization and ETag computation.
B.1. JSON Canonicalization (RFC 8785)
Input (arbitrary formatting):
{
"status": "published",
"id": 123
}
Canonical form (JCS per RFC 8785):
{"id":123,"status":"published"}
SHA-256 (hex):
f8b47f69857655c0c84feb9427d443933d91891589f5eee6e51
Resulting ETag (base64-encoded, example):
"sha256-+LR/aYV2VcDIT+uUJ9RD2Sx8DhtEOTPZGJFYn17ublE="
The ETag value shown above is the Base64-encoded SHA-256 digest of
the
canonical JSON form.
B.2. Numeric Precision
Input:
{"value": 1.0}
Canonical form (JCS normalizes 1.0 to 1):
{"value":1}
Implementers MUST ensure their JSON canonicalization produces JCS-
compliant output before hashing.
Appendix C. Single-URI Deployment Example (Informative)
This appendix demonstrates a complete workflow using the Single-
URI deployment model, where both the Projected Representation
(HTML) and the State-Bearing Representation (JSON) are served from
the same URI via content negotiation.
Scenario: A blog article at https://example.com/article/123 serves
both HTML (for browsers) and canonical JSON (for API clients). An
agent wants to read the human-friendly HTML, extract the Semantic
Validator, and perform a safe write operation.
C.1. Reading the Projected Representation
The agent first requests the HTML Projected Representation:
GET /article/123 HTTP/1.1
Host: example.com
Accept: text/html
Server response:
HTTP/1.1 200 OK
Content-Type: text/html
ETag: "html-abc123"
Vary: Accept
Link: </article/123>; rel="state"; type="application/json"
<!DOCTYPE html>
<html>
<head><title>Understanding HTTP Caching</title></head>
<body>
<article>
<h1>Understanding HTTP Caching</h1>
<p class="meta">Status: published | Author: Jane Smith</p>
<p>HTTP caching is a fundamental optimization...</p>
</article>
</body>
</html>
The Link: </article/123>; rel="state" header indicates the SBR is
available at the same URI by requesting application/json.
C.2. Obtaining the SBR Validator
To obtain the Semantic Validator for safe writes, the agent
requests the SBR:
GET /article/123 HTTP/1.1
Host: example.com
Accept: application/json
Server response:
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "sha256-K8N9P3M2L5H7"
Vary: Accept
Link: </article/123>; rel="alternate"; type="text/html"
Link: <https://datatracker.ietf.org/doc/draft-jurkovikj-
httpapi-agentic-state/>; rel="profile"
{
"id": 123,
"title": "Understanding HTTP Caching",
"status": "published",
"author": "Jane Smith",
"body": "HTTP caching is a fundamental optimization..."
}
The SBR response uses rel="alternate" to link to the HTML
projection,
enabling bidirectional navigation. The rel="state" link is omitted
because this response is the SBR, clients already have the
authoritative
validator in the ETag header.
The agent now has the Semantic Validator "sha256-K8N9P3M2L5H7"
which represents the current Canonical Resource State.
C.3. Performing a Safe Write
The agent wants to update the article status to "draft". It sends
a conditional write using the Semantic Validator:
PATCH /article/123 HTTP/1.1
Host: example.com
Content-Type: application/merge-patch+json
If-Match: "sha256-K8N9P3M2L5H7"
{
"status": "draft"
}
Success response (303 See Other pattern):
HTTP/1.1 303 See Other
Location: /article/123
Link: </article/123>; rel="state"; type="application/json";
state-etag="\"sha256-R9T4Q8P1N7M3\""
The agent can now follow the Location header to retrieve the
updated SBR, or extract the new Semantic Validator
"sha256-R9T4Q8P1N7M3" from the state-etag parameter for subsequent
operations.
Alternative success response (204 No Content pattern):
HTTP/1.1 204 No Content
Content-Location: /article/123
Link: </article/123>; rel="state"; type="application/json";
state-etag="\"sha256-R9T4Q8P1N7M3\""
Conflict response (state changed):
If another agent modified the article between steps C.2 and C.3:
HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json
Link: </article/123>; rel="state"; type="application/json";
state-etag="\"sha256-X2Y9Z4W1V8U5\""
{
"type": "https://example.com/errors/precondition-failed",
"title": "Precondition Failed",
"status": 412,
"detail": "The article has been modified by another agent.",
"current-etag": "sha256-X2Y9Z4W1V8U5",
"provided-etag": "sha256-K8N9P3M2L5H7"
}
The agent can extract the current Semantic Validator from the
state-etag parameter and retry with the updated state.
C.4. Optional: Zero-Fetch Optimization
For monitoring scenarios, the agent can efficiently poll for
changes without fetching the full representation:
Pattern 1: HEAD request with If-None-Match
HEAD /article/123 HTTP/1.1
Host: example.com
Accept: application/json
If-None-Match: "sha256-R9T4Q8P1N7M3"
If unchanged:
HTTP/1.1 304 Not Modified
ETag: "sha256-R9T4Q8P1N7M3"
Vary: Accept
If changed:
HTTP/1.1 200 OK
ETag: "sha256-T5U8V1W4X7Y0"
Vary: Accept
Content-Type: application/json
Content-Length: 234
Pattern 2: GET request with If-None-Match
GET /article/123 HTTP/1.1
Host: example.com
Accept: application/json
If-None-Match: "sha256-R9T4Q8P1N7M3"
Server returns 304 if unchanged, or 200 with updated content if
changed.
This zero-fetch pattern minimizes bandwidth while maintaining
accurate change detection based on the Semantic Validator.
10. References
10.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March
1997.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017.
[RFC9110] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110,
June 2022.
[RFC8288] Nottingham, M., "Web Linking", RFC 8288, DOI
10.17487/RFC8288, October 2017.
[RFC6585] Nottingham, M. and R. Fielding, "Additional HTTP Status
Codes", RFC 6585, DOI 10.17487/RFC6585, April 2012.
[RFC9530] Polli, R. and L. Pardue, "Digest Fields", RFC 9530, DOI
10.17487/RFC9530, February 2024.
[RFC9457] Nottingham, M., Wilde, E., and S. Dalal, "Problem
Details for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023.
10.2. Informative References
[RFC9111] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "HTTP Caching", STD 98, RFC 9111, DOI 10.17487/RFC9111, June
2022.
[RFC6906] Wilde, E., "The 'profile' Link Relation Type", RFC 6906,
DOI 10.17487/RFC6906, March 2013.
[RFC5023] Gregorio, J., Ed., and B. de hOra, Ed., "The Atom
Publishing Protocol", RFC 5023, DOI 10.17487/RFC5023, October
2007.
[RFC5789] Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC
5789, DOI 10.17487/RFC5789, March 2010.
[RFC6596] Ohye, M. and J. Kupke, "The Canonical Link Relation",
RFC 6596, DOI 10.17487/RFC6596, April 2012.
[RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON
Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785,
June 2020.
[I-D.jurkovikj-http-semantic-validator] Jurkovikj, A., "Semantic
Validators for HTTP", Work in Progress, Internet-Draft, draft-
jurkovikj-http-semantic-validator-00, May 2026.
[RFC6902] Bryan, P., Ed. and M. Nottingham, Ed., "JavaScript
Object Notation (JSON) Patch", RFC 6902, DOI 10.17487/RFC6902,
April 2013.
[RFC7396] Hoffman, P. and J. Snell, "JSON Merge Patch", RFC 7396,
DOI 10.17487/RFC7396, October 2014.
[RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of
Running Code: The Implementation Status Section", BCP 205, RFC
7942, DOI 10.17487/RFC7942, July 2016.
[I-D.ietf-httpbis-unencoded-digest] Pardue, L. and M. West, "HTTP
Unencoded Digest", Work in Progress, Internet-Draft, draft-ietf-
httpbis-unencoded-digest-04, March 2026.
[I-D.ietf-httpapi-digest-fields-problem-types] Kleidl, M., Pardue,
L., and R. Polli, "HTTP Problem Types for Digest Fields", Work in
Progress, Internet-Draft, draft-ietf-httpapi-digest-fields-
problem-types-05, March 2026.
Author's Address
Antun Jurkovikj
Email: antunjurkovic@gmail.com