<?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-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-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/>
<area>Internet</area>
<workgroup>Network Working Group</workgroup>

<abstract>
<t>This document describes a HTTP-based protocol 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>RPP is data format agnostic, this document describes a framework describing protocol messages in any data format.
the client uses server-driven content negotiation. Allowing the client to select from a set of representation media types supported by the server, such as JSON <xref target="RFC8259"></xref>, XML or <xref target="YAML"></xref>.</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>EPP RFCs - This is a reference to the EPP version 1.0 specifications <xref target="RFC5730"></xref>, <xref target="RFC5731"></xref>, <xref target="RFC5732"></xref> and <xref target="RFC5733"></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>
</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, lines starting with &quot;C:&quot; represent data sent by a RPP client and lines starting with &quot;S:&quot; represent data returned by a RPP server. 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 rppp.example.nl. 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="design-considerations"><name>Design Considerations</name>
<t>RPP is designed to improve the ease of design, development, deployment, and management of an provisioning service. This section lists the main design criteria.</t>

<ul>
<li><t>Ease of use, provide a clear, clean, easy to use and self-explanatory interface that can easily be integrated into existing software systems. Based on these principles a <xref target="REST"></xref> architectural style was chosen, where a client  interacts with a RPP server via HTTP.</t>
</li>
<li><t>Scalability, HTTP allows the use of well know mechanisms for creating scalable systems, such as load balancing. Load balancing at the level of request messages is more efficient compared to load balancing based on TCP sessions. When using EPP over TCP, the TCP session can be used to transmit multiple request messages and these are then all processed by a single EPP server and not load balanced across a pool of available servers. During normal registry operations, the bulk of EPP requests can be expected to be of the informational type, load balancing and possibly separating these to dedicated compute resources may also improve registry services and provide better performance for the transform request types.</t>
</li>
<li><t>Stateless, <xref target="RFC5730"></xref> REQUIRES a stateful session between a client and server. A RPP server MUST be stateless and MUST NOT keep client session or any other application state. Each client request needs to provide all the information necessary for the server to successfully process the request.</t>
</li>
<li><t>Security, allow for the use of authentication and authorization solutions available for HTTP based applications. HTTP provides an Authorization header <xref target="RFC2616" sectionFormat="of" section="14.8"></xref>.</t>
</li>
<li><t>Content negotiation, A server may choose to include support for multiple media types.
The client must be able to signal to the server what media type the server should expect for the request content and to use for the response content.</t>
</li>
<li><t>Compatibility with existing EPP semantics defined in the EPP RFCs.</t>
</li>
<li><t>Simplicity, when the semantics of a resource URL and HTTP method match an EPP command and request message, the use of a request message should be optional.</t>
</li>
<li><t>Performance, reducing the number of required request and response messages, improves the performance and network bandwidth requirements for both client and server. Not every request will require a message to be created, marshalled, and transmitted.</t>
</li>
</ul>
</section>

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

<section anchor="resource-naming-convention"><name>Resource Naming Convention</name>
<t>The naming convention SHOULD follow best practices defined for RESTful APIs, where the resource name should be a noun.
A RPP resource can be a single unique object identifier e.g. a domain name or consist out of a collection of objects. A collection of objects available for registry operations MUST be identified by: <tt>/{context-root}/{version}/{collection}</tt></t>

<ul>
<li><t><tt>{context-root}</tt> is the base URL which MUST be specified, the {context-root} MAY be an empty, zero length string.</t>
</li>
<li><t><tt>{version}</tt> is a path segment which identifies the version of the RPP implementation.
</t>
</li>
<li><t><tt>{collection}</tt> MUST be substituted by all collection of objects, e.g. &quot;domains&quot;, &quot;hosts&quot; or &quot;contacts&quot; or other supported objects.</t>
</li>
</ul>
<t>A trailing slash MAY be added to each request. Implementations MUST consider requests which only differ with respect to this trailing slash as identical.</t>
<t>A specific RPP object instance MUST be identified by {context-root}/ {version}/{collection}/{id}</t>
<t>An example domain name resource for domain name example.nl is encoded into the following URL:</t>
<t><tt>/rpp/v1/domains/example.nl</tt></t>
<t>The path segment after a collection path segment MUST be used to identify an object instance, the path segment after an object instance MUST be used to identify attributes or related collections linked to the object instance.</t>
</section>

