<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-ietf-rpp-core-00" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true" tocDepth="4">

<front>
<title abbrev="RESTful Provisioning Protocol">RESTful Provisioning Protocol (RPP)</title><seriesInfo value="draft-ietf-rpp-core-00" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="M." surname="Wullink" fullname="Maarten Wullink"><organization>SIDN Labs</organization><address><postal><street></street>
</postal><email>maarten.wullink@sidn.nl</email>
<uri>https://sidn.nl/</uri>
</address></author><author initials="P." surname="Kowalik" fullname="Pawel Kowalik"><organization>DENIC</organization><address><postal><street></street>
</postal><email>pawel.kowalik@denic.de</email>
<uri>https://denic.de/</uri>
</address></author><date year="2026" month="July" day="6"></date>
<area>Internet</area>
<workgroup>Network Working Group</workgroup>

<abstract>
<t>This document describes the endpoints for the RESTful Provisioning Protocol, used for the provisioning and management of objects in a shared database.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>This document describes an Application Programming Interface (API) API based on the HTTP protocol <xref target="RFC2616"></xref> and the principles of <xref target="REST"></xref>. Conforming to the REST constraints is generally referred to as being &quot;RESTful&quot;. Hence the API is dubbed: &quot;'RESTful Provisioning Protocol&quot; or &quot;RPP&quot; for short.</t>
<t>The RPP API is designed to be used for the provisioning and management of objects in a shared database, such as domain names, hosts, and entities.</t>
</section>

<section anchor="terminology"><name>Terminology</name>
<t>In this document the following terminology is used.</t>
<t>REST - Representational State Transfer (<xref target="REST"></xref>). An architectural style.</t>
<t>RESTful - A RESTful web service is a web service or API implemented using HTTP and the principles of <xref target="REST"></xref>.</t>
<t>RESTful Provisioning Protocol or RPP - The protocol described in this document.</t>
<t>URL - A Uniform Resource Locator as defined in <xref target="RFC3986"></xref>.</t>
<t>Resource - An object having a type, data, and possible relationship to other resources, identified by a URL.</t>
<t>RPP client - An HTTP user agent performing an RPP request</t>
<t>RPP server - An HTTP server responsible for processing requests and returning results in any supported media type.</t>
<t>JWT - JSON Web Token as defined in <xref target="RFC7519"></xref>.</t>
</section>

<section anchor="conventions-used-in-this-document"><name>Conventions Used in This Document</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;,&quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in <xref target="RFC2119"></xref>.</t>
<t>In examples, indentation and white space in examples are provided only to illustrate element relationships and are not REQUIRED features of the protocol.</t>
<t>All example requests assume a RPP server using HTTP version 2 is listening on the standard HTTPS port on host rpp.example. An authorization token has been provided by an out of band process and MUST be used by the client to authenticate each request.</t>
</section>

<section anchor="mapping-to-epp"><name>Mapping to EPP</name>
<t>RPP is designed as an independent protocol and does not require an EPP server. RPP concepts such as transaction identifiers, result codes, and object attributes are defined in their own right and serve RPP purposes regardless of whether an EPP backend is present, however compatibility with EPP is to the great extent preserved. Implementers with no prior EPP experience are be able to implement RPP based solely on this specification.</t>
<t>Some RPP concepts are functionally similar to EPP concepts, but they are not directly derived from EPP and MAY have different semantics. To avoid confusion, RPP elements SHOULD NOT use an &quot;EPP&quot; prefix or suffix. For implementers who operate an EPP backend and need to bridge RPP requests to EPP commands, a separate RPP-to-EPP mapping document [TODO REF] is provided. Any extensions to RPP are not covered by that mapping document; the mapping of extension elements MUST be defined in the respective extension specification.</t>
</section>

<section anchor="request-headers"><name>Request Headers</name>
<t>A RPP request does not always require a request message body. The information conveyed by the HTTP method, URL, and request headers may be sufficient for the server to be able to successfully processes a request. However, the client MUST include a request message body when the server requires additional attributes to be present in the request message. The RPP HTTP headers listed below use the &quot;RPP-&quot; prefix, following the recommendations in <xref target="RFC6648"></xref>.</t>

<ul spacing="compact">
<li><tt>RPP-Cltrid</tt>:  A client-assigned transaction identifier. The client MUST include this header in every request. It serves two independent purposes: as an idempotency key, allowing the server to detect and safely handle duplicate requests, and as an audit-trail identifier, enabling end-to-end correlation of a request across client and server logs. The value MUST be unique per request.</li>
<li><t><tt>RPP-Authorization</tt>: The client MAY use this header to send authorization information in the format <tt>&lt;method&gt; &lt;authorization information&gt;</tt>, similar to the HTTP <tt>Authorization</tt> header, defined in [RFC9110, Section 11.6.2]. The <tt>&lt;method&gt;</tt> indicates the type of authorization being used. For EPP object authorization information, for example the authorization information used for domain names described in [RFC5731, Section 2.3], a new <tt>authinfo</tt> method is defined and MUST be used. The <tt>&lt;authorization information&gt;</tt> defines the following comma separated fields:</t>

<ul spacing="compact">
<li>value (REQUIRED): Base64 encoded EPP password-based authorization information. Base64 encoding is used to prevent problems when special characters are present that may conflict with the format rules for the Authorization header.</li>
<li>roid (OPTIONAL): A Roid as defined in <xref target="RFC5731"></xref>, <xref target="RFC5733"></xref>, and <xref target="RFC5730"></xref>. The roid is used to identify the object for which the authorization information is provided. If the roid is not provided, then the server MUST assume that the authorization information is linked to the object identified by the URL of the request.</li>
</ul></li>
</ul>
<t>Use of the RPP-Authorization header:</t>

<sourcecode type="http"><![CDATA[RPP-Authorization: authinfo value=TXkgU2VjcmFRva2Vu, roid=REG-X-123
]]>
</sourcecode>
<t>The value of the <tt>RPP-Authorization</tt> header is case sensitive. The server MUST reject requests where the case of the header value does not match the expected case.
The <tt>RPP-Authorization</tt> header is specific to the user agent and MUST NOT be cached, as recommended by <xref target="RFC9110" sectionFormat="bare" section="Section 16.4.2"></xref>, the server MUST use the correct HTTP cache directives to prevent caching of the <tt>RPP-Authorization</tt> header.</t>

<ul spacing="compact">
<li><tt>RPP-Profile</tt>: The client MUST use this header to indicate the profiles is used in the request.</li>
</ul>
</section>

<section anchor="response-headers"><name>Response Headers</name>
<t>The server HTTP response contains a status code, headers, and MAY contain an RPP response message in the message body. HTTP headers are used to transmit additional data to the client and MAY be used to send RPP process related data to the client. HTTP headers used by RPP MUST use the &quot;RPP-&quot; prefix, the following response headers have been defined for RPP.</t>

<ul>
<li><t><tt>RPP-Svtrid</tt>:  A server-assigned transaction identifier. The server MUST include this header in every response. It provides a unique, server-side audit-trail reference for the processed request.</t>
</li>
<li><t><tt>RPP-Cltrid</tt>: The server MUST echo the client transaction identifier from the request back to the client in this response header. This allows the client to correlate responses to their originating requests.</t>
</li>
<li><t><tt>RPP-Code</tt>: This header is the equivalent of the EPP result code defined in <xref target="RFC5730"></xref> and MUST be used accordingly. This header MUST be added to all responses and MAY be used by the client for easy access to the result code, without having to parse the HTTP response message body.</t>
</li>
</ul>
<t>For the EPP codes related to session management (1500, 2500, 2501 and 2502) there are no corresponding RPP codes.</t>
<t>In order for RPP to be backwards compatible with EPP, RPP will use 5-digit coding of the result codes, where first digit will denote origin specification of the result codes.</t>
<t>For <xref target="RFC5730"></xref> Result Codes the leading digit MUST be &quot;0&quot;.
For RPP result codes the leading digit MUST be &quot;1&quot;. For avoidance of confusion RPP MUST not define new codes with the same semantic meaning as already defined in EPP.</t>
<t>For RPP codes the remaining 4 digits MUST keep the same semantics as <xref target="RFC5730"></xref> Result Codes.</t>

<ul spacing="compact">
<li><tt>RPP-Queue-Size</tt>: Return the number of unacknowledged messages in the client message queue. The server MAY include this header in all RPP responses.</li>
</ul>
<t>When a uniform interface operation implicitly creates a process object as a side effect, the server MUST communicate the URL of the created process resource using the <tt>Link</tt> response header <xref target="RFC8288"></xref> with the <tt>rpp-process</tt> relation type. If multiple process objects are created, the server MUST include one <tt>Link</tt> header field per created process resource, each with <tt>rel=&quot;rpp-process&quot;</tt>.</t>
<t>Example:</t>

<artwork><![CDATA[Link: <https://rpp.example/rpp/v1/domainNames/foo.example/processes/createProcesses/latest>; rel="rpp-process" process="createProcess"; processId="XYZ-12345";
]]>
</artwork>
</section>

<section anchor="error-handling-and-relation-between-http-status-codes-and-rpp-codes"><name>Error handling and relation between HTTP status codes and RPP codes</name>
<t>RPP leverages standard HTTP status codes to reflect the outcome of RPP operations. The RPP result codes are based on the EPP result codes defined in <xref target="RFC5730"></xref>. This allows clients to handle responses generically using common HTTP patterns. While the HTTP status code provides the primary, high-level outcome, the specific RPP result code MUST still be provided in the <tt>RPP-Code</tt> HTTP header for detailed diagnostics.</t>
<t>The mapping strategy is to use the most specific HTTP code that accurately reflects the operation's result.</t>
<t>For common and well-defined outcomes, a specific HTTP status code is used. For example, an attempt to access a non-existent resource (EPP code 2302) MUST return 404 Not Found, and an attempt to create a resource that already exists (EPP code 2303) MUST return 409 Conflict. This allows a client to handle these common situations based on the HTTP code alone.</t>
<t>For all other failures, a generic HTTP status code is used. Client-side errors (e.g., syntax, parameter, or policy violations) MUST return 400 Bad Request. Server-side failures MUST return 500 Internal Server Error.</t>
<t>The server MUST return HTTP status codes, following the mapping rules in Table 1.</t>
<t>Table 1: RPP result code and HTTP Status-Code mapping.</t>
<table>
<thead>
<tr>
<th>HTTP Status-Code</th>
<th>Description</th>
<th>Corresponding RPP result code(s)</th>
</tr>
</thead>

<tbody>
<tr>
<td>Success (2xx)</td>
<td></td>
<td></td>
</tr>

<tr>
<td>200 OK</td>
<td>The request was successful (e.g., for GET or UPDATE).</td>
<td>01000 (in all cases not specified otherwise), 01300, 01301</td>
</tr>

<tr>
<td>201 Created</td>
<td>The resource was created successfully.</td>
<td>01000 for resource creating requests (POST/PUT)</td>
</tr>

<tr>
<td>202 Accepted</td>
<td>The request was accepted for asynchronous processing.</td>
<td>01001</td>
</tr>

