<?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-wullink-rpp-core-01" 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-wullink-rpp-core-01" 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 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>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="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>
<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>
</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>:  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 HTTP response message body.</t>
</li>
<li><t><tt>RPP-EPP-Code</tt>: An optional that MAY be used when RPP is used as a frontend service for an EPP service. The header can be used by the client for easy access to the EPP result code, without having to parse 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 (HEAD) request.</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>
</ul>
</section>

<section anchor="endpoints"><name>Endpoints</name>
<t>subsequent sections provide details for each endpoint. URLs are assumed to be using the prefix: &quot;/{context-root}/{version}/&quot;. Some RPP endpoints do not require a request and/or response message.</t>
<t>{c}: An abbreviation for {collection}: this MUST be substituted with &quot;domains&quot;, &quot;hosts&quot;, &quot;entities&quot; or any other collection of objects.
{i}: 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.</t>
<t>A RPP client MAY use the HTTP GET method for executing informational request 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-for-existence"><name>Check for Existence</name>

<ul spacing="compact">
<li>Request: HEAD /{collection}/{id}</li>
<li>Request message: None</li>
<li>Response message: None</li>
</ul>
<t>The HTTP HEAD method MUST be used for object existence check. The response MUST contain the <tt>RPP-Check-Avail</tt> header. The value of the <tt>RPP-Check-Avail</tt> header MUST be false or true, depending on whether the object can be provisioned.</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>

<sourcecode type="http"><![CDATA[HEAD /rpp/v1/domains/example.nl HTTP/2
Host: rpp.example.nl
Authorization: Bearer <token>
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
RPP-Cltrid: ABC-12345
RPP-Svtrid: XYZ-12345
RPP-Check-Avail: false
RPP-result-code: 1000
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. If the object has authorization information attached then the client MUST use an empty message body and include the RPP-AuthInfo HTTP header. If the authorization is linked to a database object the client MUST also include the RPP-Roid header. The client MAY also use a message body that includes the authorization information, the client MUST then not use the RPP-AuthInfo and RPP-Roid headers.</t>

<ul spacing="compact">
<li>Request: GET /{collection}/{id}</li>
<li>Request message: Optional</li>
<li>Response message: Info response</li>
</ul>
<t>Example request for an object not using authorization information.</t>

<sourcecode type="http"><![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

]]>
</sourcecode>
<t>Example request using RPP-AuthInfo and RPP-Roid headers for an object that has attached authorization information.</t>

<sourcecode type="http"><![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

]]>
</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: 1000

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

<section anchor="poll-for-messages"><name>Poll for Messages</name>
<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 /rpp/v1/messages HTTP/2
Host: rpp.example.nl
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: 1301

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

<section anchor="delete-message"><name>Delete Message</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>

<sourcecode type="http"><![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

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

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

<section anchor="create-resource"><name>Create Resource</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>

<sourcecode type="http"><![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
]]>
</sourcecode>
<t>Example Domain Create response:</t>

<sourcecode type="http"><![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
]]>
</sourcecode>
</section>

<section anchor="delete-resource"><name>Delete Resource</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>

<sourcecode type="http"><![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

]]>
</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: 1000

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

<section anchor="renew-resource"><name>Renew Resource</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><strong>TODO:</strong>: current-date: can also be a HTTP header?</t>
<t>Example Domain Renew request:</t>

<sourcecode type="http"><![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

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

<sourcecode type="http"><![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

]]>
</sourcecode>
<t>Example Renew 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
Content-Length: 205
Location: https://rpp.example.nl/rpp/v1/domains/example.nl
Content-Type: application/rpp+json
RPP-code: 1000

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

<section anchor="transfer-resource"><name>Transfer Resource</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>

<section anchor="start"><name>Start</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>

<sourcecode type="http"><![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

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

<sourcecode type="http"><![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

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

<sourcecode type="http"><![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

]]>
</sourcecode>
<t>Example Transfer 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
Content-Length: 328
Content-Type: application/rpp+json
Location: https://rpp.example.nl/rpp/v1/domains/example.nl/transfer
RPP-code: 1001

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

<section anchor="status"><name>Status</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 Status response</li>
</ul>
<t>Example domain name Transfer Status request without authorization information required:</t>

<sourcecode type="http"><![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

]]>
</sourcecode>
<t>If the requested transfer 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>

<sourcecode type="http"><![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

]]>
</sourcecode>
<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>

<sourcecode type="http"><![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

]]>
</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: 1000

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

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

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

<sourcecode type="http"><![CDATA[POST /rpp/v1/domains/example.nl/transfer/cancelation HTTP/2
Host: rpp.example.nl
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: 1000

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

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

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

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

]]>
</sourcecode>
<t>Example Reject 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: 1000

TODO

]]>
</sourcecode>
</section>

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

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

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

]]>
</sourcecode>
<t>Example Approve 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: 1000

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

<section anchor="update-resource"><name>Update Resource</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 Update message.</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>

<sourcecode type="http"><![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
]]>
</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: 1000

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

<section anchor="extension-framework"><name>Extension Framework</name>
<t>TODO</t>
</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>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>
</section>

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

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

</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.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.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.8259.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.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>