<section anchor="session-management"><name>Session Management</name>
<t>One of the main design considerations for RPP is to enable scalable EPP services, for this reason the RPP uses a stateless architecture and does not create and maintain client sessions. The Session concept is an anti-pattern in the context of a stateless service, the server MUST NOT maintain any state information relating to the client or RPP transaction.</t>
<t>Session management as described in <xref target="RFC5730"></xref> requires a stateful server architecture for maintaining client and application state over multiple client request and is therefore no longer supported.</t>
<t>A RPP request MUST contain all information required for the server to be able to successfully process the request. The client MUST include authentication credentials for each request. This MAY be done by using any of the available HTTP authentication mechanisms, such as those described in <xref target="RFC2617"></xref>.</t>
</section>

<section anchor="rest"><name>HTTP Layer</name>
<t>RPP uses the REST architectural style, each HTTP method is assigned a distinct behavior, requests are expressed by a URL referring to a resource, a HTTP method, HTTP headers and an optional message body containing the request message.</t>
<t>A RPP HTTP message body MUST contain at most a single request or response. HTTP requests MUST be processed independently of each other and in the same order as received by the server. A client MAY choose to send a new request, using an existing connection, before the response for the previous request has been received (pipelining). A server using HTTP/2 <xref target="RFC7540"></xref> or HTTP/3 <xref target="RFC9114"></xref> contains built-in support for stream multiplexing and MAY choose to support pipelining using this mechanism. The response MAY be returned out of order to the client, because some requests may require more processing time.</t>
<t>HTTP/1 does not use persistent connections by default, the client MAY use the &quot;Connection&quot; header to request for the server not to close the existing connection, so it can be re-used for future requests. The server MAY choose not to honor this request.</t>

<section anchor="content-negotiation"><name>Content negotiation</name>
<t>The server MAY choose to support multiple data formats for object representations, such as JSON or YAML.
The client and server MUST support server-driven content negotiation and related HTTP headers for content negotiation, as described in <xref target="RFC2616" sectionFormat="of" section="12.2"></xref>.</t>
<t>The client MUST use the following HTTP headers:</t>

<ul spacing="compact">
<li><tt>Content-Type</tt>: Used to indicate the media type for the content in the message body</li>
<li><tt>Accept</tt>: Used to indicate the media type the server MUST use for the representation of objects, this MAY
       be a list of types and related weight factors, as described in <xref target="RFC2616" sectionFormat="of" section="14.1"></xref></li>
</ul>
<t>The client MUST synchronize the value for the Content-Type and Accept headers, for example a client MUST NOT send an JSON formatted request message to the server, while at the same time requesting a YAML formatted response message. The server MUST use the <tt>Content-Type</tt> HTTP header to indicate the media type used for the representation in the response message body. The server MUST return HTTP status code 406 (Not Acceptable) or 415 (Unsupported Media Type) when the client requests an unsupported media type.</t>
</section>

<section anchor="request"><name>Request</name>
<t>In contrast to EPP over TCP <xref target="RFC5734"></xref>, 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 for most commands. However, the client MUST include the request message in the HTTP request 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>
<t><strong>TODO:</strong> the non standard headers mentioned below are linked to EPP and may need to be removed or modified</t>