<tr>
<td>204 No Content</td>
<td>The resource was deleted successfully.</td>
<td>01000 for DELETE</td>
</tr>

<tr>
<td>Client Errors (4xx)</td>
<td></td>
<td></td>
</tr>

<tr>
<td>400 Bad Request</td>
<td>Generic client-side error (syntax, parameters, policy).</td>
<td>02000-02005, 02104-02106, 02300-02301, 02304-02308</td>
</tr>

<tr>
<td>403 Forbidden</td>
<td>Authentication or authorization failed.</td>
<td>02200-02202</td>
</tr>

<tr>
<td>404 Not Found</td>
<td>The requested resource does not exist.</td>
<td>02303</td>
</tr>

<tr>
<td>409 Conflict</td>
<td>The resource could not be created because it already exists.</td>
<td>02302</td>
</tr>

<tr>
<td>Server Errors (5xx)</td>
<td></td>
<td></td>
</tr>

<tr>
<td>500 Internal Server Error</td>
<td>Generic server-side error; command failed.</td>
<td>02400</td>
</tr>

<tr>
<td>501 Not Implemented</td>
<td>The requested command or feature is not implemented.</td>
<td>02100-02103</td>
</tr>
</tbody>
</table><t>Some EPP result codes, like 01500, 02500, 02501 and 02502 are related to session management and therefore not applicable to a sessionless RPP protocol.</t>
</section>

<section anchor="problem-detail-responses-for-errors"><name>Problem Detail responses for errors</name>
<t>When an error occurs that prevents processing of the requested action, an RPP server MUST respond using a Problem Detail
document <xref target="RFC9457"></xref> detailing what went wrong, or what was not acceptable to the server.
The <tt>type</tt> field MUST be the <tt>urn:ietf:params:rpp:problem</tt> URN.
The <tt>status</tt> field MUST reflect the HTTP status code.
The document MUST contain an <tt>errors</tt> element, as a list of objects detailing individual errors.</t>
<t>This document consists of the following fields:</t>

<dl spacing="compact">
<dt><tt>type</tt></dt>
<dd>(required, string) This field MUST always contain the fixed string value <tt>urn:ietf:params:rpp:error</tt> to indicate that this is an RPP Problem Detail response.</dd>
<dt><tt>title</tt></dt>
<dd>(required, string) A short human-readable description of the Problem Detail type.</dd>
<dt><tt>errors</tt></dt>
<dd>(optional, array of error objects) MUST contain objects detailing information about the specific errors that occurred, including optional references to which values in the original request were not acceptable to the server.</dd>
</dl>
<t>The <tt>error</tt> object consist of the following fields:</t>

<dl spacing="compact">
<dt><tt>type</tt></dt>
<dd>(required, string) This field SHOULD be a URI that identifies the error type. This URI MAY be dereferenceable to obtain human-readable documentation about the error type.</dd>
<dt><tt>result</tt></dt>
<dd>(required, string) This field MUST contain the RPP result code associated with the error.</dd>
<dt><tt>paths</tt></dt>
<dd>(optional, list of strings) The JSONPath <xref target="RFC9535"></xref> to the value(s) in the request that caused the error. This field MAY be omitted if no specific value in the request can be identified as the cause of the error.</dd>
<dt><tt>reason</tt></dt>
<dd>(required, string) A human-readable detailed description of the error.</dd>
</dl>
<t>RPP specifications and/or extensions MAY add extension fields to the error object, to convey additional information about the causes of the error. For example, to indicate the account balance on a billing failure, the following Problem Detail response could be used:</t>

<sourcecode type="json"><![CDATA[{
  "type": "urn:ietf:params:rpp:error",
  "title": "RPP Error",
  "errors": [{
    "type": "https://rpp.example/problems/billing/billing-failure",
    "result": "02104",
    "reason": "Not enough balance on account to create domain",
    "balance": 10.0,
    "action_cost": 25.0
  }]
}
]]>
</sourcecode>
<t>Problem Detail response containing multiple errors for a domain create request using an invalid domain name (_$.example), JSONPaths are specified in the error objects to indicate which value in the request caused the error:</t>

<sourcecode type="json"><![CDATA[{
  "type": "urn:ietf:params:rpp:error",
  "title": "RPP Error",
  "errors": [{
    "type": "https://rpp.example/problems/domains/domain-syntax",
    "result": "02005",
    "paths": ["$.domain.name"],
    "reason": "Invalid character(s) in domain name",
  },
  {
    "type": "https://rpp.example/problems/domains/domain-allowed-length",
    "result": "02004",
    "paths": ["$.domain.name"],
    "reason": "Domain name length must be between 3 and 63 characters",
  }]
}
]]>
</sourcecode>
</section>

<section anchor="bootstrapping"><name>Bootstrapping</name>
<t>The server MUST provide a mechanism for clients to discover the location of the RPP server, two methods are defined for this purpose, using the IANA registry for RPP servers or using DNS-based bootstrapping. The server MUST provide at least one of these methods, and MAY provide both methods. The client MUST use either the IANA registry for RPP servers or a DNS lookup using an HTTPS resource record as defined in <xref target="RFC9460"></xref>. The client MUST be able to handle the case where the choosen method does not return a valid RPP server location, and MUST be able to use the other method as a fallback to discover the RPP server location.</t>
<t>The format and procedure for adding an RPP server to the IANA registry is defined in the IANA Considerations section below. If the server uses both the IANA registry and DNS-based bootstrapping, then both methods MUST return the same location for the RPP server.</t>
<t>For DNS-based bootstrapping, an RPP server MUST publish an HTTPS resource record in a <tt>_rpp</tt> child zone for each DNS zone that is managed by the RPP server. The owner name of the HTTPS resource record MUST be the managed zone name itself, prepended with the <tt>_rpp.</tt> label (e.g., <tt>_rpp.&lt;zone&gt;</tt>).</t>
<t>If multiple HTTPS resource records are returned, the client MUST process them according to the priority rules defined in <xref target="RFC9460"></xref>. If multiple records have the same SvcPriority, the client SHOULD select one based on local policy.</t>
<t>The client MUST construct the URL for the well-known endpoint of the RPP server as follows, using the <tt>TargetName</tt> and <tt>port</tt> SvcParams from the HTTPS resource record:</t>

<ul spacing="compact">
<li><tt>https://&lt;TargetName&gt;:&lt;port&gt;/.well-known/rpp.json</tt> when the <tt>port</tt> SvcParam is present and not 443</li>
<li><tt>https://&lt;TargetName&gt;/.well-known/rpp.json</tt> when the <tt>port</tt> SvcParam is absent or is 443</li>
</ul>
<t>Example HTTPS resource record for an RPP server for the TLD &quot;example&quot; running HTTPS on port 443 at <tt>rpp.example.</tt>:</t>

<sourcecode type="dns"><![CDATA[@ORIGIN example.
_rpp IN HTTPS 1 . alpn=h2,h3
]]>
</sourcecode>
<t>In this example, the well-known endpoint URL is <tt>https://rpp.example/.well-known/rpp.json</tt>.</t>
<t>Example HTTPS resource record for an RPP server using a different TargetName (rpp-svr2.registry.example) and a non-standard port (8443) for the TLD &quot;example&quot;:</t>

<sourcecode type="dns"><![CDATA[@ORIGIN example.
_rpp IN HTTPS 1 rpp-svr2.registry.example. alpn=h2,h3 port=8443
]]>
</sourcecode>
<t>In this example, the well-known endpoint URL is <tt>https://rpp-svr2.registry.example:8443/.well-known/rpp.json</tt>.</t>
</section>

<section anchor="discoverability"><name>Discoverability</name>
<t>RPP server capabilities MUST be discoverable by clients. The server MUST provide a well-known endpoint at <tt>/.well-known/rpp.json</tt> at the root of the RPP server, this endpoint MUST return a JSON document containing the capabilities of the RPP server. The well-known endpoint MUST be accessible without authentication, and the client MUST be able to access this endpoint before authenticating with the server. The well-known endpoint MUST be accessible using the HTTP GET method and MUST return an HTTP status code 200 (OK) if the request was successful. The response message body MUST contain a JSON document describing the capabilities of the RPP server using the following fields:</t>

<ul spacing="compact">
<li><tt>base_url</tt>: (required, string) The base URL for the RPP API, this is the URL that MUST be used as the base for all endpoint URL templates.</li>
<li><tt>version</tt>: (required, string) The version of the RPP API supported by the server, for example &quot;1.0&quot;.</li>
<li><tt>tlds</tt>: (required, array of strings) A list of TLDs supported by the server, for example &quot;example&quot;, &quot;org&quot;.</li>
<li><t><tt>extensions</tt>: (optional, array of extension objects) A list of supported extensions, each extension object MUST contain the following fields:</t>

<ul spacing="compact">
<li><tt>name</tt>: (required, string) A short name for the extension, for example &quot;registry fee extension&quot;.</li>
<li><tt>id</tt>: (required, string) A unique URN identifier for the extension, for example &quot;urn:ietf:params:rpp:extension:registry-fee&quot;.</li>
<li><tt>version</tt>: (required, string) The version of the extension supported by the server, for example &quot;1.0&quot;.</li>
<li><tt>url</tt>: (required, string) for standard extensions, this MUST be the URL for the extension in the IANA registry, for private extensions, this MUST be the URL for the extension specification, the domain name used in the URL MUST resolve and the URL MUST be accessible to the client.</li>
</ul></li>
<li><t><tt>profiles</tt>: (optional, array of profile objects) A list of supported profiles, each profile object MUST contain the following fields:</t>

<ul spacing="compact">
<li><tt>name</tt>: (required, string) A short name for the profile, for example &quot;domain provisioning profile&quot;.</li>
<li><tt>id</tt>: (required, string) A unique URN identifier for the profile, for example &quot;urn:ietf:params:rpp:profile:domain-provisioning-1.0&quot;.</li>
<li><tt>version</tt>: (required, string) The version of the profile supported by the server, for example &quot;1.0&quot;.</li>
<li><tt>url</tt>: (required, string) for standard profiles, this MUST be the URL for the profile in the IANA registry, for private profiles, this MUST be the URL for the profile specification, the domain name used in the URL MUST resolve and the URL MUST be accessible to the client.</li>
</ul></li>
<li><tt>objects</tt>: (required, array)  A list of supported resource collections, for example &quot;domains&quot;, &quot;hosts&quot;, &quot;entities&quot;.</li>
<li><tt>authentication</tt>: (optional, array of strings) A list of supported authentication methods, for example &quot;Bearer&quot;, &quot;Basic&quot;.<br />
</li>
<li><t><tt>endpoints</tt>: (required, array of endpoint objects) A list of available endpoints, each endpoint object MUST contain the following fields:</t>

