| Internet-Draft | Agentic State Transfer | July 2026 |
| Jurkovikj | Expires 28 January 2027 | [Page] |
HTTP applications frequently expose one logical object through several representations or resources. Ordinary HTTP entity tags identify selected representations; they do not, by themselves, provide a conditional-update mechanism spanning different request targets.¶
This document specifies Agentic State Transfer (AST), an HTTP profile for
preventing lost updates to shared application state. AST Core requires a
client to mutate the State-Bearing Resource using the strong ETag of its
State-Bearing Representation and the standard If-Match field. AST Semantic
uses Semantic-ETag and If-Semantic-Match when a protected mutation targets
a different resource or representation in the same concurrency domain. The
profile also defines state discovery, atomic compare-and-commit behavior,
conflict handling, deferred processing, caching constraints, and security
requirements.¶
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."¶
This Internet-Draft will expire on 28 January 2027.¶
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.¶
A single application object is often visible through several HTTP resources or representations. A content-management system might provide an HTML page, a JSON state resource, a Markdown editor, and a form handler, all backed by the same database object. Multiple human and automated clients can construct updates from different views of that object.¶
HTTP already provides optimistic concurrency control through ETag and
If-Match [RFC9110]. Those fields work when the validator was obtained from a
selected representation of the same target resource later modified by the
client. Problems arise when an application treats an ETag obtained from one
resource as though it were an If-Match condition on a different resource.
That changes the target scope of If-Match and is not standard HTTP semantics.¶
AST defines two conformant deployment modes:¶
AST Core uses only existing HTTP conditional request fields. Every protected mutation targets the State-Bearing Resource and uses the strong ETag of the State-Bearing Representation selected at that target.¶
AST Semantic uses the Semantic Validator extension
[I-D.jurkovikj-http-semantic-validator]. A protected mutation can target a
projected or otherwise different resource, provided the target positively
advertises enforcement of If-Semantic-Match for the same concurrency
domain.¶
Both modes require atomic compare-and-commit behavior. They differ only in which validator and precondition can safely cross representation or resource boundaries.¶
Consider an article exposed as HTML at /article/123 and as complete JSON state
at /api/article/123.¶
Client A reads one view and changes the article.¶
Client B constructs a different change from an older view.¶
Client B submits its change without a version-specific precondition.¶
The server applies Client B's stale update and overwrites part or all of Client A's work.¶
AST prevents this outcome by requiring a validator that identifies the state against which the mutation was constructed and by requiring the comparison and state transition to occur as one atomic operation.¶
AST specifies:¶
designation and discovery of a State-Bearing Resource and Representation;¶
AST Core use of ETag, If-Match, 412, and 428;¶
AST Semantic use of Semantic-ETag and If-Semantic-Match;¶
atomicity across all writers in one concurrency domain;¶
response behavior, conflict handling, deferred processing, and creation;¶
caching, content negotiation, integrity, and security constraints; and¶
registration of a link relation for state discovery.¶
AST does not define an application data model, patch format, merge algorithm, authentication scheme, authorization policy, database transaction mechanism, or non-HTTP binding.¶
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, as shown here.¶
The authoritative application state whose concurrent modification is protected by AST. The CRS includes every value whose change could make a mutation constructed against an earlier state unsafe.¶
The complete set of CRS values and write paths serialized by one AST precondition. A concurrency domain can be scoped by resource, tenant, principal, language, workflow, or another application boundary.¶
A selected representation that exposes the complete CRS needed to construct and reconcile protected mutations. Its ordinary strong ETag validates that selected representation.¶
The HTTP target resource from which the SBR is selected. AST Core mutations target this resource.¶
A representation derived from the CRS but not designated as the SBR. It can omit, transform, summarize, render, or otherwise project state.¶
A target resource that provides a Projected Representation or accepts an application-specific action related to the same CRS.¶
A state-changing request for which an AST profile requires a version-specific precondition.¶
An If-Match or If-Semantic-Match value containing at least one explicit
validator that identifies a state observed by the client. A wildcard-only
condition is not version-specific.¶
For each AST concurrency domain, an origin server MUST designate one canonical State-Bearing Resource. That resource selects one SBR that exposes the complete CRS needed for conflict reconciliation. Additional aliases MAY redirect to the canonical State-Bearing Resource, but clients and projected resources need one unambiguous state target.¶
A deployment can use either:¶
a dedicated State-Bearing Resource, such as /api/article/123; or¶
one URI with content negotiation, provided a request can unambiguously select the SBR for both retrieval and precondition evaluation.¶
A dedicated State-Bearing Resource is RECOMMENDED because it avoids ambiguity about representation selection on unsafe requests.¶
A TCT M-URL [I-D.jurkovikj-collab-tunnel] is a Projected Resource by default. It is an AST SBR only when the origin explicitly designates it as such, it losslessly exposes the complete CRS, and it implements all requirements of the chosen AST mode.¶
The concurrency domain MUST include all state whose change could invalidate a client's intended mutation. It also MUST include state relevant to the applicable authorization and integrity decisions. If one request atomically modifies several otherwise independent objects, the server MUST either:¶
protect a composite concurrency domain that covers all of them; or¶
use an application transaction mechanism that prevents partial or stale commits with equivalent safety.¶
Different principals or audiences MUST use separate domains when they do not observe exactly the same mutation-relevant CRS.¶
AST Core is the existing-HTTP-fields deployment mode. It does not change the
meaning of ETag or If-Match.¶
The SBR MUST have a strong ETag as defined by [RFC9110]. That ETag validates the exact selected SBR representation. It MUST change whenever the SBR representation data changes.¶
Every CRS change in the concurrency domain MUST produce SBR representation data with a different strong ETag before or atomically with publication of the changed state. The reverse is not required: serializer, schema, profile, or representation metadata changes can require a new strong ETag even when the application regards the CRS as semantically equivalent.¶
A Projected Representation MAY have its own ETag. The SBR ETag MUST NOT be reused as a Projected Representation's ETag unless the selected representation data are identical and all ordinary HTTP strong-validator requirements are satisfied.¶
A protected AST Core mutation MUST be evaluated against one unambiguously selected SBR variant.¶
The RECOMMENDED deployment is a dedicated SBR URI that serves one media type
without Content-Encoding and includes Cache-Control: no-transform. If
content negotiation is used at the State-Bearing Resource:¶
the client MUST send the request fields needed to select the SBR;¶
the server MUST evaluate If-Match against that selected SBR;¶
the same selection rules MUST apply when the validator is retrieved and when the mutation is submitted; and¶
Vary MUST list every request field used for selection.¶
An AST Core deployment MUST NOT accept an ETag of one content-coded variant as
an If-Match condition on a different selected variant. A deployment that
needs representation-independent validation across codings SHOULD implement
AST Semantic or expose a dedicated identity-coded State-Bearing Resource.¶
A protected AST Core mutation:¶
MUST target the State-Bearing Resource;¶
MUST select the SBR;¶
MUST contain If-Match with at least one explicit strong entity-tag; and¶
MUST be compared with the current selected SBR using the strong comparison function defined by [RFC9110].¶
An SBR ETag obtained from one URI MUST NOT be reinterpreted as an If-Match
condition on another target URI.¶
A client does not need to retrieve the SBR immediately before every mutation, but it MUST possess the SBR ETag for the state against which the mutation was constructed. The precondition determines whether that belief remains current.¶
A Projected Resource that does not implement AST Semantic MUST NOT accept a CRS
mutation by treating the SBR ETag as an If-Match condition on the projected
target.¶
When such a resource does not support the unsafe method, it SHOULD respond with
405 Method Not Allowed, MUST include an Allow field as required by
[RFC9110], and SHOULD include a concurrency-state link to the
State-Bearing Resource:¶
HTTP/1.1 405 Method Not Allowed Allow: GET, HEAD Link: </api/article/123>; rel="concurrency-state"; type="application/json"¶
AST Semantic extends the profile with the fields defined by [I-D.jurkovikj-http-semantic-validator]. It is intended for protected mutations whose request target is not the State-Bearing Resource or whose selected representation is not the SBR.¶
Every resource from which a client is expected to construct a semantic-mode
mutation SHOULD expose Semantic-ETag. Resources in the same concurrency
domain MUST expose an equal current semantic validator when they represent the
same mutation-relevant CRS.¶
Ordinary ETags remain representation-specific:¶
HTTP/1.1 200 OK Content-Type: text/html ETag: "html-v52" Semantic-ETag: "article-state-v7" Link: </api/article/123>; rel="concurrency-state"; type="application/json"¶
The State-Bearing Resource can expose both its ordinary ETag and the same
Semantic-ETag:¶
HTTP/1.1 200 OK Content-Type: application/json ETag: "json-v18" Semantic-ETag: "article-state-v7"¶
A protected AST Semantic mutation:¶
MUST target a resource and request method for which AST Semantic enforcement is positively advertised;¶
MUST contain If-Semantic-Match with at least one explicit semantic
validator;¶
MUST be evaluated in the concurrency domain advertised for that target; and¶
MUST satisfy the comparison, capability, and atomicity requirements of [I-D.jurkovikj-http-semantic-validator].¶
A wildcard-only If-Semantic-Match value does not satisfy AST's
version-specific precondition requirement.¶
A request MAY also contain ordinary If-Match. When it does, both the
representation precondition and semantic precondition MUST succeed.¶
Because an unaware HTTP server can ignore an extension request field, a client
MUST NOT rely on If-Semantic-Match unless it has positive knowledge,
specific to the target resource and request method, that the target enforces
AST Semantic.¶
A conforming AST Semantic deployment MUST make enforcement discoverable for
each protected target resource and mutation method. It MUST advertise AST
Semantic participation using a profile link relation or application
documentation that is equally explicit. The profile link is RECOMMENDED:¶
Link: <https://www.ietf.org/archive/id/draft-jurkovikj-httpapi-agentic-state-02.html#ast-semantic-profile>; rel="profile"¶
The profile URI above identifies this exact Internet-Draft revision. Clients MUST NOT assume that a versionless Datatracker URI or a different draft revision is equivalent. A future RFC will define stable RFC-based profile identifiers.¶
The profile link identifies AST Semantic participation but does not by
itself enumerate request methods. Method coverage MUST be defined by
resource-and-method-specific documentation or another explicit discovery
mechanism. A client MUST NOT infer enforcement for another method, resource,
or origin from one profile link.¶
AST Core can be advertised similarly:¶
Link: <https://www.ietf.org/archive/id/draft-jurkovikj-httpapi-agentic-state-02.html#ast-core-profile>; rel="profile"¶
A profile media-type parameter is not defined for application/json by this
document and MUST NOT be used as a substitute for the link relation unless the
selected media type separately defines such a parameter.¶
This section applies to both AST modes. "Required precondition" means
If-Match in AST Core and If-Semantic-Match in AST Semantic.¶
For a protected mutation of an existing resource, the server MUST NOT apply the request unless it contains the required version-specific precondition.¶
After authentication, authorization, request syntax, media-type, and other normal validation checks:¶
an absent required precondition MUST produce 428 Precondition Required
[RFC6585];¶
a wildcard-only value, or a value containing no explicit validator suitable
for the selected AST mode, MUST also produce 428; and¶
a syntactically valid version-specific condition that does not match MUST
produce 412 Precondition Failed.¶
The 400 Bad Request fallback formerly permitted by this profile is not
conformant. A 428 response SHOULD use Problem Details [RFC9457] and explain
which field is required.¶
After normal request validation, evaluation of the required validator, application of the state transition, and publication of the resulting validator MUST occur atomically with respect to every operation capable of changing the same concurrency domain.¶
This requirement applies to HTTP handlers, background workers, migrations, administrator interfaces, message consumers, scheduled jobs, and other write paths. Two concurrent requests MUST NOT both compare successfully against the same old validator and then both commit conflicting transitions.¶
The server MAY implement this requirement with a database compare-and-swap, transactional version column, serializable transaction, lock, version vector, or another mechanism with equivalent behavior.¶
In AST Core, a successful response can carry the new ordinary ETag only when that ETag correctly describes the selected representation of the target resource under [RFC9110]. Typical patterns are:¶
HTTP/1.1 204 No Content ETag: "json-v19"¶
or:¶
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "json-v19"
{"id":123,"status":"draft"}
¶
For PUT, a server MUST follow the RFC 9110 restriction on sending validators
when the received representation was transformed before storage. If a valid
new ETag cannot be returned, the client retrieves it with a subsequent GET or
HEAD.¶
In AST Semantic, a successful state-changing response SHOULD include the new
Semantic-ETag when a current state remains and the principal is authorized to
observe it:¶
HTTP/1.1 204 No Content Semantic-ETag: "article-state-v8" Link: </api/article/123>; rel="concurrency-state"; type="application/json"¶
If the response contains a Projected Representation, its ordinary ETag MUST
validate that projection, while Semantic-ETag carries the semantic validator.¶
A server MAY use 303 See Other to direct the client to retrieve the current
SBR. Content-Location does not rebind an ordinary ETag to another
resource, and AST does not define a state-etag Link parameter.¶
A 412 Precondition Failed response SHOULD identify the State-Bearing Resource
using rel="concurrency-state". Subject to authorization and disclosure
policy:¶
AST Core MAY include the current SBR ETag when it correctly identifies the
current selected representation of the target; and¶
AST Semantic SHOULD include the current Semantic-ETag.¶
HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json
Semantic-ETag: "article-state-v9"
Link: </api/article/123>; rel="concurrency-state"; type="application/json"
{
"type": "https://example.com/problems/precondition-failed",
"title": "Precondition failed",
"status": 412,
"detail": "The resource changed after the client constructed its update."
}
¶
A validator returned with 412 is advisory and can become stale immediately.
A client MUST NOT retry solely by replacing its supplied validator with that
value. It MUST first retrieve or otherwise validate the current state and
reconcile its intended mutation, unless the operation specification explicitly
guarantees that blind retry is safe.¶
After 412, a client can:¶
retrieve the current SBR and reapply its intent;¶
perform a three-way merge when application semantics make that safe;¶
request human or policy-engine intervention; or¶
abandon the mutation.¶
AST does not define merge semantics. A server MAY include authorized conflict context in a Problem Details response, but clients MUST treat it as untrusted and potentially stale.¶
A precondition checked only when 202 Accepted is emitted does not protect a
state transition committed later. A server performing deferred processing
MUST do at least one of the following:¶
commit the CRS transition before returning 202, deferring only external
side effects;¶
reserve or fence the matched version until commit; or¶
re-evaluate the expected validator atomically when the deferred transition commits.¶
A commit-time mismatch MUST prevent the CRS mutation. The operation's status
resource or equivalent completion channel MUST report a failed-precondition
outcome. The original 202 response cannot be retrospectively changed to
412.¶
The version-specific precondition requirement applies to mutations of existing concurrency domains. Common creation patterns include:¶
POST to a collection resource, with the new resource URI and initial
validator returned on success; and¶
PUT with If-None-Match: * to create a resource only when no current
representation exists at the target URI.¶
Once created, later protected mutations use AST Core or AST Semantic as advertised. AST does not define an idempotency-key field or replay store; applications can use a separately specified idempotency mechanism.¶
The State-Bearing Resource MUST support GET. It SHOULD support HEAD when
the implementation can provide metadata consistent with the corresponding
GET.¶
AST Core clients use ordinary If-None-Match against the State-Bearing
Resource. A server returns 304 Not Modified only when the standard HTTP
precondition evaluates as specified by [RFC9110]. When the corresponding
200 response would contain ETag, the 304 response MUST contain the same
current ETag as required by HTTP.¶
GET /api/article/123 HTTP/1.1 Accept: application/json If-None-Match: "json-v18" HTTP/1.1 304 Not Modified ETag: "json-v18"¶
Semantic equivalence alone never authorizes a 304; AST Semantic does not
change cache revalidation semantics.¶
Projected Representations use normal HTTP cache validators. A projection's
ETag MUST NOT be sent as If-Match to the State-Bearing Resource unless it is
also, under ordinary HTTP semantics, a current validator of the selected SBR.¶
AST Semantic projections can expose Semantic-ETag for logical-state
observation, but caches continue to use ordinary ETags and standard freshness
rules.¶
A response MUST include Vary for every request field used to select its
representation, including Accept, Accept-Language, or Accept-Encoding as
applicable [RFC9111]. AST does not create a new cache key and does not waive
ordinary content-negotiation requirements.¶
Range requests do not change validator scope. An origin MAY decline range
support for operational reasons, but AST does not require Accept-Ranges:
none merely because an SBR is JSON.¶
AST Semantic validator construction follows [I-D.jurkovikj-http-semantic-validator]. It is independent of the selected representation's bytes and can therefore remain equal across media types or content codings when they belong to the same concurrency domain.¶
Storing a validator beside the CRS is permitted, but the storage update alone does not establish conformance. The compare, transition, and validator publication MUST be one atomic operation as described above.¶
concurrency-state Link Relation
A Projected Resource SHOULD include a concurrency-state link to the
canonical State-Bearing Resource:¶
Link: </api/article/123>; rel="concurrency-state"; type="application/json"¶
The link target identifies the resource from which a client can retrieve the
complete state needed to understand and reconcile protected mutations. The
link itself does not transfer a validator and does not change the target scope
of If-Match.¶
The type target attribute SHOULD identify the expected SBR media type. A
client MUST still process the target's actual response according to HTTP and
MUST obtain its ordinary ETag from the target in AST Core.¶
Clients SHOULD follow concurrency-state links automatically only when the
target is same-origin. Following a cross-origin concurrency-state link
requires explicit client policy covering trust, redirects, DNS rebinding,
private-network destinations, TLS identity, and credential handling.¶
A client MUST NOT automatically forward Authorization, cookies, client
certificates, or other ambient credentials to a newly discovered authority
solely because it appears in a concurrency-state link.¶
The registered alternate relation MAY be used for navigation among other
representations. An alternate link does not imply AST participation or
concurrency semantics.¶
ETags and semantic validators are not content-integrity or authentication mechanisms. When payload integrity is required, a sender can use Digest Fields [RFC9530]. When message authentication is required, an application can use an appropriate authentication or signature mechanism.¶
Request digest validation is independent of AST precondition evaluation. A server performs authentication, authorization, request syntax and digest validation, and other normal checks before the atomic AST compare-and-commit step.¶
A server MAY implement AST for only part of an API. Clients MUST NOT infer AST support for one resource from support on another resource at the same origin.¶
A client that cannot establish AST Core or AST Semantic support MUST NOT assume that a mutation is protected. It can use application documentation, decline the mutation, or use another application-specific safety mechanism.¶
An ordinary ETag from one target resource cannot be treated as an If-Match
condition on another. AST Semantic permits cross-resource validation only
through an explicitly advertised semantic equivalence domain and
If-Semantic-Match.¶
Cross-origin discovery can create SSRF, credential-forwarding, redirect, and trust-boundary risks. Same-origin discovery is the default; clients need an explicit cross-origin policy.¶
Failure to serialize every writer in a concurrency domain defeats AST's lost- update guarantee. Operators MUST audit non-HTTP write paths and distributed components, not only the public request handler.¶
Validators can reveal update frequency, correlate views, or expose internal revision identifiers. Servers SHOULD use opaque or privacy-preserving construction and separate domains when correlation is sensitive. Validators MUST NOT be treated as authorization tokens.¶
A new validator does not prove that a stale operation remains semantically
valid. Clients that blindly retry after 412 can overwrite intervening
changes despite using a current validator. The mandatory reconciliation rule
reduces this risk.¶
Intermediaries can transform, compress, strip, or rewrite representation
metadata. AST Core deployments SHOULD use a dedicated identity-coded SBR with
Cache-Control: no-transform. AST Semantic separates representation ETags
from semantic state, but clients still require end-to-end assurance that the
origin enforces the semantic precondition.¶
IANA is requested to register the following relation in the "Link Relation Types" registry established by [RFC8288].¶
Relation Name: concurrency-state¶
Description: Refers to the resource that provides the complete authoritative state used to understand and reconcile conditional updates to the context resource.¶
Reference: this document¶
Notes: The target can expose an ordinary ETag for AST Core and a
Semantic-ETag for AST Semantic. The relation does not change the scope or
meaning of If-Match.¶
Before registration, an implementation that needs an extension relation type SHOULD use a URI under a namespace it controls. A mutable Datatracker document URL is not a permanent extension-relation namespace.¶
An AST Core server:¶
MUST designate one canonical State-Bearing Resource per concurrency domain;¶
MUST expose a strong ETag for the selected SBR;¶
MUST require a version-specific If-Match on every protected mutation;¶
MUST ensure that the mutation targets and selects the SBR;¶
MUST return 428 when the required version-specific condition is absent and
412 when it is false;¶
MUST atomically compare, transition, and publish the new validator; and¶
MUST NOT reinterpret an SBR ETag as an If-Match condition on another target
resource.¶
An AST Semantic server additionally:¶
MUST implement [I-D.jurkovikj-http-semantic-validator];¶
MUST positively advertise enforcement for each protected target and mutation method;¶
MUST require a version-specific If-Semantic-Match for cross-representation
or cross-resource protected mutations;¶
MUST use one complete concurrency domain for equal semantic validators; and¶
SHOULD return the resulting Semantic-ETag after a successful transition.¶
An AST client:¶
MUST possess the validator for the state against which its mutation was constructed;¶
MUST use If-Match only at the SBR target in AST Core;¶
MUST use If-Semantic-Match only after positive capability discovery in AST
Semantic;¶
MUST NOT use wildcard-only conditions as AST version evidence; and¶
MUST reconcile state after 412 rather than blindly substituting a returned
validator.¶
-01
This revision:¶
separates AST Core and AST Semantic conformance modes;¶
restricts AST Core If-Match to the selected SBR at the request target;¶
integrates Semantic-ETag and If-Semantic-Match for cross-resource writes;¶
requires resource-and-method-specific capability signaling for semantic preconditions;¶
requires 428 rather than a 400 fallback;¶
rejects wildcard-only conditions as AST version evidence;¶
requires atomic compare-and-commit across every writer;¶
corrects deferred 202 processing;¶
removes the state-etag Link parameter and the 204 plus
Content-Location ETag pattern;¶
names the state-discovery relation concurrency-state;¶
prohibits blind retry based only on a validator returned with 412;¶
distinguishes semantic validators from ordinary cache validators and digest fields;¶
makes same-origin concurrency-state discovery the default; and¶
clarifies that a TCT M-URL is a projection unless explicitly designated as a complete AST SBR.¶
GET /api/article/123 HTTP/1.1
Host: example.com
Accept: application/json
Accept-Encoding: identity
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "json-v18"
Cache-Control: no-cache, no-transform
Link: <https://www.ietf.org/archive/id/draft-jurkovikj-httpapi-agentic-state-02.html#ast-core-profile>; rel="profile"
{"id":123,"status":"published","title":"Example"}
¶
PATCH /api/article/123 HTTP/1.1
Host: example.com
Accept: application/json
Accept-Encoding: identity
Content-Type: application/merge-patch+json
If-Match: "json-v18"
{"status":"draft"}
¶
HTTP/1.1 204 No Content ETag: "json-v19"¶
PATCH /article/123 HTTP/1.1
Host: example.com
If-Match: "json-v18"
Content-Type: application/merge-patch+json
{"status":"draft"}
¶
HTTP/1.1 405 Method Not Allowed Allow: GET, HEAD Link: </api/article/123>; rel="concurrency-state"; type="application/json"¶
GET /article/123 HTTP/1.1 Host: example.com Accept: text/html HTTP/1.1 200 OK Content-Type: text/html ETag: "html-v52" Semantic-ETag: "article-state-v7" Link: </api/article/123>; rel="concurrency-state"; type="application/json" Link: <https://www.ietf.org/archive/id/draft-jurkovikj-httpapi-agentic-state-02.html#ast-semantic-profile>; rel="profile"¶
PATCH /article/123 HTTP/1.1
Host: example.com
Content-Type: application/merge-patch+json
If-Semantic-Match: "article-state-v7"
{"status":"draft"}
¶
HTTP/1.1 204 No Content Semantic-ETag: "article-state-v8" Link: </api/article/123>; rel="concurrency-state"; type="application/json"¶
HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json
Semantic-ETag: "article-state-v9"
Link: </api/article/123>; rel="concurrency-state"; type="application/json"
{
"type": "https://example.com/problems/precondition-failed",
"title": "Precondition failed",
"status": 412,
"detail": "Retrieve the current state and reconcile the intended change."
}
¶
A single URI can serve both HTML and the SBR by content negotiation, but the protected mutation must unambiguously select the same SBR variant:¶
GET /article/123 HTTP/1.1 Host: example.com Accept: application/json Accept-Encoding: identity HTTP/1.1 200 OK Content-Type: application/json ETag: "json-v18" Vary: Accept¶
PATCH /article/123 HTTP/1.1
Host: example.com
Accept: application/json
Accept-Encoding: identity
Content-Type: application/merge-patch+json
If-Match: "json-v18"
{"status":"draft"}
¶
If the server cannot unambiguously select the SBR for the unsafe request, it
MUST NOT apply AST Core If-Match semantics to that request. A dedicated SBR
URI is therefore preferred.¶
For deployments that choose JCS and SHA-256 for the SBR representation:¶
Input JSON:¶
{
"status": "published",
"id": 123
}
¶
JCS form:¶
{"id":123,"status":"published"}
¶
SHA-256 hexadecimal:¶
f8b47f69857655c0c84feb9427d443d92c7c0e1b443933d91891589f5eee6e51¶
Base64-encoded digest example:¶
+LR/aYV2VcDIT+uUJ9RD2Sx8DhtEOTPZGJFYn17ublE=¶