<ul>
<li><t><tt>RPP-Cltrid</tt>:  The client transaction identifier is the equivalent of the <tt>clTRID</tt> element defined in <xref target="RFC5730"></xref> and MUST be used accordingly, when the HTTP message body does not contain an EPP request that includes a cltrid.</t>
</li>
<li><t><tt>RPP-AuthInfo</tt>: The client MAY use this header for sending basic token-based authorization information, as described in <xref target="RFC5731" sectionFormat="of" section="2.6"></xref> and <xref target="RFC5733" sectionFormat="of" section="2.8"></xref>. If the authorization is linked to a contact object then the client MUST also include the RPP-Roid header.</t>
</li>
<li><t><tt>RPP-Roid</tt>: If the authorization info, is linked to a database object, the client MAY use this header for the Repository Object IDentifier (ROID), as described in <xref target="RFC5730" sectionFormat="of" section="4.2"></xref>.</t>
</li>
<li><t><tt>Accept-Language</tt>: The server MUST support the use of HTTP Accept-Language header by clients. The client MAY issue a Hello request to discover the languages supported by the server. Multiple servers in a load-balanced environment SHOULD reply with consistent &quot;lang&quot; elements in the Greeting response. The value of the Accept-Language header MUST match 1 of the languages from the Greeting. When the server receives a request using an unsupported language, the server MUST respond using the default language configured for the server.</t>
</li>
<li><t><tt>Connection</tt>: If the server uses HTTP/1.1 or lower, the client MAY choose to use this header to request the server to keep op the TCT-connection. The client MUST not use this header when the server uses HTTP/2 <xref target="RFC9113" sectionFormat="of" section="8.2.2"></xref> or HTTP/3 <xref target="RFC9113" sectionFormat="of" section="4.2"></xref></t>
</li>
<li><t><tt>Accept-Encoding</tt>: The client MAY choose to use the Accept-Encoding HTTP header to request the server to use compression for the response message body.</t>
</li>
</ul>
</section>

<section anchor="response"><name>Response</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>
<t><strong>TODO:</strong> the non standard headers mentioned below are linked to EPP and may need to be removed.</t>

<ul>
<li><t><tt>RPP-Svtrid</tt>:  This header is the equivalent of the &quot;svTRID&quot; element defined in <xref target="RFC5730"></xref> and MUST be used accordingly when the RPP response does not contain an EPP response in the HTTP message body. If an HTTP message body with the EPP XML equivalent &quot;svTRID&quot; exists, both values MUST be consistent.</t>
</li>
<li><t><tt>RPP-Cltrid</tt>: This header is the equivalent of the &quot;clTRID&quot; element defined in <xref target="RFC5730"></xref> and MUST be used accordingly when the RPP response does not contain an EPP response in the HTTP message body. If the contents of the HTTP message body contains a &quot;clTRID&quot; value, then both values MUST be consistent.</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, except for the Greeting, and MAY be used by the client for easy access to the EPP result code, without having to parse the content of the HTTP response message body.</t>
</li>
<li><t><tt>RPP-Check-Avail</tt>: An alternative for the &quot;avail&quot; attribute of the object:name element in an Object Check response and MUST be used accordingly. The server does not return a HTTP message body in response to a RPP Object Check request.</t>
</li>
<li><t><tt>RPP-Check-Reason</tt>: An optional alternative for the &quot;object:reason&quot; element in an Object Check response and MUST be used accordingly.</t>
</li>
<li><t><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.
</t>
</li>
<li><t><tt>Cache-Control</tt>:  The client MUST never cache results, the server MUST always return the value &quot;No-Store&quot; for this header, as described in <xref target="RFC7234" sectionFormat="of" section="5.2.1.5"></xref>.
</t>
</li>
<li><t><tt>Content-Language</tt>: The server MUST include this header in every response that contains an EPP message in the message body.</t>
</li>
<li><t><tt>Content-Encoding</tt>: The server MAY choose to compress the responses message body, using an   algorithm selected from the list of algorithms provided by the client using the Accept-Encoding request header.</t>
</li>
</ul>
<t>RPP does not always return an response in the HTTP message body. The <tt>Object Check</tt> request for example may return an empty HTTP response body. When the server does not return an EPP message, it MUST return at least the RPP-Svtrid, RPP-Cltrid and RPP-code headers.</t>
</section>

<section anchor="error-handling"><name>Error Handling</name>
<t>RESTful Provisioning Protocol and HTTP protocol are both an application layer protocol, having their own status- and result codes and the server MUST NOT mix these two distinct codes.</t>
</section>
</section>

<section anchor="command-mapping"><name>Commands</name>
<t>A RPP command contains 4 distinct elements.</t>

<ol spacing="compact">
<li>Resource defined by a URL</li>
<li>HTTP method to be used on the resource</li>
<li>Request message (Optional)</li>
<li>Response message (Optional)</li>
</ol>
<t><xref target="tbl-cmd-mapping"></xref> lists an overview of RPP commands, the subsequent sections provide details for each command. Resource URLs in the table are assumed to be using the prefix: &quot;/{context-root}/{version}/&quot;. Some RPP endpoints do not require a request and/or response message, as is indicated by the table columns &quot;Request&quot; and &quot;response&quot;.</t>