<ul spacing="compact">
<li><tt>name</tt>: (required, string) A short name for the endpoint, for example &quot;availability&quot;, &quot;info&quot;, &quot;poll&quot;, &quot;create&quot;, &quot;delete&quot;, &quot;renewal&quot; or &quot;transfer&quot;.</li>
<li><tt>url_template</tt>: (required, string) The URI template for the endpoint, using the syntax defined in <xref target="RFC6570"></xref>.</li>
</ul></li>
<li><t><tt>maintenance</tt>: (optional, array) An array containing information about upcoming planned maintenance windows of the server, with the following fields:</t>

<ul spacing="compact">
<li><tt>start_time</tt>: (required, string) The start time of the maintenance window in ISO 8601 format.</li>
<li><tt>end_time</tt>: (required, string) The end time of the maintenance window in ISO 8601 format.</li>
<li><tt>description</tt>: (optional, string) A human-readable description of the maintenance window.</li>
</ul></li>
</ul>
<t>The following template variables are defined for use in RPP endpoint URL templates. They are data object independent; the same variables are used regardless of which Data Object or Process Object the endpoint acts on.</t>

<ul spacing="compact">
<li><tt>collection</tt>: The resource collection path segment, derived per Rule 1.</li>
<li><tt>id</tt>: The Unique Identifier value (as defined in <xref target="I-D.ietf-rpp-data-objects"></xref>) of the resource instance within <tt>collection</tt>.</li>
<li><tt>process-collection</tt>: The process collection path segment, derived per Rule 3.</li>
<li><tt>process-id</tt>: The Unique Identifier value (as defined in <xref target="I-D.ietf-rpp-data-objects"></xref>) of a specific process instance, scoped to its owner Data Object instance.</li>
</ul>
<t>Example discovery response document:</t>

<sourcecode type="json"><![CDATA[{
  "base_url": "https://rpp.example/rpp/v1",
  "version": "1.0",
  "tlds": ["example", "org"],
  "extensions": [
    {
      "name": "RPP example extension",
      "id": "urn:ietf:params:rpp:extension:example-extension",
      "version": "1.0",
      "url": "https://www.iana.org/assignments/rpp-extensions/rpp-example-extension-1.0"
    }
  ],
  "profiles": [
    {
      "name": "EPP compatibility profile",
      "id": "urn:ietf:params:rpp:profile:epp-compatibility",
      "version": "1.0",
      "url": "https://www.iana.org/assignments/rpp-profiles/epp-compatibility-provisioning-profile-1.0"
    }
  ],
  "objects": ["domains", "hosts", "entities"],
  "endpoints": [
    {
      "name": "availability",
      "url_template": "/{collection}/{id}/availability"
    },
    {
      "name": "info",
      "url_template": "/{collection}/{id}"
    },
    {
      "name": "poll",
      "url_template": "/messages"
    },
    {
      "name": "create",
      "url_template": "/{collection}"
    },
  ],
  "authentication": ["Bearer"],
  "maintenance": [
    {
      "start_time": "2026-06-01T00:00:00Z",
      "end_time": "2026-06-01T06:00:00Z",
      "description": "Planned maintenance for server upgrades"
    }
  ]

}
]]>
</sourcecode>

<section anchor="workflow"><name>Workflow</name>
<t>The steps for a typical workflow of provisioning an object using RPP without knowing the location and capabilities of the server are as follows, the first three steps are optional, the client can choose to skip any of these steps if it already has the required information from a previous interaction or configuration.</t>

<ol spacing="compact">
<li>Bootstrap (optional): The client discovers the location of the RPP server by looking up the IANA registry for RPP servers or by performing a DNS SRV lookup as defined in <xref target="RFC2782"></xref>.</li>
<li>Discover capabilities (optional):  The client retrieves the capabilities of the RPP server by sending a GET request to the well-known endpoint at <tt>/.well-known/rpp.json</tt>.</li>
<li>Extract RPP URLs (optional): The client extracts the base URL and endpoint URL templates from the discovery response, and uses this information to construct the URLs for the desired operations.</li>
<li>Perform provisioning operations: The client performs provisioning operations by sending HTTP requests to the appropriate endpoint URLs, using the HTTP method and request message body as required by the specific operation.</li>
</ol>
</section>
</section>

<section anchor="versioning"><name>Versioning</name>
<t>RPP is designed to be extensible and backward compatible. The version of the RPP API is indicated in the URL path, for example: <tt>https://rpp.example/rpp/v1/</tt>. The server MUST support at least one version of the RPP API, and MUST return a 404 Not Found status code for requests using an unsupported version. The versioning scheme uses the Semantic Versioning format defined in <xref target="SemVer"></xref>, but only the major version number is used to indicate breaking changes. The minor and patch version numbers are not used in an URL path, but can be used in the media type or in the message body to indicate non-breaking changes.</t>
<t>The following RPP elements include versioning support:</t>

<ul spacing="compact">
<li>Endpoints: The server MUST support at least one version of the RPP API, and MUST return a 404 Not Found status code for requests using an unsupported version.</li>
<li>Messages: A request and response message MUST include the version of the RPP API it is compatible with.</li>
<li>Extensions: RPP extensions MUST include the version of the RPP API they are compatible with.</li>
<li>Profiles: RPP profiles MUST include the version of the RPP API they are compatible with.</li>
<li>Media types: RPP media types MUST include the version of the RPP API they are compatible with.</li>
<li>Result codes: RPP result codes may be added by extensions or updates to the core RPP specification.</li>
</ul>

<section anchor="endpoints"><name>Endpoints</name>
<t>The <tt>base_url</tt> element of the RPP Discovery response MAY include the version of the RPP API supported by the server. The client MUST use this <tt>base_url</tt> for all subsequent requests to the server. For example, if the version is 1.2.3, the <tt>base_url</tt> is <tt>https://rpp.example/rpp/v1/</tt>, then the client MUST use this URL for all subsequent requests to the server, and MUST not use a different version in the URL path.</t>
</section>

<section anchor="messages"><name>Messages</name>
<t>The <tt>version</tt> element of the RPP request and response messages MUST include the version of the RPP API that the message is compatible with. The server MUST reject requests with a version that is not supported by the server, and MUST return a RPP Client error code.</t>
</section>

<section anchor="extensions"><name>Extensions</name>
<t>The RPP server MUST include the version for each extension in the RPP Discovery response. The client MUST use this version information to determine which extensions are supported by the server, and to ensure that it uses the correct version of the extension when making requests to the server.
A request using an extension MUST include the version of the extension. The server MUST reject requests using extensions with a version that is not supported by the server, and MUST return a RPP Client error code. The following is an example of how the version information for an extension can be included in the RPP Discovery response:</t>

<sourcecode type="json"><![CDATA["extensions": [
    {
      "name": "RPP example extension",
      "id": "urn:ietf:params:rpp:extension:example-extension",
      "version": "1.0",
      "url": "https://www.iana.org/assignments/rpp-extensions/rpp-example-extension-1.0"
    }
  ],
]]>
</sourcecode>
</section>

<section anchor="profiles"><name>Profiles</name>
<t>The RPP server MUST include the version for each profile in the RPP Discovery response. The client MUST use this version information to determine which profiles are supported by the server, and to ensure that it uses the correct version of the profile when making requests to the server. A request using a profile MUST include the version of the profile. The server MUST reject requests using profiles with a version that is not supported by the server, and MUST return a RPP Client error code. The following is an example of how the version information for a profile can be included in the RPP Discovery response:</t>

<sourcecode type="json"><![CDATA["profiles": [
    {
      "name": "EPP compatibility profile",
      "id": "urn:ietf:params:rpp:profile:epp-compatibility",
      "version": "1.0",
      "url": "https://www.iana.org/assignments/rpp-profiles/epp-compatibility-provisioning-profile-1.0"
    }
  ]
]]>
</sourcecode>
</section>
</section>

<section anchor="media-types"><name>Media types</name>
<t>RPP media types are used to indicate the format of the request and response messages, and MUST include a parameter indicating the name of the profile they are compatible with. The server MUST use the profile information in the media type to determine which features, extensions and versions to use when processing the request, and to ensure that it returns a response that is compatible with the client. The client MUST use the profile information in the media type to determine which features, extensions and versions to use when processing the response, and to ensure that it can correctly interpret the response.</t>
<t>The definition of profile parameters in media types is described in section ....</t>
</section>

<section anchor="profiles-1"><name>Profiles</name>
<t>A profile is a named set of protocol features and versions that are used to define the compatibility and capabilities of RPP server implementations, allowing for better interoperability between different implementations. Using profiles helps to simplify the implementation and deployment of RPP by providing a clear and concise way for the client and server to communicate their capabilities and requirements.</t>
<t>A profile is identified by a unique name and may be published as a standard profile in the IANA registry for RPP profiles, to promote interoperability and standardization across implementations. Standard profiles names MUST use the RPP URN namespace defined in this document, for example: <tt>urn:ietf:params:rpp:profile:{profile_name}</tt>. The profile name MUST be unique within the RPP URN namespace and SHOULD be descriptive of the features and versions included in the profile.</t>
<t>A profile can also be defined as a private profile, which is not published in the IANA registry, but is used by specific server implementations only. A private profile can be defined by a server operator to specify the features and versions supported by their implementation. If the profile is not published in the IANA registry, then the server operator MUST ensure that the profile name is globally unique to avoid conflicts with other profiles, the use of reverse domain name notation is RECOMMENDED for private profiles to ensure uniqueness.</t>

<section anchor="definition"><name>Definition</name>
<t>A profile definition MUST contain the following fields, private profiles may contain additional fields as needed:</t>

<ul spacing="compact">
<li><tt>name</tt>: A unique name that identifies the profile.</li>
<li><tt>description</tt>: A human-readable description of the profile and its intended use.</li>
<li><tt>version</tt>: The version of the profile.</li>
<li><tt>rpp_version</tt>: The minimum version of the RPP protocol that is supported or required for the profile.</li>
<li><tt>objects</tt>: A list of objects allowed for provisioning operations, for example &quot;domains&quot;, &quot;hosts&quot;, &quot;entities&quot;, etc.</li>
<li><tt>extensions</tt>: A list of extensions, including their versions, that are supported or required for the profile.</li>
<li><tt>profile</tt>: A base profile that is extended by this profile. The base profile MUST be published in the IANA registry for RPP profiles, or be made available to the client using other means.</li>
</ul>
<t anchor="profile-example">Example JSON representation for a standard profile named &quot;example-profile&quot; that supports RPP version 1.0 and includes two extensions, &quot;rppExample&quot; version 1.0 and &quot;rppOther&quot; version 1.1. The profile also &quot;extends&quot; the &quot;base-profile&quot; profile, which is defined in the IANA registry for RPP profiles and supports RPP version 1.0.</t>

<sourcecode type="json"><![CDATA[{
  "name": "urn:ietf:params:rpp:profile:example-profile",
  "description": "An example profile for provisioning objects using the RPP protocol.",
  "version": "1.0",
  "rpp_version": "1.0",
  "objects": ["domains", "hosts", "entities"],
  "extensions": [
    {
      "rppExample": {
        "version": "1.0"
      },
      "rppOther": {
        "version": "1.1"
      }
    }
  ],
  "profile": {
    "name": "urn:ietf:params:rpp:profile:base-profile",
    "version": "1.0"
  }
}
]]>
</sourcecode>
</section>