<ul spacing="compact">
<li><tt>{c}</tt>:  An abbreviation for {collection}: this MUST be substituted with
&quot;domains&quot;, &quot;hosts&quot;, &quot;contacts&quot; or any other collection of objects.</li>
<li><tt>{i}</tt>:  An abbreviation for an object id, this MUST be substituted with the value of a domain name, hostname, contact-id or a message-id or any other defined object.</li>
<li><tt>Optional</tt>: A request message is only required when the server requires additional data not avaliable otherwise.</li>
</ul>
<t anchor="tbl-cmd-mapping">Command            | Method   | Resource                  | Request     | Response</t>
<table><name>RPP Commands
</name>
<tbody>
<tr>
<td>Check</td>
<td>HEAD</td>
<td>/{c}/{i}</td>
<td>No</td>
<td>No</td>
</tr>

<tr>
<td>Info</td>
<td>GET</td>
<td>/{c}/{i}</td>
<td>Optional</td>
<td>Yes</td>
</tr>

<tr>
<td>Poll Request</td>
<td>GET</td>
<td>/messages</td>
<td>No</td>
<td>Yes</td>
</tr>

<tr>
<td>Poll Ack</td>
<td>DELETE</td>
<td>/messages/{i}</td>
<td>No</td>
<td>Yes</td>
</tr>

<tr>
<td>Create</td>
<td>POST</td>
<td>/{c}</td>
<td>Yes</td>
<td>Yes</td>
</tr>

<tr>
<td>Delete</td>
<td>DELETE</td>
<td>/{c}/{i}</td>
<td>Optional</td>
<td>Yes</td>
</tr>

<tr>
<td>Renew</td>
<td>POST</td>
<td>/{c}/{i}/renewal</td>
<td>Optional</td>
<td>Yes</td>
</tr>

<tr>
<td>Transfer Request</td>
<td>POST</td>
<td>/{c}/{i}/transfer</td>
<td>Optional</td>
<td>Yes</td>
</tr>

<tr>
<td>Transfer Query</td>
<td>GET</td>
<td>/{c}/{i}/transfer</td>
<td>Optional</td>
<td>Yes</td>
</tr>

<tr>
<td>Transfer Cancel</td>
<td>DELETE</td>
<td>/{c}/{i}/transfer</td>
<td>Optional</td>
<td>Yes</td>
</tr>

<tr>
<td>Transfer Approve</td>
<td>PUT</td>
<td>/{c}/{i}/transfer</td>
<td>Optional</td>
<td>Yes</td>
</tr>

<tr>
<td>Transfer Reject</td>
<td>DELETE</td>
<td>/{c}/{i}/transfer</td>
<td>Optional</td>
<td>Yes</td>
</tr>

<tr>
<td>Update</td>
<td>PATCH</td>
<td>/{c}/{i}</td>
<td>Yes</td>
<td>Yes</td>
</tr>