<section anchor="inheritance"><name>Inheritance</name>
<t>A profile can include another profile, which is referred to as &quot;inheriting&quot; from that profile. When a profile inherits from another profile, it means that the features and versions defined in the inherited profile are also included in the inheriting profile. This allows for the creation of more complex profiles by building upon existing profiles. For example, a profile named &quot;example-profile&quot; could inherit from a base profile named &quot;base-profile&quot;, which includes a set of common features and versions. The &quot;example-profile&quot; could then add additional features and versions on top of the ones defined in the &quot;base-profile&quot;, or it can override some of the features and versions from the &quot;base-profile&quot;. This allows for greater flexibility and modularity in defining profiles, as well as promoting reuse of common features and versions across different profiles. However, it is important to note that the use of inheritance in profiles can also make things more complicated, as it can create dependencies between profiles and make it harder to understand the features and versions included in a profile. Therefore, it is recommended to use inheritance with caution and to clearly document the relationships between profiles. The depth of inheritance MUST be limited to 1 to provent excessive complexity, and profile designers MUST NOT create circular dependencies between profiles, where a profile inherits from itself directly.</t>
<t>This is an example of the parent base-profile used in the previous example, it contains a single extension &quot;rppOther&quot; version 1.0 and does not include any other profiles:</t>

<sourcecode type="json"><![CDATA[{
  "name": "urn:ietf:params:rpp:profile:base-profile",
  "description": "A base profile for provisioning objects using the RPP protocol.",
  "version": "1.0",
  "rpp_version": "1.0",
  "objects": ["domains", "hosts", "entities"],
  "extensions": [
    {
      "rppOther": {
        "version": "1.0"
      }
    }
  ],
  "profile":
}
]]>
</sourcecode>
<t>The example profile definition shown in <xref target="profile-example"></xref> uses the &quot;base-profile&quot; as its base and inherits its features and also overrides the version of the &quot;rppOther&quot; extension defined in the base profile.</t>
</section>

<section anchor="signalling"><name>Signalling</name>
<t>This document descibes two distinct methods for signalling the profile used in a RPP request or response, the first method uses a dedicated HTTP header, the second method uses media type parameters. The two methods MUST not be used simultaneously in a single request or response. If both methods are used in a single request or response, then the server MUST return an HTTP error response and include a Problem Detail response in the message body.</t>

<section anchor="header-signalling"><name>Header signalling</name>
<t>The client MUST use the <tt>RPP-Profile</tt> header to indicate the name of the profile that is to be used for the request. The value of this header MUST be of the type <tt>parameter</tt> described in <xref target="RFC8941"></xref>, the first parameter MUST uniquely identify a profile, for example <tt>urn:ietf:params:rpp:profile:example-profile</tt>, followed by the version parameter. If the server does not support the indicated profile or version, then the server MUST return an HTTP error response and include a Problem Detail response in the message body.</t>
<t>The ABNF for Profile header value is as follows:</t>

<sourcecode type="abnf"><![CDATA[profile-header = "profile" "=" profile-name ";" OWS "version" "=" version
profile-name   = token
version        = 1*DIGIT "." 1*DIGIT
]]>
</sourcecode>
<t>Example:</t>

<sourcecode type="http"><![CDATA[RPP-Profile: profile=urn:ietf:params:rpp:profile:example-profile;version=1.0
]]>
</sourcecode>
</section>

<section anchor="media-type-parameter-signalling"><name>Media type parameter signalling</name>
<t>When using Media type parameter signalling, the client and the server MUST use media type parameters in the Accept and Content-Type headers to indicate the name and version of the profile used in the request. The media type parameters MUST be defined as follows:</t>

<ul spacing="compact">
<li><tt>profile</tt>: The value of this parameter MUST uniquely identify the profile, for example <tt>urn:ietf:params:rpp:profile:example-profile</tt>.</li>
<li><tt>version</tt>: The value of this parameter MUST indicate the version of the profile used in the request.</li>
</ul>
<t>The ABNF for media type parameter signalling is as follows:</t>

<sourcecode type="abnf"><![CDATA[profile-parameter = "profile" "=" profile-name ";" OWS "version" "=" version
profile-name      = token
version           = 1*DIGIT "." 1*DIGIT
]]>
</sourcecode>
<t>Example for the media type <tt>application/rpp+json</tt> with profile parameters indicating the use of the &quot;example-profile&quot; profile version 1.0.:</t>

<sourcecode type="http"><![CDATA[Accept: application/rpp+json; profile="urn:ietf:params:rpp:profile:example-profile"; version="1.0"
Content-Type: application/rpp+json; profile="urn:ietf:params:rpp:profile:example-profile"; version="1.0"
]]>
</sourcecode>
</section>

<section anchor="process-signalling"><name>Process signalling</name>
<t>When a server creates a process resource as a side effect of a uniform interface operation, it signals this to the client using the <tt>Link</tt> response header <xref target="RFC8288"></xref> with <tt>rel=&quot;rpp-process&quot;</tt>. The following target attributes are defined for this relation type:</t>

<ul spacing="compact">
<li><tt>process</tt>: (REQUIRED) The process object identifier of the created process (e.g. <tt>process=&quot;transferProcess&quot;</tt>).</li>
<li><tt>processId</tt>: (OPTIONAL) The server-assigned persistent identifier of the created process instance (e.g. <tt>processId=&quot;XYZ-12345&quot;</tt>). If the server assigns a persistent identifier, this attribute MUST be included.</li>
<li><tt>latest</tt>: (OPTIONAL) The boolean value <tt>&quot;true&quot;</tt>, indicating that the target URL is the latest process created of a given type. The target URL MAY use the <tt>&quot;latest&quot;</tt> mnemonic rather than a specific process identifier. There MUST NOT be more than one process of a given type with this attribute set to <tt>&quot;true&quot;</tt>.</li>
</ul>
<t>If multiple process objects are created, the server MUST include one <tt>Link</tt> header field per created process resource.</t>
<t>Example:</t>

<sourcecode type="http"><![CDATA[Link: <https://rpp.example/rpp/v1/domainNames/foo.example/processes/transferProcesses/XYZ-12345>; rel="rpp-process"; process="transferProcess"; processId="XYZ-12345"; latest=true
]]>
</sourcecode>
</section>
</section>
</section>

<section anchor="endpoints-1"><name>Endpoints</name>
<t>Endpoints are described using URI Templates <xref target="RFC6570"></xref> relative to a discoverable base URL, as recommended by <xref target="RFC9205"></xref>. Some RPP endpoints do not require a request and/or response message.</t>

<section anchor="http-mapping-rules"><name>HTTP Mapping Rules</name>
<t>All RPP endpoints are derived mechanically from the Data Object definitions in <xref target="I-D.ietf-rpp-data-objects"></xref>. No endpoint URL or HTTP method related to processing of provisioning objects is defined independently of a corresponding Data Object. The rules in this section MUST be applied to determine the URL path and HTTP method for any operation.</t>

<section anchor="rule-1-collection-path-segment"><name>Rule 1: Collection Path Segment</name>
<t>Each Data Object has a stable, <tt>&quot;Identifier&quot;</tt> (e.g. <tt>&quot;domainName&quot;</tt>, <tt>&quot;contact&quot;</tt>, <tt>&quot;host&quot;</tt>). The URL path segment for a collection of such objects MUST be derived by applying the <tt>plural()</tt> function to the object's <tt>&quot;Identifier&quot;</tt>. The <tt>&quot;plural()&quot;</tt> function appends an &quot;s&quot; or &quot;es&quot; to the identifier as per English language rules. Any irregular plural version MUST be defined in the data object specification.</t>

<artwork><![CDATA[{collection} = plural(dataObject.identifier)
]]>
</artwork>
<t>Examples derived from current data object identifiers:</t>
<table>
<thead>
<tr>
<th>Data Object <tt>&quot;Identifier&quot;</tt></th>
<th><tt>&quot;plural()&quot;</tt> result</th>
<th>URL collection segment</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>&quot;domainName&quot;</tt></td>
<td><tt>&quot;domainNames&quot;</tt></td>
<td><tt>&quot;/domainNames&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;contact&quot;</tt></td>
<td><tt>&quot;contacts&quot;</tt></td>
<td><tt>&quot;/contacts&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;host&quot;</tt></td>
<td><tt>&quot;hosts&quot;</tt></td>
<td><tt>&quot;/hosts&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;organisation&quot;</tt></td>
<td><tt>&quot;organisations&quot;</tt></td>
<td><tt>&quot;/organisations&quot;</tt></td>
</tr>
</tbody>
</table></section>

<section anchor="rule-2-uniform-interface-operations"><name>Rule 2: Uniform Interface Operations</name>
<t>The four uniform interface operations defined in the RPP data object specification map to HTTP methods and URL paths as follows. <tt>&quot;{collection}&quot;</tt> is derived per Rule 1. <tt>&quot;{id}&quot;</tt> is the unique identifier value of the specific object instance.</t>
<table>
<thead>
<tr>
<th>Operation <tt>&quot;Identifier&quot;</tt></th>
<th>HTTP Method</th>
<th>URL path</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>&quot;create&quot;</tt></td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>/&quot;{collection}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;read&quot;</tt></td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;update&quot;</tt></td>
<td><tt>&quot;PUT or PATCH&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;delete&quot;</tt></td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}&quot;</tt></td>
</tr>
</tbody>
</table></section>

<section anchor="rule-3-direct-access-sub-resource-path-segment"><name>Rule 3: Direct Access Sub-Resource Path Segment</name>
<t>A data element whose <tt>&quot;Direct Access&quot;</tt> flag is set to <tt>true</tt> in its Data Object definition is additionally exposed as a sub-resource, nested under the URL of the resource instance that contains it. This rule applies uniformly and recursively: the containing resource instance MAY itself be a Direct Access sub-resource of a further-enclosing resource.</t>
<t>The fixed path segment for such a sub-resource MUST be derived from the Direct Access data element's own <tt>&quot;Identifier&quot;</tt> — not from the <tt>&quot;Identifier&quot;</tt> of the associated object type the element references.</t>
<t>If the Direct Access element's cardinality is 0-1 or 1, the element's own <tt>&quot;Identifier&quot;</tt> MUST be used as the path segment, unpluralized; the resulting path already addresses a single instance unambiguously.</t>

<artwork><![CDATA[{direct-access-path} = {container-path} "/" directAccessElement.identifier
]]>
</artwork>
<t>If the Direct Access element's cardinality is greater than 1, the <tt>plural()</tt> function MUST be applied to the element's <tt>&quot;Identifier&quot;</tt> to derive the path segment, and an individual associated object instance MUST be additionally addressed by appending its Unique Identifier value as a further path segment, <tt>&quot;{unique-id}&quot;</tt>. <xref target="I-D.ietf-rpp-data-objects"></xref> requires that any object type referenced by a Direct Access element of cardinality greater than 1 define a Unique Identifier for exactly this purpose.</t>

<artwork><![CDATA[{direct-access-path} = {container-path} "/" plural(directAccessElement.identifier) "/" {unique-id}
]]>
</artwork>
<t>Applying Rule 3 recursively from the top-level Data Object down to every Direct Access element defined in <xref target="I-D.ietf-rpp-data-objects"></xref> yields the following paths (<tt>&quot;{id}&quot;</tt> denotes the Unique Identifier value of the resource instance immediately to its left; it is instantiated per resource type as shown in the Derived Endpoint Reference below):</t>
<table>
<thead>
<tr>
<th>Container path</th>
<th>Direct Access element <tt>&quot;Identifier&quot;</tt></th>
<th>Cardinality</th>
<th>Resulting path</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>&quot;/domainNames/{id}&quot;</tt></td>
<td><tt>&quot;processes&quot;</tt></td>
<td>0-1</td>
<td><tt>&quot;/domainNames/{id}/processes&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;/contacts/{id}&quot;</tt></td>
<td><tt>&quot;processes&quot;</tt></td>
<td>0-1</td>
<td><tt>&quot;/contacts/{id}/processes&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;/hosts/{id}&quot;</tt></td>
<td><tt>&quot;processes&quot;</tt></td>
<td>0-1</td>
<td><tt>&quot;/hosts/{id}/processes&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;/organisations/{id}&quot;</tt></td>
<td><tt>&quot;processes&quot;</tt></td>
<td>0-1</td>
<td><tt>&quot;/organisations/{id}/processes&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;/organisations/{id}/users/{id}&quot;</tt></td>
<td><tt>&quot;processes&quot;</tt></td>
<td>0-1</td>
<td><tt>&quot;/organisations/{id}/users/{id}/processes&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;/{collection}/{id}/processes&quot;</tt></td>
<td><tt>&quot;transferProcess&quot;</tt></td>
<td>0+</td>
<td><tt>&quot;/{collection}/{id}/processes/transferProcesses/{process-id}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;/{collection}/{id}/processes&quot;</tt></td>
<td><tt>&quot;renewProcess&quot;</tt></td>
<td>0+</td>
<td><tt>&quot;/{collection}/{id}/processes/renewProcesses/{process-id}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;/{collection}/{id}/processes&quot;</tt></td>
<td><tt>&quot;restoreProcess&quot;</tt></td>
<td>0+</td>
<td><tt>&quot;/{collection}/{id}/processes/restoreProcesses/{process-id}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;/{collection}/{id}/processes&quot;</tt></td>
<td><tt>&quot;createProcess&quot;</tt></td>
<td>0+</td>
<td><tt>&quot;/{collection}/{id}/processes/createProcesses/{process-id}&quot;</tt></td>
</tr>
</tbody>
</table><t><tt>&quot;{collection}&quot;</tt> in the last four rows is derived per Rule 1 and stands for any owner Data Object's collection segment (e.g. <tt>&quot;domainNames&quot;</tt>, <tt>&quot;contacts&quot;</tt>); the <tt>Processes</tt> element and its nested Process Object elements are defined once, generically, and Direct Access sub-resources derive identically regardless of the owner Data Object type. <tt>&quot;{process-id}&quot;</tt> is the Process Object's Unique Identifier value; Rule 4 defines the <tt>&quot;latest&quot;</tt> mnemonic as an additional way to address it.</t>
<t>The remaining rules in this section (Rules 4 through 6) apply Rule 3 specifically to Process Objects and describe how they are further exposed and interacted with.</t>
</section>

<section anchor="rule-4-process-uniform-interface-operations"><name>Rule 4: Process Uniform Interface Operations</name>
<t>The four uniform interface operations from Rule 2 apply to Process Objects at the path derived per Rule 3. A server MAY assign a unique identifier <tt>&quot;{process-id}&quot;</tt> to each process instance and make it addressable by this identifier. The fixed keyword <tt>&quot;latest&quot;</tt> is used to address the most recent process instance when no specific process <tt>&quot;{process-id}&quot;</tt> is known or assigned.</t>
<table>
<thead>
<tr>
<th>Operation <tt>&quot;Identifier&quot;</tt></th>
<th>HTTP Method</th>
<th>URL path</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>&quot;create&quot;</tt></td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/{process-collection}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;read&quot;</tt></td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/{process-collection}/latest&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;read&quot;</tt> (specific instance)</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/{process-collection}/{process-id}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;delete&quot;</tt></td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/{process-collection}/latest&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;delete&quot;</tt> (specific instance)</td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/{process-collection}/{process-id}&quot;</tt></td>
</tr>
</tbody>
</table><t>A started process MAY create a resource accessible using both the <tt>&quot;latest&quot;</tt> mnemonic and a server-assigned <tt>&quot;{process-id}&quot;</tt>. If the server exposes any access to a process instances, access to the most recent instance via <tt>&quot;latest&quot;</tt> MUST be supported.</t>
<t>When a process is created and immediately completed by the server, a 201 Created response MAY still be provided with a <tt>&quot;Location&quot;</tt> header pointing to the created process resource.</t>
<t>If the server chooses not to expose any persistent process resource, it MUST return 200 OK instead of 201 Created.</t>
<t>The operations using the DELETE method MUST NOT accept a request body. Because the semantic of the HTTP DELETE method are not defined and may cause deployment issues.
If a request body is present for any operation using the DELETE method, the server MUST reject the request with an appropriate error response.</t>
<t>This means that the &quot;delete&quot; operation (HTTP DELETE method) is not extensible, if the server needs to support additional data for a special &quot;delete&quot; operation, then a new process MUST be defined for this purpose.</t>
</section>

<section anchor="rule-5-extended-process-operations"><name>Rule 5: Extended Process Operations</name>
<t>Operations on a Process Object beyond the uniform interface (e.g. <tt>&quot;transferApprove&quot;</tt>, <tt>&quot;transferReject&quot;</tt>, <tt>&quot;report&quot;</tt>) are mapped to sub-resources of a specific process instance. The operation's <tt>&quot;Identifier&quot;</tt> is used unchanged as the final path segment. The HTTP method for all such extended operations MUST be <tt>POST</tt>.</t>
<table>
<thead>
<tr>
<th>Operation <tt>&quot;Identifier&quot;</tt></th>
<th>HTTP Method</th>
<th>URL path</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>&quot;{operationIdentifier}&quot;</tt></td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/{process-collection}/latest/{operationIdentifier}&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;{operationIdentifier}&quot;</tt> (specific instance)</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/{process-collection}/{process-id}/{operationIdentifier}&quot;</tt></td>
</tr>
</tbody>
</table><t>The operation <tt>&quot;Identifier&quot;</tt> MUST be used as-is with no transformation. The following examples are derived directly from the operation identifiers defined in the RPP data object specification:</t>
<table>
<thead>
<tr>
<th>Operation <tt>&quot;Identifier&quot;</tt></th>
<th>Derived URL path (relative to <tt>&quot;domains/foo.example&quot;</tt>)</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>&quot;transferApprove&quot;</tt></td>
<td><tt>&quot;/domains/foo.example/processes/transferProcesses/latest/transferApprove&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;transferReject&quot;</tt></td>
<td><tt>&quot;/domains/foo.example/processes/transferProcesses/latest/transferReject&quot;</tt></td>
</tr>

<tr>
<td><tt>&quot;report&quot;</tt></td>
<td><tt>&quot;/domains/foo.example/processes/restoreProcesses/latest/report&quot;</tt></td>
</tr>
</tbody>
</table></section>

<section anchor="rule-6-process-listing"><name>Rule 6: Process Listing</name>
<t>A server MAY implement a listing facility for processes. If implemented, the following URL structures MUST be used by the client.</t>
<t>To retrieve all process instances of a given process type:</t>
<t><tt>&quot;GET /{collection}/{id}/processes/{process-collection}/&quot;</tt></t>
<t>To retrieve all process instances across all process types for an object:</t>
<t><tt>&quot;GET /{collection}/{id}/processes/&quot;</tt></t>
<t>A server MAY choose not to implement these endpoints, in which case it MUST return 404 Not Found or 501 Not Implemented.</t>
</section>
</section>

<section anchor="derived-endpoint-reference"><name>Derived Endpoint Reference</name>
<t>The following table lists all current RPP endpoints, each derived by applying the rules above to the relevant data object and operation identifiers. The following table is non normative.</t>
<table>
<thead>
<tr>
<th>Operation</th>
<th>HTTP Method</th>
<th>URL path</th>
</tr>
</thead>

<tbody>
<tr>
<td>Domain: read</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/domainNames/{id}&quot;</tt></td>
</tr>

<tr>
<td>Domain: create</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/domainNames&quot;</tt></td>
</tr>

<tr>
<td>Domain: update</td>
<td><tt>&quot;PUT or PATCH&quot;</tt></td>
<td><tt>&quot;/domainNames/{id}&quot;</tt></td>
</tr>

<tr>
<td>Domain: delete</td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/domainNames/{id}&quot;</tt></td>
</tr>

<tr>
<td>Contact: read</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/contacts/{id}&quot;</tt></td>
</tr>

<tr>
<td>Contact: create</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/contacts&quot;</tt></td>
</tr>

<tr>
<td>Contact: update</td>
<td><tt>&quot;PUT or PATCH&quot;</tt></td>
<td><tt>&quot;/contacts/{id}&quot;</tt></td>
</tr>

<tr>
<td>Contact: delete</td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/contacts/{id}&quot;</tt></td>
</tr>

<tr>
<td>Host: read</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/hosts/{id}&quot;</tt></td>
</tr>

<tr>
<td>Host: create</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/hosts&quot;</tt></td>
</tr>

<tr>
<td>Host: update</td>
<td><tt>&quot;PUT or PATCH&quot;</tt></td>
<td><tt>&quot;/hosts/{id}&quot;</tt></td>
</tr>

<tr>
<td>Host: delete</td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/hosts/{id}&quot;</tt></td>
</tr>

<tr>
<td>Organisation: read</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/organisations/{id}&quot;</tt></td>
</tr>

<tr>
<td>Organisation: create</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/organisations&quot;</tt></td>
</tr>

<tr>
<td>Organisation: update</td>
<td><tt>&quot;PATCH&quot;</tt></td>
<td><tt>&quot;/organisations/{id}&quot;</tt></td>
</tr>

<tr>
<td>Organisation: delete</td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/organisations/{id}&quot;</tt></td>
</tr>

<tr>
<td>User: read</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/organisations/{id}/users/{userId}&quot;</tt></td>
</tr>

<tr>
<td>User: create</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/organisations/{id}/users&quot;</tt></td>
</tr>

<tr>
<td>User: update</td>
<td><tt>&quot;PATCH&quot;</tt></td>
<td><tt>&quot;/organisations/{id}/users/{userId}&quot;</tt></td>
</tr>

<tr>
<td>User: delete</td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/organisations/{id}/users/{userId}&quot;</tt></td>
</tr>

<tr>
<td>Transfer: create</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/transferProcesses&quot;</tt></td>
</tr>