<tr>
<td>Extension [1]</td>
<td>*</td>
<td>/{c}/{i}/extension/*</td>
<td>*</td>
<td>*</td>
</tr>
</tbody>
</table><t>[1] This mapping is used as a placeholder for future extensions</t>

<section anchor="query-resources"><name>Query Resources</name>
<t>A RPP client MAY use the HTTP GET method for executing a query command only when no request data has to be added to the HTTP message body. Sending content using an HTTP GET request is discouraged in <xref target="RFC9110"></xref>, there exists no generally defined semantics for content received in a GET request. When an RPP object requires additional information, the client MUST use the HTTP POST method and add the query command content to the HTTP message body.</t>

<section anchor="check"><name>Check</name>

<ul spacing="compact">
<li>Request: HEAD /{collection}/{id}</li>
<li>Request message: None</li>
<li>Response message: None</li>
</ul>
<t><strong>TODO</strong>: allow more more finegrained status response from a check, not just 0 or 1</t>
<t>The HTTP HEAD method MUST be used for object existence check. The response MUST contain the <tt>RPP-Check-Avail</tt> header and MAY contain the <tt>RPP-Check-Reason</tt> header. The value of the <tt>RPP-Check-Avail</tt> header MUST be &quot;0&quot; or &quot;1&quot;, depending on whether the object can be provisioned or not.</t>
<t>The Check endpoint MUST be limited to checking only a single object-id per request, to allow the server to effiently load balance requests.</t>
<t>Example request for a domain name:</t>

<artwork><![CDATA[HEAD /rpp/v1/domains/example.nl HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept-Language: en
RPP-Cltrid: ABC-12345

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

<artwork><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
RPP-Cltrid: ABC-12345
RPP-Svtrid: XYZ-12345
RPP-Check-Avail: 0
RPP-Check-Reason: In use
RPP-result-code: 1000
Content-Length: 0

]]>
</artwork>
</section>

<section anchor="info"><name>Info</name>
<t>The Object Info request MUST use the HTTP GET method on a resource identifying an object instance, using an empty message body. If the object has authorization information attached and the authorization then the client MUST include the RPP-AuthInfo HTTP header. If the authorization is linked to a database object the client MUST include the RPP-Roid header.</t>
<t>Example request for an object not using authorization information.</t>

<ul spacing="compact">
<li>Request: GET /{collection}/{id}</li>
<li>Request message: Optional</li>
<li>Response message: Info response</li>
</ul>

<artwork><![CDATA[GET /rpp/v1/domains/example.nl HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</artwork>
<t>Example request using RPP-AuthInfo header for an object that has attached authorization information.</t>

<ul spacing="compact">
<li>Request: GET /{collection}/{id}</li>
<li>Request message: Optional</li>
<li>Response message: Info response</li>
</ul>

<artwork><![CDATA[GET /rpp/v1/domains/example.nl HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
RPP-AuthInfo: secret-token
RPP-Roid: REG-XYZ-12345

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

<artwork><![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: 1000

TODO
]]>
</artwork>

<section anchor="object-filtering"><name>Object Filtering</name>
<t>
The server MUST support the use of the <tt>filter</tt> and <tt>val</tt> query parameters for the purpose of limiting the number of objects in a response.</t>

<ul spacing="compact">
<li><tt>filter</tt>: The attribute or field name to apply the filter on</li>
<li><tt>val</tt>: The value used for filtering</li>
</ul>
<t>The Domain Name Mapping <xref target="RFC5731" sectionFormat="bare" section="Section 3.1.2"></xref> describes an optional &quot;hosts&quot; attribute for the Domain Info command. This attribute may be used for filtering hosts returned in the Info response, and is mapped to the <tt>filter</tt> and <tt>val</tt> query parameters. If the filtering query parameters are absent from the request URL, the server MUST use the default filter value described in the corresponding EPP RFCs.</t>
<t>URLs used for filtering based on <tt>hosts</tt> attribute for Domain Info request:</t>

<ul spacing="compact">
<li>default: GET /domains/{id}</li>
<li>all: GET /domains/{id}?filter=hosts&amp;val=all</li>
<li>del: GET /domains/{id}?filter=hosts&amp;val=del</li>
<li>sub: GET /domains/{id}?filter=hosts&amp;val=sub</li>
<li>none: GET /domains/{id}?filter=hosts&amp;val=none</li>
</ul>
<t>Example Domain Info request, the response should only include delegated hosts:</t>

<artwork><![CDATA[GET /rpp/v1/domains/example.nl?filter=hosts&val=del HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</artwork>
</section>
</section>

<section anchor="poll"><name>Poll</name>

<section anchor="poll-request"><name>Poll Request</name>

<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>

<artwork><![CDATA[GET /rpp/v1/messages HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

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

<artwork><![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: 1301

TODO
]]>
</artwork>
</section>

<section anchor="poll-ack"><name>Poll Ack</name>

<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>

<artwork><![CDATA[DELETE /rpp/v1/messages/12345 HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

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

<artwork><![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: 1000
RPP-Queue-Size: 0
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
Content-Length: 145

TODO
]]>
</artwork>
</section>
</section>

<section anchor="transfer-query"><name>Transfer Query</name>
<t>A transfer object 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>

<ul spacing="compact">
<li>Request: GET {collection}/{id}/transfer</li>
<li>Request message: Optional</li>
<li>Response message: Transfer Query response</li>
</ul>
<t>Example domain name Transfer Query request without authorization information required:</t>

<artwork><![CDATA[GET /rpp/v1/domains/example.nl/transfer HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</artwork>
<t>If the requested object has associated authorization information that is not linked to another database object, then the HTTP GET method MUST be used and the authorization information MUST be included using the RPP-AuthInfo header.</t>
<t>Example domain name Transfer Query request using RPP-AuthInfo header:</t>

<artwork><![CDATA[GET /rpp/v1/domains/example.nl/transfer HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
RPP-AuthInfo: secret-token

]]>
</artwork>
<t>If the requested object has associated authorization information linked to another database object, then the HTTP GET method MUST be used and both the RPP-AuthInfo and the RPP-Roid header MUST be included.</t>
<t>Example domain name Transfer Query request and authorization using RPP-AuthInfo and the RPP-Roid header:</t>

<artwork><![CDATA[GET /rpp/v1/domains/example.nl/transfer HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-AuthInfo: secret-token
RPP-Roid: REG-XYZ-12345
Content-Length: 0

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

<artwork><![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: 1000

TODO
]]>
</artwork>
</section>
</section>

<section anchor="transform-resources"><name>Transform Resources</name>

<section anchor="create"><name>Create</name>

<ul spacing="compact">
<li>Request: POST /{collection}</li>
<li>Request message: Object Create request</li>
<li>Response message: Object Create response</li>
</ul>
<t>The client MUST use the HTTP POST method to create a new object resource. If the RPP request results in a newly created object, then the server MUST return HTTP status code 200 (OK). The server MUST add the &quot;Location&quot; header to the response, the value of this header MUST be the URL for the newly created resource.</t>
<t>Example Domain Create request:</t>

<artwork><![CDATA[POST /rpp/v1/domains HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Content-Type: application/rpp+json
Accept-Language: en
Content-Length: 220

TODO
]]>
</artwork>
<t>Example Domain Create response:</t>

<artwork><![CDATA[HTTP/2 200
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.nl/rpp/v1/domains/example.nl
RPP-code: 1000

TODO
]]>
</artwork>
</section>

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

<ul spacing="compact">
<li>Request: DELETE /{collection}/{id}</li>
<li>Request message: Optional</li>
<li>Response message: Status</li>
</ul>
<t>The client MUST the HTTP DELETE method and a resource identifying a unique object instance. The server MUST return HTTP status code 200 (OK) if the resource was deleted successfully.</t>
<t>Example Domain Delete request:</t>

<artwork><![CDATA[DELETE /rpp/v1/domains/example.nl HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

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

<artwork><![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: 1000

TODO
]]>
</artwork>
</section>

<section anchor="renew"><name>Renew</name>

<ul spacing="compact">
<li>Request: POST /{collection}/{id}/renewal</li>
<li>Request message: Optional</li>
<li>Response message: Renew response</li>
</ul>
<t>Not all EPP object types include support for the renew command. The current-date query parameter MAY be used for date on which the current validity period ends, as described in <xref target="RFC5731" sectionFormat="of" section="3.2.3"></xref>. The new period MAY be added to the request using the unit and value request parameters. The response MUST include the Location header for the renewed object.</t>
<t>Example Domain Renew request:</t>

<artwork><![CDATA[POST /rpp/v1/domains/example.nl/renewal?current-date=2024-01-01 HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Content-Type: application/rpp+json
Accept-Language: en
Content-Length: 0

]]>
</artwork>
<t>Example Domain Renew request, using 1 year period:</t>

<artwork><![CDATA[POST /rpp/v1/domains/example.nl/renewal?current-date=2024-01-01?unit=y&value=1 HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Content-Type: application/rpp+json
Accept-Language: en
Content-Length: 0

]]>
</artwork>
<t>Example Renew response:</t>

<artwork><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Language: en
Content-Length: 205
Location: https://rpp.example.nl/rpp/v1/domains/example.nl
Content-Type: application/rpp+json
RPP-code: 1000

TODO
]]>
</artwork>
</section>

<section anchor="transfer"><name>Transfer</name>
<t>The Transfer command is mapped to a nested resource, named &quot;transfer&quot;. The semantics of the HTTP DELETE method are determined by the role of the client executing the DELETE method. The DELETE method is defined as &quot;reject transfer&quot; for the current sponsoring client of the object. For the new sponsoring client the DELETE method is defined as &quot;cancel transfer&quot;.</t>
<t><strong>TODO:</strong> allow for alternative more client friendly methods for transferring objects, maybe use interactive oauth2.0 flows?</t>

<section anchor="request-1"><name>Request</name>

<ul spacing="compact">
<li>Request: POST /{collection}/{id}/transfer</li>
<li>Request message: Optional</li>
<li>Response message: Status</li>
</ul>
<t>In order to initiate a new object transfer process, the client MUST use the HTTP POST method on a unique resource to create a new transfer resource object. Not all RPP objects support the Transfer command.</t>
<t>If the transfer request is successful, then the response MUST include the Location header for the object being transferred.</t>
<t>Example request not using object authorization:</t>

<artwork><![CDATA[POST /rpp/v1/domains/example.nl/transfer HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
Content-Length: 0

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

<artwork><![CDATA[POST /rpp/v1/domains/example.nl/transfer HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
RPP-Cltrid: ABC-12345
RPP-AuthInfo: secret-token
Accept-Language: en
Content-Length: 0

]]>
</artwork>
<t>Example request using 1 year renewal period, using the <tt>unit</tt> and <tt>value</tt> query parameters:</t>

<artwork><![CDATA[POST /rpp/v1/domains/example.nl/transfer?unit=y&value=1 HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
Content-Length: 0

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

<artwork><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Language: en
Content-Length: 328
Content-Type: application/rpp+json
Location: https://rpp.example.nl/rpp/v1/domains/example.nl/transfer
RPP-code: 1001

TODO
]]>
</artwork>
</section>

<section anchor="cancel"><name>Cancel</name>

<ul spacing="compact">
<li>Request: DELETE /{collection}/{id}/transfer</li>
<li>Request message: Optional</li>
<li>Response message: Status</li>
</ul>
<t>The new sponsoring client MUST use the HTTP DELETE method to cancel a requested transfer.</t>
<t>Example request:</t>

<artwork><![CDATA[DELETE /rpp/v1/domains/example.nl/transfer HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

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

<artwork><![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: 1000

TODO
]]>
</artwork>
</section>

<section anchor="reject"><name>Reject</name>

<ul spacing="compact">
<li>Request: DELETE /{collection}/{id}/transfer</li>
<li>Request message:  None</li>
<li>Response message: Status</li>
</ul>
<t>The currently sponsoring client of the object MUST use the HTTP DELETE method to reject a started transfer process.</t>
<t>Example request:</t>

<artwork><![CDATA[DELETE /rpp/v1/domains/example.nl/transfers/latest HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

]]>
</artwork>
<t>Example Reject response:</t>

<artwork><![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: 1000

TODO

]]>
</artwork>
</section>

<section anchor="approve"><name>Approve</name>

<ul spacing="compact">
<li>Request: PUT /{collection}/{id}/transfers/latest</li>
<li>Request message: Optional</li>
<li>Response message: Status</li>
</ul>
<t>The currently sponsoring client MUST use the HTTP PUT method to approve a transfer requested by the new sponsoring client.</t>
<t>Example Approve request:</t>

<artwork><![CDATA[PUT /rpp/v1/domains/example.nl/transfer HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
Content-Length: 0

]]>
</artwork>
<t>Example Approve response:</t>

<artwork><![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: 1000

TODO
]]>
</artwork>
</section>
</section>

<section anchor="update"><name>Update</name>

<ul spacing="compact">
<li>Request: PATCH /{collection}/{id}</li>
<li>Request message: Object Update message</li>
<li>Response message: Status</li>
</ul>
<t>An object Update request MUST be performed using the HTTP PATCH method. The request message body MUST contain an EPP Update request, and the object-id value in the request MUST match the value of the object-id path parameter in the URL.</t>
<t><strong>TODO:</strong> when using JSON, also allow for JSON patch so client can send partial update data only?</t>
<t>Example request:</t>

<artwork><![CDATA[PATCH /rpp/v1/domains/example.nl HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Content-Type: application/rpp+json
Accept-Language: en
Content-Length: 252

TODO
]]>
</artwork>
<t>Example response:</t>

<artwork><![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: 1000

TODO
]]>
</artwork>
</section>
</section>

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

<section anchor="protocol-extension"><name>Protocol Extension</name>

<ul spacing="compact">
<li>Request: * /extensions/*</li>
<li>Request message: *</li>
<li>Response message: *</li>
</ul>
<t>EPP Protocol extensions, defined in <xref target="RFC5730" sectionFormat="of" section="2.7.1"></xref> are supported using the &quot;/extensions&quot; root resource.
The HTTP method used for a new Protocol extension is not defined but must follow the RESTful principles.</t>
<t>The example below, illustrates the use of the &quot;Domain Cancel Delete&quot; command. The new command is created below the &quot;extensions&quot; path element and after this element follows the &quot;domains&quot; object collection, finally a special &quot;deletion&quot; path element is added to the end of the URL. A client MUST use the HTPP DELETE method on a domain name deletion resource to cancel an ongoing domain delete transaction and move the domain from the grace state back to the active state.</t>
<t>Example Protocol Extension request:</t>

<ul spacing="compact">
<li>Request: DELETE /extensions/{collection}/{id}/deletion</li>
<li>Request message: Optional</li>
<li>Response message: Optional error response</li>
</ul>

<artwork><![CDATA[DELETE /rpp/v1/extensions/domains/example.nl/deletion HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345

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

<artwork><![CDATA[HTTP/2 200 OK
Date: Wed, 24 Jan 2024 12:00:00 UTC
Server: Example RPP server v1.0
Content-Language: en
Content-Length: 0
RPP-Svtrid: XYZ-12345
RPP-Cltrid: ABC-12345
RPP-code: 1000

TODO
]]>
</artwork>
</section>

<section anchor="object-extension"><name>Object Extension</name>
<t>An Object extension is differs from the other 2 extension types in the way that an Object extension is implemented using a new Object mapping for a new Object type, while re-using the existing EPP command and response structures. The newly created Object mapping, is similar to the existing Object mappings defined in <xref target="RFC5731"></xref>, <xref target="RFC5732"></xref> and <xref target="RFC5733"></xref>, and MUST be used in a similar fashion.</t>
<t>A hypothetical new Object mapping for IP addresses, may result in a new resource collection named &quot;ips&quot;, the semantics for the HTTP methods would have to be defined. Creating a new IP address may use the HTTP POST method on the &quot;ips&quot; collection.</t>

<ul spacing="compact">
<li>Request: POST /{collection}/{id}</li>
<li>Request message: IP Create Request message</li>
<li>Response message: IP Create Response message</li>
</ul>
<t>Example request:</t>

<artwork><![CDATA[POST /rpp/v1/ips HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
Accept: application/rpp+json
Accept-Language: en
RPP-Cltrid: ABC-12345
Content-Type: application/rpp+json
Content-Length: 220

TODO

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

<artwork><![CDATA[HTTP/2 200 OK
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.nl/rpp/v1/ips/192.0.2.1
RPP-code: 1000

TODO

]]>
</artwork>
</section>

<section anchor="command-response-extension"><name>Command-Response Extension</name>
<t>TODO</t>
</section>
</section>
</section>

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

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

<section anchor="security-considerations"><name>Security Considerations</name>
<t>Running RPP relies on the security of the underlying HTTP <xref target="RFC9110"></xref> transport, hence the best common practices for securing HTTP also apply to RPP. It is RECOMMENDED to follow them closely.</t>
<t>Data confidentiality and integrity MUST be enforced, all data transport between a client and server MUST be encrypted using TLS <xref target="RFC5246"></xref>. <xref target="RFC5734" sectionFormat="bare" section="Section 9"></xref> describes the level of security that is REQUIRED for all RPP endpoints.</t>
<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>.</t>
<t><strong>TODO:</strong> describe common modern authentication solutions such as  oath2.0</t>
</section>

</middle>

<back>
<references><name>Normative References</name>
<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.2617.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.5246.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.5732.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.5734.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.7234.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.7540.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.8259.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.9113.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9114.xml"/>
<reference anchor="YAML" target="https://yaml.org/spec/1.2.2/">
  <front>
    <title>YAML: YAML Ain&#39;t Markup Language</title>
    <author>
      <organization>YAML Language Development Team</organization>
    </author>
    <date year="2000"></date>
  </front>
</reference>
</references>

</back>

</rfc>