<tr>
<td>Transfer: read</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/transferProcesses/latest&quot;</tt></td>
</tr>

<tr>
<td>Transfer: delete (cancel)</td>
<td><tt>&quot;DELETE&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/transferProcesses/latest&quot;</tt></td>
</tr>

<tr>
<td>Transfer: transferApprove</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/transferProcesses/latest/transferApprove&quot;</tt></td>
</tr>

<tr>
<td>Transfer: transferReject</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/transferProcesses/latest/transferReject&quot;</tt></td>
</tr>

<tr>
<td>Restore: create</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/restoreProcesses&quot;</tt></td>
</tr>

<tr>
<td>Restore: read</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/restoreProcesses/latest&quot;</tt></td>
</tr>

<tr>
<td>Restore: report</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/restoreProcesses/latest/report&quot;</tt></td>
</tr>

<tr>
<td>Renew: create</td>
<td><tt>&quot;POST&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/renewProcesses&quot;</tt></td>
</tr>

<tr>
<td>Renew: read</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/renewProcesses/latest&quot;</tt></td>
</tr>

<tr>
<td>Transfer: list</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes/transferProcesses&quot;</tt></td>
</tr>

<tr>
<td>Processes: list</td>
<td><tt>&quot;GET&quot;</tt></td>
<td><tt>&quot;/{collection}/{id}/processes&quot;</tt></td>
</tr>
</tbody>
</table>
<aside><t>TODO: add availability and message queue</t>
</aside>
</section>

<section anchor="availability-for-creation"><name>Availability for Creation</name>

<aside><t>TODO: align with data object when availability is described there</t>
</aside>
<t>The Availability for Creation endpoint is used to check whether an object can be successfully provisioned. Two distinct methods are defined for checking the availability of provisioning of an object, the first method uses the HEAD method for a quick check to find out if the object can be provisioned. The second method uses the GET method to retrieve additional information about the object's availability for provisioning, for example about pricing or additional requirements to be able to provision the requested object.</t>
<t>When the client uses the HTTP HEAD method, the server MUST respond with an HTTP status code 200 (OK) if the object can be provisioned or with an HTTP status code 404 (Not Found) if the object cannot be provisioned.</t>
<t>When the client uses the HTTP GET method, the server MUST respond with an HTTP status code 200 (OK) if the object can be provisioned. The server MUST include a message body containing more detailed availability information, for example about pricing or additional requirements to be able to provision the requested object. The message body MAY be and empty JSON object if no additional information is applicable.</t>
<t>If the object cannot be provisioned then the server MUST return an HTTP status code 404 (Not Found) and include a problem statement in the message body.</t>
<t>As an extension point the server MAY define and the client MAY use additional HTTP query parameters to further specify the check operation or the kind of response information that shall be returned. For example Registry Fee Extension <xref target="RFC8748"></xref> defines a possibility to request certain currency, only certain commands or periods. Such functionality would add query parameters, which could be used with GET request to receive additional pricing information with the response. HEAD request would not be affected in this case.</t>
<t>The server MUST respond with the same HTTP status code if the same URL is requested with HEAD and with GET.</t>

<artwork><![CDATA[- Request: HEAD|GET {collection}/{id}/availability
- Request message: None
- Response message: Optional availability response
]]>
</artwork>
<t>Example request for a domain name that is not available for provisioning:</t>

<sourcecode type="http"><![CDATA[HEAD domains/foo.example/availability HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</sourcecode>
<t>Example response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 404 Not Found
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
RPP-Cltrid: ABC-12345
RPP-Svtrid: XYZ-12345
RPP-code: 01000
Content-Length: 0

]]>
</sourcecode>
</section>

<section anchor="resource-information"><name>Resource Information</name>
<t>The Object Info request MUST use the HTTP GET method on a resource identifying an object instance (Rule 2, <tt>read</tt> operation). If the object has authorization information attached then the client MUST use an empty message body and include the RPP-Authorization HTTP header. If the authorization is linked to a database object the client MUST also include the roid in the RPP-Authorization header. The client MAY also use a message body that includes the authorization information, the client MUST then not use the RPP-Authorization header.</t>
<t>Example request for an object not using authorization information:</t>

<sourcecode type="http"><![CDATA[GET /rpp/v1/domainNames/foo.example HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</sourcecode>
<t>Example request using RPP-Authorization header for an object that has attached authorization information:</t>

<sourcecode type="http"><![CDATA[GET /rpp/v1/domainNames/foo.example HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
RPP-Authorization: authinfo value=TXkgU2VjcmV0IFRva2Vu

]]>
</sourcecode>
<t>Example Info response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 424
Content-Type: application/rpp+json
Content-Language: en
RPP-code: 01000

TODO: JSON message here
]]>
</sourcecode>
</section>

<section anchor="create-resource"><name>Create Resource</name>
<t>The client MUST use the HTTP POST method on a resource identifying a collection of object instances (Rule 2, <tt>create</tt> operation).</t>
<t>Example Domain Create request for a new domain name <tt>foo.example</tt>:</t>

<sourcecode type="http"><![CDATA[POST /rpp/v1/domainNames HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Content-Type: application/rpp+json
Accept-Language: en
Content-Length: 220

TODO
]]>
</sourcecode>
<t>Example Domain Create response for a new domain name <tt>foo.example</tt>:</t>

<sourcecode type="http"><![CDATA[HTTP/2 201 Created
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Language: en
Content-Length: 642
Content-Type: application/rpp+json
Location: https://rpp.example/rpp/v1/domainNames/foo.example
RPP-code: 01000

TODO
]]>
</sourcecode>
<t>Example Domain Create response where a <tt>createProcess</tt> object was implicitly created:</t>

<sourcecode type="http"><![CDATA[HTTP/2 201 Created
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Language: en
Content-Type: application/rpp+json
Location: https://rpp.example/rpp/v1/domainNames/foo.example
Link: <https://rpp.example/rpp/v1/domainNames/foo.example/processes/createProcesses/latest>; rel="rpp-process" process="createProcess"; processId="XYZ-12345";
RPP-code: 01000

TODO
]]>
</sourcecode>
</section>

<section anchor="delete-resource"><name>Delete Resource</name>
<t>The client MUST use the HTTP DELETE method on a resource identifying a unique object instance (Rule 2, <tt>delete</tt> operation).</t>
<t>Example Domain Delete request:</t>

<sourcecode type="http"><![CDATA[DELETE /rpp/v1/domainNames/foo.example HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</sourcecode>
<t>Example Domain Delete response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 80
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
RPP-code: 01000

TODO
]]>
</sourcecode>
</section>

<section anchor="update-resource"><name>Update Resource</name>
<t>RPP supports two complementary update operations for modifying an existing object instance, each with its own semantics and use cases:</t>

<ul>
<li><t><strong>Full update</strong> (HTTP PUT): The client sends a complete replacement representation of the object. The server MUST replace the stored object with the provided representation. Any attributes not present in the request body MUST be treated as absent and cleared or reset to their default values, subject to server policy. The client MUST send all read-write attributes required by the data model, not just the changed ones. The client MUST not send any create-only attributes.</t>
</li>
<li><t><strong>Partial update</strong> (HTTP PATCH): The client sends only the attributes to be modified. The server MUST apply only the changes indicated in the request body and leave all other attributes unchanged. Data representation of the partial update payload determines how the changes are transmitted between client and server and applied to the data object.
The client MAY send changes to any read-write attributes defined in the data model. The client MUST not send any create-only attributes.</t>
</li>
</ul>
<t>Both operations MUST be performed on a URL identifying a unique object instance (Rule 2). The request body MUST contain a valid object representation in the negotiated media type.</t>
<t>The server MUST respond with HTTP status code 200 (OK) and include the updated object representation in the response body.</t>
<t>Example full update request (PUT):</t>

<sourcecode type="http"><![CDATA[PUT /rpp/v1/domainNames/foo.example HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Content-Type: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
Content-Length: 252

TODO
]]>
</sourcecode>
<t>Example full update response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 80
Content-Type: application/rpp+json
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
RPP-code: 01000

TODO
]]>
</sourcecode>
<t>Example partial update request (PATCH):</t>

<sourcecode type="http"><![CDATA[PATCH /rpp/v1/domainNames/foo.example HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Content-Type: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
Content-Length: 252

TODO
]]>
</sourcecode>
<t>Example partial update response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 80
Content-Type: application/rpp+json
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
RPP-code: 01000

TODO
]]>
</sourcecode>
</section>

<section anchor="processes"><name>Processes</name>
<t>Each provisioning object may be related to one or more running processes, such as a transfer or renewal. Each process has its own data, distinct from the data of the provisioning object itself, and may be interacted with using its own set of operations.</t>
<t>All process resources MUST exist under the <tt>/{collection}/{id}/processes/{process-collection}</tt> path, where <tt>{process-collection}</tt> is derived per Rule 3.</t>

<section anchor="relation-to-object-representation"><name>Relation to object representation</name>
<t>A uniform interface operation MAY require process data in addition to the object representation data. How the process data is embedded in the request body MUST be defined in the corresponding representation specification.</t>
</section>

<section anchor="response-with-information-about-created-process"><name>Response with information about created process</name>
<t>When the server creates a process object as a side effect of the operation, it MUST signal this to the client as described in <xref target="process-signalling"></xref>.</t>
</section>

<section anchor="restore-resource"><name>Restore Resource</name>

<aside><t>TODO: this needs update once restoreProcess is defined in Data Objects</t>
</aside>
</section>

<section anchor="renew-resource"><name>Renew Resource</name>
<t>Renew is modelled as a Process Object with its own lifecycle. The <tt>renewProcess</tt> object identifier yields the <tt>renewProcesses</tt> collection segment per Rule 3.</t>
<t>The client MUST use the HTTP POST method to create a new renew process (Rule 4, <tt>create</tt>).</t>
<t>Not every object resource includes support for the renew command. The response MUST include the Location header for the created renew process resource.</t>
<t>Example Domain Renew request:</t>

<sourcecode type="http"><![CDATA[POST /rpp/v1/domainNames/foo.example/processes/renewProcesses HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Content-Type: application/rpp+json
RPP-Cltrid: ABC-12345
Accept-Language: en
Content-Length: 96

{
  "expiryDate": "2025-09-08",
  "renewalPeriod": {
    "unit": "y",
    "value": 1
  }
}
]]>
</sourcecode>
<t>Example Renew response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 201 Created
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Language: en
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
Content-Length: 85
Location: https://rpp.example/rpp/v1/domainNames/foo.example/processes/renewProcesses/XYZ-12345
Content-Type: application/rpp+json
RPP-code: 01000

{
  "expiryDate": "2026-09-08"
}
]]>
</sourcecode>
</section>

<section anchor="transfer-resource"><name>Transfer Resource</name>
<t>The Transfer operation manages the change of sponsoring client for a provisioned object. Transfer is modelled as a Process Object with its own lifecycle. The <tt>transferProcess</tt> object identifier yields the <tt>transferProcesses</tt> collection segment per Rule 3.</t>

<section anchor="start"><name>Start</name>
<t>The initiating client MUST use the HTTP POST method to create a new transfer process (Rule 4, <tt>create</tt>).</t>
<t>Example request not using object authorization:</t>

<sourcecode type="http"><![CDATA[POST /rpp/v1/domainNames/foo.example/processes/transferProcesses HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
Content-Length: 320

{
  "transferDir": "push",
  "gainingClientId": "ClientX"
}

]]>
</sourcecode>
<t>Example request using object authorization:</t>

<sourcecode type="http"><![CDATA[POST /rpp/v1/domainNames/foo.example/processes/transferProcesses HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
RPP-Cltrid: ABC-12345
RPP-Authorization: authinfo value=TXkgU2VjcmV0IFRva2Vu
Accept-Language: en
Content-Length: 320

{
    "transferDir": "pull"
}

]]>
</sourcecode>
<t>Example Transfer response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 201 Created
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Language: en
Content-Length: 182
Content-Type: application/rpp+json
Location: https://rpp.example/rpp/v1/domainNames/foo.example/processes/transferProcesses/latest
RPP-code: 01001

{
  "trStatus": "pending",
  "reqClientId": "ClientX",
  "actClientId": "ClientY",
  "requestDate": "2000-06-06T22:00:00.0Z",
  "actionDate": "2000-06-11T22:00:00.0Z",
  "exDate": "2002-09-08T22:00:00.0Z"
}
]]>
</sourcecode>
</section>

<section anchor="status"><name>Status</name>
<t>A transfer process resource may not exist when no transfer has been initiated for the specified object. The client MUST use the HTTP GET method and MUST NOT add content to the HTTP message body.</t>
<t>Example domain name Transfer Status request:</t>

<sourcecode type="http"><![CDATA[GET /rpp/v1/domainNames/foo.example/processes/transferProcesses/latest HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</sourcecode>
<t>Example Transfer Query response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 230
Content-Type: application/rpp+json
Content-Language: en
RPP-code: 01000

{
  "trStatus": "pending",
  "reqClientId": "ClientX",
  "actClientId": "ClientY",
  "requestDate": "2000-06-06T22:00:00.0Z",
  "actionDate": "2000-06-11T22:00:00.0Z",
  "exDate": "2002-09-08T22:00:00.0Z"
}
]]>
</sourcecode>
</section>

<section anchor="cancel"><name>Cancel</name>
<t>The initiating client cancels its pending transfer request using the DELETE method on the process resource (Rule 4, <tt>delete</tt>).</t>
<t>Example request:</t>

<sourcecode type="http"><![CDATA[DELETE /rpp/v1/domainNames/foo.example/processes/transferProcesses/latest HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</sourcecode>
<t>Example response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 80
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
RPP-code: 01000

{
  "trStatus": "clientCancelled",
  "reqClientId": "ClientX",
  "actClientId": "ClientY",
  "requestDate": "2000-06-06T22:00:00.0Z",
  "actionDate": "2000-06-11T22:00:00.0Z"
}
]]>
</sourcecode>
</section>

<section anchor="reject"><name>Reject</name>
<t>The currently sponsoring client rejects a pending transfer. This is an extended process operation; the operation identifier <tt>transferReject</tt> is used unchanged as the final path segment (Rule 5).</t>
<t>Example request:</t>

<sourcecode type="http"><![CDATA[POST /rpp/v1/domainNames/foo.example/processes/transferProcesses/latest/transferReject HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</sourcecode>
<t>Example response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 80
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
RPP-code: 01000

{
  "trStatus": "clientRejected",
  "reqClientId": "ClientX",
  "actClientId": "ClientY",
  "requestDate": "2000-06-06T22:00:00.0Z",
  "actionDate": "2000-06-11T22:00:00.0Z"
}

]]>
</sourcecode>
</section>

<section anchor="approve"><name>Approve</name>
<t>The currently sponsoring client approves a pending transfer. The operation identifier <tt>transferApprove</tt> is used unchanged as the final path segment (Rule 5).</t>
<t>Example request:</t>

<sourcecode type="http"><![CDATA[POST /rpp/v1/domainNames/foo.example/processes/transferProcesses/latest/transferApprove HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
Content-Length: 0

]]>
</sourcecode>
<t>Example response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 80
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
RPP-code: 01000

{
  "trStatus": "clientApproved",
  "reqClientId": "ClientX",
  "actClientId": "ClientY",
  "requestDate": "2000-06-06T22:00:00.0Z",
  "actionDate": "2000-06-11T22:00:00.0Z"
}
]]>
</sourcecode>
</section>
</section>
</section>

<section anchor="messages-1"><name>Messages</name>

<section anchor="retrieve"><name>Retrieve</name>

<aside><t>TODO: update when covered in data objects</t>
</aside>
<t>The messages endpoint is used for retrieving messages stored on the server for the client to process.</t>

<ul spacing="compact">
<li>Request: GET /messages</li>
<li>Request message: None</li>
<li>Response message: Poll response</li>
</ul>
<t>The client MUST use the HTTP GET method on the messages resource collection to request the message at the head of the queue.</t>
<t>Example request:</t>

<sourcecode type="http"><![CDATA[GET messages HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</sourcecode>
<t>Example response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Length: 312
Content-Type: application/rpp+json
Content-Language: en
RPP-code: 01301

TODO
]]>
</sourcecode>
</section>

<section anchor="delete"><name>Delete</name>

<aside><t>TODO: update when covered in data objects</t>
</aside>

<ul spacing="compact">
<li>Request: DELETE /messages/{id}</li>
<li>Request message: None</li>
<li>Response message: Poll Ack response</li>
</ul>
<t>The client MUST use the HTTP DELETE method to acknowledge receipt of a message from the queue. The &quot;msgID&quot; attribute of a received RPP Poll message MUST be included in the message resource URL, using the {id} path element. The server MUST use RPP headers to return the RPP result code and the number of messages left in the queue. The server MUST NOT add content to the HTTP message body of a successful response, the server may add content to the message body of an error response.</t>
<t>Example request:</t>

<sourcecode type="http"><![CDATA[DELETE messages/12345 HTTP/2
Host: rpp.example
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</sourcecode>
<t>Example response:</t>

<sourcecode type="http"><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Language: en
RPP-code: 01000
RPP-Queue-Size: 0
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
Content-Length: 145

TODO
]]>
</sourcecode>
</section>
</section>
</section>

<section anchor="extension-framework"><name>Extension Framework</name>
<t>TODO</t>
</section>

<section anchor="rpp-result-codes"><name>RPP Result Codes</name>
<t>RPP result codes are used to indicate the result of an RPP request. They are returned in the RPP-Code header of the HTTP response. The format of the RPP result code is a 5-digit string, where the first digit MUST always be &quot;1&quot;, the second digit indicates the class of the result, and the remaining four digits indicate the specific result within that class, his allows implementers to define more specific result codes within each class. The classes of RPP result codes are designed to match the classes of HTTP status codes, to facilitate mapping between RPP result codes and HTTP status codes. The classes of RPP result codes are defined as follows:</t>

<ul spacing="compact">
<li>11xxx: Informational</li>
<li>12xxx: Success</li>
<li>13xxx: Reserved for future use</li>
<li>14xxx: Client error</li>
<li>15xxx: Server error</li>
</ul>
<t>The following RPP result codes are defined and used in this document:</t>
<table>
<thead>
<tr>
<th>RPP Result Code</th>
<th>HTTP Status Code</th>
<th>Description</th>
</tr>
</thead>

<tbody>
<tr>
<td>12000</td>
<td>200 OK</td>
<td>Command completed successfully</td>
</tr>

<tr>
<td>12001</td>
<td>201 Created</td>
<td>Command completed successfully and a new resource was created</td>
</tr>
</tbody>
</table></section>

<section anchor="authentication-and-authorization"><name>Authentication and Authorization</name>
<t>Due to the stateless nature of RPP, the client MUST include the authentication credentials in each HTTP request. This MAY be done by using JSON Web Tokens (JWT) <xref target="RFC7519"></xref> or Basic authentication <xref target="RFC7617"></xref>. The server MUST validate the authentication credentials on each request and reject any request with invalid credentials with an appropriate HTTP status code.</t>
<t>When using JWTs for OAuth 2.0 <xref target="RFC6749"></xref> Access Tokens, the JWT profile described in <xref target="RFC9068"></xref> MUST be used. It is RECOMMENDED to use short-lived tokens and to implement token revocation mechanisms to mitigate the risk of token compromise. If sensitive information is included in the JWT payload, it MUST be encrypted to prevent unauthorized access when the token is persistent to a storage device. Furthermore, the best practices for JWT usage as outlined in <xref target="RFC8725"></xref> MUST be followed.</t>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>

<section anchor="urn-sub-namespace-for-rpp-urn-ietf-params-rpp"><name>URN Sub-namespace for RPP (urn:ietf:params:rpp)</name>
<t>The IANA is requested to add the following value to the &quot;IETF URN Sub-namespace for Registered Protocol Parameter Identifiers&quot; registry, following the template in <xref target="RFC3553"></xref>:
TODO: add filled in template, if we decide to use URN for profile identification, for example &quot;urn:ietf:params:rpp:profile:example-profile&quot;</t>

<sourcecode type="text"><![CDATA[Registry name: rpp 
Specification: This Document
Repository: ?
Index value: ?
]]>
</sourcecode>
</section>

<section anchor="rpp-registry-group"><name>RPP registry group</name>
<t>The IANA is requested to create a new registry group for RPP, this will be used to group together all the RPP-related registries such as those for discovery URLs, extensions and profiles.</t>

<sourcecode type="text"><![CDATA[Name of the registry: RESTful Provisioning Protocol (RPP)
Reference: This Document
IANA Registry Reference: TODO
]]>
</sourcecode>
</section>

<section anchor="rpp-discovery-registry"><name>RPP Discovery registry</name>
<t>The IANA is requested to create a new registry for RPP discovery URLs, this registry will be used to register the well-known URLs for RPP discovery endpoints, used by RPP clients to discover the capabilities of a RPP server.</t>

<sourcecode type="text"><![CDATA[Name of the registry: RPP Discovery URLs
Registry group: RESTful Provisioning Protocol (RPP)
Registration procedure: Expert Review
]]>
</sourcecode>
<t>Fields to be registered:</t>

<ul spacing="compact">
<li><tt>tld</tt>: The top-level domain (TLD) for which the discovery URL is applicable, for example &quot;example&quot;.</li>
<li><tt>url</tt>: The URL for the discovery endpoint, for example &quot;<eref target="https://rpp.example/.well-known/rpp.json&quot;">https://rpp.example/.well-known/rpp.json"</eref>.</li>
<li><tt>description</tt>: A human-readable description of the discovery URL and its intended use.</li>
</ul>
</section>

<section anchor="rpp-extension-registry"><name>RPP Extension registry</name>
<t>The IANA is requested to create a new registry for RPP extensions, this registry will be used to register standardized extensions to the RPP protocol. Extensions are defined as additional features or capabilities that can be added to the base RPP protocol, for example support for additional resource types, additional operations or additional authentication methods.</t>

<sourcecode type="text"><![CDATA[Name of the registry: RPP Extensions
Registry group: RESTful Provisioning Protocol (RPP)
Registration procedure: Expert Review
]]>
</sourcecode>
<t>Fields to be registered:</t>

<ul spacing="compact">
<li><tt>name</tt>: The name of the extension, for example &quot;RPP example extension&quot;.</li>
<li><tt>version</tt>: The version of the extension, for example &quot;1.0&quot;.</li>
<li><tt>url</tt>: The URL for the extension specification, for example &quot;<eref target="https://www.iana.org/assignments/rpp-extensions/rpp-example-extension-1.0&quot;">https://www.iana.org/assignments/rpp-extensions/rpp-example-extension-1.0"</eref>.</li>
<li><tt>description</tt>: A human-readable description of the extension and its intended use.</li>
</ul>
</section>

<section anchor="rpp-profile-registry"><name>RPP Profile registry</name>
<t>The IANA is requested to create a new registry for RPP profiles, this registry will be used to register standardized profiles for the RPP protocol. Profiles are defined as specific configurations of the RPP protocol that are designed to meet the needs of specific use cases or environments, for example an EPP compatibility profile that defines a set of RPP features and behaviors that are compatible with the Extensible Provisioning Protocol (EPP) <xref target="RFC5730"></xref>.</t>

<sourcecode type="text"><![CDATA[Name of the registry: RPP Profiles
Registry group: RESTful Provisioning Protocol (RPP)
Registration procedure: Expert Review
]]>
</sourcecode>
<t>Fields to be registered:</t>

<ul spacing="compact">
<li><tt>name</tt>: The name of the profile, for example &quot;EPP compatibility profile&quot;.</li>
<li><tt>id</tt>: A unique URN identifier for the profile, for example &quot;urn:ietf:params:rpp:profile:epp-compatibility-1.0&quot;.</li>
<li><tt>version</tt>: The version of the profile, for example &quot;1.0&quot;.</li>
<li><tt>url</tt>: The URL for the profile specification, for example &quot;<eref target="https://www.iana.org/assignments/rpp-profiles/epp-compatibility-provisioning-profile-1.0&quot;">https://www.iana.org/assignments/rpp-profiles/epp-compatibility-provisioning-profile-1.0"</eref>.</li>
<li><tt>description</tt>: A human-readable description of the profile and its intended use.</li>
</ul>
</section>

<section anchor="rpp-result-codes-registry"><name>RPP Result Codes Registry</name>
<t>The IANA is requested to create a new registry &quot;RPP Result codes&quot;, this registry will be used to register RPP result codes defined in this document and in future RPP specifications and extensions.</t>

<sourcecode type="text"><![CDATA[Name of the registry: RPP Result codes
Registry group: RESTful Provisioning Protocol (RPP)
Registration procedure: Expert Review
]]>
</sourcecode>
<t>Fields to be registered:</t>

<ul spacing="compact">
<li><tt>code</tt>: The RPP result code, for example &quot;12000&quot;.</li>
<li><tt>description</tt>: A human-readable description of the result code and its intended use.</li>
</ul>
</section>

<section anchor="link-relation-type-rpp-process"><name>Link Relation Type: rpp-process</name>
<t>The IANA is requested to register the following link relation type in the &quot;Link Relation Types&quot; registry, following the template in <xref target="RFC8288"></xref>:</t>

<sourcecode type="text"><![CDATA[Relation Name: rpp-process
Description:   Identifies a process resource that was implicitly created as a
               side effect of a uniform interface operation on the target
               resource.  The context resource is the provisioning object on
               which the operation was performed; the target resource is the
               created process instance.  The following target attributes are
               defined for this relation type: "process" (the Process Object
               Identifier, REQUIRED), "processId" (the server-assigned process
               instance identifier, OPTIONAL), and "latest" (the boolean value
               "true", OPTIONAL, indicating the target URL uses the "latest"
               mnemonic).
Reference:     This document
]]>
</sourcecode>
</section>

<section anchor="rpp-media-type-application-rpp-json"><name>RPP Media Type (application/rpp+json)</name>
<t>The IANA is requested to add the following RPP media type to the &quot;Media Types&quot; registry, following the template in <xref target="RFC6838"></xref>:</t>

<sourcecode type="text"><![CDATA[Type name: application
Subtype name: rpp+json
Required parameters: version
Optional parameters: "N/A"
Encoding considerations: "N/A"
Security considerations: "N/A"
Interoperability considerations: "N/A"
Published specification: This document
Applications that use this media type: RPP protocol and extensions
Fragment identifier considerations: "N/A"
Additional information: "N/A"
Person & email address to contact for further information: Author's email address
Intended usage: COMMON
Restrictions on usage: "N/A"
Author: Document authors
Change controller: Document authors
Provisional registration: No
]]>
</sourcecode>
</section>
</section>

<section anchor="internationalization-considerations"><name>Internationalization Considerations</name>
<t>TODO</t>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>
<t>RPP relies on the security of the underlying HTTP transport, hence the best common practices for securing HTTP described in <xref target="RFC9325"></xref> also apply to RPP and MUST be followed by RPP implementations.</t>
<t>Data confidentiality and integrity MUST be enforced. Every client and server interaction MUST be encrypted using TLS version 1.3 <xref target="RFC8446"></xref>. Future versions of TLS MAY be used as they become available and are deemed secure.</t>
</section>

<section anchor="change-history"><name>Change History</name>

<section anchor="version-draft-wullink-rpp-core-05-to-draft-ietf-rpp-core-00"><name>Version draft-wullink-rpp-core-05 to draft-ietf-rpp-core-00</name>

<ul spacing="compact">
<li>Renamed the document name to &quot;draft-ietf-rpp-core&quot; and reset version number to 00 (Issue #80)</li>
<li>Added Organisation and User resource type, with create, read, update and delete operations. (Issue #67)</li>
<li>Added section about Mapping to EPP. (Issue #55)</li>
<li>Described full and partial update operations, using HTTP PUT and PATCH methods respectively. (Issue #21)</li>
<li>Added support for embedding process data in uniform interface operations. Registered the <tt>rpp-process</tt> link relation type with IANA.</li>
<li>Generalised process sub-resource URL derivation into Rule 3 (Direct Access Sub-Resource Path Segment); Rules 4 through 6 now apply this general rule to Process Objects instead of deriving process paths independently.</li>
<li>Corrected the Renew process collection segment from <tt>renewalProcesses</tt> to <tt>renewProcesses</tt> in the Renew Resource section and the Derived Endpoint Reference table, matching the <tt>renewProcess</tt> identifier in <xref target="I-D.ietf-rpp-data-objects"></xref>.</li>
<li>Aligned the URL template variables in Discoverability with Unique Identifier terminology from <xref target="I-D.ietf-rpp-data-objects"></xref> and with the <tt>{process-collection}</tt>/<tt>{process-id}</tt> naming used in the Endpoints section; removed the unused <tt>process_name</tt> variable.</li>
</ul>
</section>

<section anchor="version-04-to-05"><name>Version 04 to 05</name>

<ul spacing="compact">
<li>Added Bootstrap and Discovery sections to the document, describing how a client can discover the location and capabilities of an RPP server</li>
<li>Added IANA Considerations section with a request for new RPP discovery URLs, extensions and profile URLs.</li>
</ul>
</section>

<section anchor="version-03-to-04"><name>Version 03 to 04</name>

<ul spacing="compact">
<li>Added a new section on versioning, describing how versioning is applied to different RPP elements. (Issue #39)</li>
<li>Added IANA request for RPP Result codes registry, and added a table with example RPP result codes. (Issue #39)</li>
<li>Added IANA request for URN sub-namespace for RPP. (Issue #39)</li>
<li>Added a new &quot;Profiles&quot; section to describe how to define and use profiles. (Issue #43)</li>
<li>Added a new section &quot;Authentication and Authorization&quot;. (Issue #37)</li>
<li>Updated the &quot;Security Considerations&quot; section to include transport security. (Issue #37)</li>
<li>Added IANA registration request for the new RPP media type. (Issue #40)</li>
</ul>
</section>

<section anchor="version-02-to-03"><name>Version 02 to 03</name>

<ul spacing="compact">
<li>Added use of Problem Detail <xref target="RFC9457"></xref> for error responses</li>
</ul>
</section>

<section anchor="version-01-to-02"><name>Version 01 to 02</name>

<ul spacing="compact">
<li>Updated the examples, changed from &quot;<em>.example.org&quot; to &quot;</em>.example&quot;</li>
<li>Merged the RPP-EPP-Code and RPP-Code headers into a single RPP-Code header</li>
<li>Update the RPP-Authorization header to match the HTTP Authorization header format</li>
<li>Added new process path segment and process representations</li>
<li>Updated the Check request to now use an &quot;availability&quot; path segment and support both GET and HEAD methods</li>
</ul>
</section>

<section anchor="version-00-to-01"><name>Version 00 to 01</name>

<ul spacing="compact">
<li>Updated &quot;Request Headers&quot; and &quot;Response Headers&quot; section</li>
<li>Changed transfer resource URL and HTTP method for reject, approve and cancel, in order to make the API easier to use</li>
</ul>
</section>

<section anchor="version-00-draft-rpp-core-to-00-draft-wullink-rpp-core"><name>Version 00 (draft-rpp-core) to 00 (draft-wullink-rpp-core)</name>

<ul spacing="compact">
<li>Renamed the document name to &quot;draft-wullink-rpp-core&quot;</li>
<li>Removed sections: Design Considerations, Resource Naming Convention, Session Management, HTTP Layer, Content Negotiation, Object Filtering, Error Handling</li>
<li>Renamed Commands section to Endpoints</li>
<li>Removed text about extensions</li>
<li>Changed naming to be less EPP like and more RDAP like</li>
</ul>
</section>
</section>

<section anchor="acknowledgements"><name>Acknowledgements</name>
<t>The authors would like to thank the following people for their helpful text contributions, comments and suggestions.</t>

<ul spacing="compact">
<li>Q Misell, AS207960 Cyfyngedig</li>
</ul>
</section>

</middle>

<back>
<references><name>References</name>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-rpp-data-objects.xml"/>
<reference anchor="REST" target="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">
  <front>
    <title>Architectural Styles and the Design of Network-based Software Architectures</title>
    <author fullname="Roy Fielding" initials="R." surname="Fielding">
      <organization></organization>
    </author>
    <date year="2000"></date>
  </front>
</reference>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2616.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2782.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3553.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5730.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5731.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5733.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6570.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6648.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6749.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6838.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7519.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7617.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8288.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8446.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8725.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8941.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9068.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9205.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9325.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9457.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9460.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9535.xml"/>
<reference anchor="SemVer" target="https://semver.org/">
  <front>
    <title>Semantic Versioning 2.0.0</title>
    <author>
      <organization>Semantic Versioning</organization>
    </author>
  </front>
</reference>
</references>
<references><name>Informative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8748.xml"/>
</references>
</references>

</back>

</rfc>
