<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.29 (Ruby 3.2.3) -->
<?rfc compact="yes"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ferro-dnsop-apertodns-protocol-01" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.31.0 -->
  <front>
    <title abbrev="ApertoDNS Protocol">ApertoDNS Protocol: A Modern Dynamic DNS Update Protocol</title>
    <seriesInfo name="Internet-Draft" value="draft-ferro-dnsop-apertodns-protocol-01"/>
    <author initials="A." surname="Ferro" fullname="Andrea Ferro">
      <organization>ApertoDNS</organization>
      <address>
        <postal>
          <country>Italy</country>
        </postal>
        <email>support@apertodns.com</email>
      </address>
    </author>
    <date year="2026" month="January" day="17"/>
    <area>Operations and Management</area>
    <workgroup>DNS Operations</workgroup>
    <keyword>dynamic dns</keyword>
    <keyword>ddns</keyword>
    <keyword>dns update</keyword>
    <keyword>REST API</keyword>
    <keyword>ACME</keyword>
    <keyword>DNS-01</keyword>
    <abstract>
      <?line 47?>

<t>This document specifies the ApertoDNS Protocol, a modern RESTful
protocol for dynamic DNS (DDNS) updates. It provides a secure,
provider-agnostic alternative to legacy protocols, with native
support for IPv4, IPv6, bulk updates, automatic IP detection,
TXT record management for ACME DNS-01 challenges, and
standardized authentication mechanisms.</t>
      <t>The protocol uses well-known URIs (RFC 8615), JSON payloads
(RFC 8259), and bearer token authentication (RFC 6750) to enable
interoperable dynamic DNS services across different providers.</t>
    </abstract>
  </front>
  <middle>
    <?line 60?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Dynamic DNS (DDNS) services allow users with dynamically assigned
IP addresses to maintain a consistent hostname that automatically
updates when their IP address changes. This capability is essential
for home users, small businesses, and IoT devices that need to be
reachable despite lacking static IP addresses.</t>
      <t>While RFC 2136 <xref target="RFC2136"/> defines DNS UPDATE for programmatic DNS
modifications, most consumer-facing DDNS services use simpler
HTTP-based protocols. The de facto standard for consumer DDNS
emerged organically without formal specification.</t>
      <t>This lack of standardization has led to:</t>
      <ul spacing="normal">
        <li>
          <t>Inconsistent implementations across providers</t>
        </li>
        <li>
          <t>Security vulnerabilities from ad-hoc designs</t>
        </li>
        <li>
          <t>Limited feature sets (e.g., no native IPv6 support)</t>
        </li>
        <li>
          <t>Vendor lock-in due to proprietary extensions</t>
        </li>
        <li>
          <t>No formal capability negotiation</t>
        </li>
      </ul>
      <t>This document specifies the ApertoDNS Protocol as a modern, secure,
and fully interoperable alternative designed for the current
Internet landscape.</t>
      <section anchor="protocol-versioning">
        <name>Protocol Versioning</name>
        <t>The protocol version specified in discovery responses (e.g., "1.3.0")
refers to the semantic version of the protocol specification itself.
This document represents the first IETF standardization of a protocol
that has been in production use since 2024. The version number in
the discovery endpoint reflects the feature set available, while
the Internet-Draft version (e.g., "-01") tracks the IETF document
revision process separately.</t>
      </section>
      <section anchor="requirements-language">
        <name>Requirements Language</name>
        <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
        <?line -18?>

</section>
      <section anchor="goals">
        <name>Goals</name>
        <t>The ApertoDNS Protocol is designed with the following goals:</t>
        <ul spacing="normal">
          <li>
            <t><strong>Provider-agnostic</strong>: Any DDNS provider can implement this
protocol using their own domain and branding</t>
          </li>
          <li>
            <t><strong>Secure by default</strong>: HTTPS required, bearer token authentication</t>
          </li>
          <li>
            <t><strong>Modern</strong>: JSON responses, proper HTTP semantics, native IPv6</t>
          </li>
          <li>
            <t><strong>Discoverable</strong>: Self-describing via discovery endpoint</t>
          </li>
          <li>
            <t><strong>Extensible</strong>: Capability negotiation allows future enhancements</t>
          </li>
          <li>
            <t><strong>Backward compatible</strong>: Optional legacy endpoint for existing clients</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="terminology">
      <name>Terminology</name>
      <t>This document uses the following terms:</t>
      <dl>
        <dt>DDNS:</dt>
        <dd>
          <t>Dynamic DNS. A service that automatically updates DNS records
when a client's IP address changes.</t>
        </dd>
        <dt>Provider:</dt>
        <dd>
          <t>An organization or service implementing this protocol to offer
DDNS services to users.</t>
        </dd>
        <dt>Hostname:</dt>
        <dd>
          <t>A fully qualified domain name (FQDN) managed by the provider
and associated with a user account.</t>
        </dd>
        <dt>Token:</dt>
        <dd>
          <t>An authentication credential issued by the provider, used to
authorize API requests.</t>
        </dd>
        <dt>Auto-detection:</dt>
        <dd>
          <t>Server-side determination of the client's IP address from the
incoming HTTP request, used when the client specifies "auto"
as the IP value.</t>
        </dd>
        <dt>Client:</dt>
        <dd>
          <t>Software or device that makes requests to a DDNS provider to
update DNS records.</t>
        </dd>
        <dt>A-label:</dt>
        <dd>
          <t>The ASCII-Compatible Encoding (ACE) form of an Internationalized
Domain Name label, as defined in <xref target="RFC5891"/>.</t>
        </dd>
        <dt>TXT Record:</dt>
        <dd>
          <t>A DNS resource record type used to store arbitrary text data,
commonly used for domain verification and ACME DNS-01 challenges.</t>
        </dd>
        <dt>ACME DNS-01:</dt>
        <dd>
          <t>A challenge type defined in <xref target="RFC8555"/> where domain ownership
is proven by provisioning a DNS TXT record.</t>
        </dd>
      </dl>
    </section>
    <section anchor="protocol-overview">
      <name>Protocol Overview</name>
      <t>The ApertoDNS Protocol is a RESTful API using JSON over HTTPS.
All protocol endpoints are located under the well-known URI path
<tt>/.well-known/apertodns/v1/</tt>.</t>
      <section anchor="base-url">
        <name>Base URL</name>
        <t>Conforming implementations <bcp14>MUST</bcp14> serve all endpoints under:</t>
        <artwork><![CDATA[
https://{provider-domain}/.well-known/apertodns/v1/
]]></artwork>
        <t>The use of well-known URIs <xref target="RFC8615"/> ensures consistent endpoint
discovery across providers.</t>
      </section>
      <section anchor="content-type">
        <name>Content Type</name>
        <t>All request and response bodies <bcp14>MUST</bcp14> use the <tt>application/json</tt>
media type <xref target="RFC8259"/> unless otherwise specified.</t>
      </section>
      <section anchor="response-format">
        <name>Response Format</name>
        <t>All responses <bcp14>MUST</bcp14> include a boolean <tt>success</tt> field at the top
level:</t>
        <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": { ... }
}
]]></sourcecode>
        <t>Or for errors:</t>
        <sourcecode type="json"><![CDATA[
{
  "success": false,
  "error": {
    "code": "error_code",
    "message": "Human-readable description"
  }
}
]]></sourcecode>
      </section>
    </section>
    <section anchor="conformance-requirements">
      <name>Conformance Requirements</name>
      <t>This section defines the requirements for conforming implementations.</t>
      <section anchor="conformance-levels">
        <name>Conformance Levels</name>
        <t>This protocol defines two conformance levels:</t>
        <dl>
          <dt>Core Conformance:</dt>
          <dd>
            <t>A conforming implementation <bcp14>MUST</bcp14> implement the following endpoints:
/info, /health, and /update. A conforming implementation <bcp14>MUST</bcp14>
support bearer token authentication. A conforming implementation
<bcp14>MUST</bcp14> serve all endpoints over HTTPS.</t>
          </dd>
          <dt>Full Conformance:</dt>
          <dd>
            <t>In addition to core conformance requirements, a fully conforming
implementation <bcp14>MUST</bcp14> implement: /bulk-update, /status/{hostname},
and /domains endpoints.</t>
          </dd>
        </dl>
      </section>
      <section anchor="capability-advertisement">
        <name>Capability Advertisement</name>
        <t>Implementations <bcp14>MUST</bcp14> accurately advertise their capabilities in
the /info endpoint response. Implementations <bcp14>MUST NOT</bcp14> advertise
capabilities they do not support.</t>
      </section>
      <section anchor="interoperability">
        <name>Interoperability</name>
        <t>Implementations <bcp14>SHOULD</bcp14> accept requests from any conforming client.
Implementations <bcp14>MUST NOT</bcp14> require proprietary extensions for basic
DDNS functionality.</t>
      </section>
    </section>
    <section anchor="authentication">
      <name>Authentication</name>
      <section anchor="supported-methods">
        <name>Supported Methods</name>
        <t>Protected endpoints require authentication via one of the following
methods:</t>
        <ol spacing="normal" type="1"><li>
            <t><strong>Bearer Token</strong> (<bcp14>RECOMMENDED</bcp14>) <xref target="RFC6750"/>: <tt>Authorization: Bearer {token}</tt></t>
          </li>
          <li>
            <t><strong>API Key Header</strong>: <tt>X-API-Key: {token}</tt></t>
          </li>
          <li>
            <t><strong>HTTP Basic</strong> (legacy only): <tt>Authorization: Basic {credentials}</tt></t>
          </li>
        </ol>
        <t>Implementations <bcp14>MUST</bcp14> support bearer token authentication.
Implementations <bcp14>MAY</bcp14> support additional methods.</t>
      </section>
      <section anchor="token-format">
        <name>Token Format</name>
        <t>Tokens <bcp14>SHOULD</bcp14> follow the format:</t>
        <artwork><![CDATA[
{provider}_{environment}_{random}
]]></artwork>
        <t>Where:</t>
        <ul spacing="normal">
          <li>
            <t><tt>{provider}</tt>: Provider identifier (e.g., "apertodns", "example")</t>
          </li>
          <li>
            <t><tt>{environment}</tt>: Token environment ("live", "test", "sandbox")</t>
          </li>
          <li>
            <t><tt>{random}</tt>: Cryptographically secure random string (minimum 32
characters recommended)</t>
          </li>
        </ul>
        <t>Example: <tt>apertodns_live_Kj8mP2xL9nQ4wR7vY1zA3bC6dE0fG5hI</tt></t>
        <t>This format enables:</t>
        <ul spacing="normal">
          <li>
            <t>Easy identification of token source during debugging</t>
          </li>
          <li>
            <t>Environment separation (production vs. testing)</t>
          </li>
          <li>
            <t>Consistent token handling across providers</t>
          </li>
        </ul>
      </section>
      <section anchor="token-transmission">
        <name>Token Transmission</name>
        <t>Tokens <bcp14>MUST</bcp14> be transmitted only in HTTP headers. Tokens <bcp14>MUST NOT</bcp14>
appear in URLs, query parameters, or request bodies where they
might be logged.</t>
      </section>
    </section>
    <section anchor="endpoints">
      <name>Endpoints</name>
      <section anchor="discovery-endpoint-info">
        <name>Discovery Endpoint (/info)</name>
        <artwork><![CDATA[
GET /.well-known/apertodns/v1/info
]]></artwork>
        <t>The discovery endpoint returns provider information, capabilities,
and configuration. This endpoint <bcp14>MUST NOT</bcp14> require authentication.</t>
        <section anchor="response-fields">
          <name>Response Fields</name>
          <table>
            <thead>
              <tr>
                <th align="left">Field</th>
                <th align="left">Type</th>
                <th align="left">Required</th>
                <th align="left">Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">protocol</td>
                <td align="left">string</td>
                <td align="left">YES</td>
                <td align="left">
                  <bcp14>MUST</bcp14> be "apertodns"</td>
              </tr>
              <tr>
                <td align="left">protocol_version</td>
                <td align="left">string</td>
                <td align="left">YES</td>
                <td align="left">Semantic version (e.g., "1.3.0")</td>
              </tr>
              <tr>
                <td align="left">provider</td>
                <td align="left">object</td>
                <td align="left">YES</td>
                <td align="left">Provider information</td>
              </tr>
              <tr>
                <td align="left">capabilities</td>
                <td align="left">object</td>
                <td align="left">YES</td>
                <td align="left">Supported features</td>
              </tr>
              <tr>
                <td align="left">authentication</td>
                <td align="left">object</td>
                <td align="left">YES</td>
                <td align="left">Supported auth methods</td>
              </tr>
              <tr>
                <td align="left">endpoints</td>
                <td align="left">object</td>
                <td align="left">YES</td>
                <td align="left">Available endpoint paths</td>
              </tr>
              <tr>
                <td align="left">rate_limits</td>
                <td align="left">object</td>
                <td align="left">NO</td>
                <td align="left">Rate limiting configuration</td>
              </tr>
              <tr>
                <td align="left">server_time</td>
                <td align="left">string</td>
                <td align="left">NO</td>
                <td align="left">Current server time (ISO 8601)</td>
              </tr>
            </tbody>
          </table>
        </section>
        <section anchor="capability-fields">
          <name>Capability Fields</name>
          <t>The capabilities object <bcp14>MUST</bcp14> include the following fields:</t>
          <table>
            <thead>
              <tr>
                <th align="left">Field</th>
                <th align="left">Type</th>
                <th align="left">Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">ipv4</td>
                <td align="left">boolean</td>
                <td align="left">IPv4 address updates supported</td>
              </tr>
              <tr>
                <td align="left">ipv6</td>
                <td align="left">boolean</td>
                <td align="left">IPv6 address updates supported</td>
              </tr>
              <tr>
                <td align="left">auto_ip_detection</td>
                <td align="left">boolean</td>
                <td align="left">Automatic IP detection supported</td>
              </tr>
              <tr>
                <td align="left">bulk_update</td>
                <td align="left">boolean</td>
                <td align="left">Bulk update endpoint available</td>
              </tr>
              <tr>
                <td align="left">max_bulk_size</td>
                <td align="left">integer</td>
                <td align="left">Maximum hostnames per bulk request</td>
              </tr>
            </tbody>
          </table>
          <t>The capabilities object <bcp14>MAY</bcp14> include the following <bcp14>OPTIONAL</bcp14> fields:</t>
          <table>
            <thead>
              <tr>
                <th align="left">Field</th>
                <th align="left">Type</th>
                <th align="left">Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">webhooks</td>
                <td align="left">boolean</td>
                <td align="left">Provider-specific webhook support available</td>
              </tr>
              <tr>
                <td align="left">txt_records</td>
                <td align="left">boolean</td>
                <td align="left">TXT record management supported</td>
              </tr>
              <tr>
                <td align="left">txt_max_records</td>
                <td align="left">integer</td>
                <td align="left">Maximum TXT records per hostname (default: 5)</td>
              </tr>
            </tbody>
          </table>
          <t>When <tt>webhooks</tt> is true, the provider offers webhook notifications
for DNS update events such as IP address changes. The webhook API
is implementation-specific and not standardized by this protocol
version. Providers offering webhooks <bcp14>SHOULD</bcp14> document their webhook
API separately.</t>
          <t>When <tt>txt_records</tt> is true, the provider supports TXT record
management via the /txt endpoint. This capability enables ACME
DNS-01 challenges <xref target="RFC8555"/> for automated certificate issuance.</t>
          <t>The capabilities object <bcp14>MAY</bcp14> include additional fields for future
extensions. Unknown capability fields <bcp14>SHOULD</bcp14> be ignored by clients.</t>
        </section>
        <section anchor="example-response">
          <name>Example Response</name>
          <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "protocol": "apertodns",
    "protocol_version": "1.3.0",
    "provider": {
      "name": "Example DDNS",
      "website": "https://example.com",
      "documentation": "https://example.com/docs",
      "support_email": "support@example.com"
    },
    "capabilities": {
      "ipv4": true,
      "ipv6": true,
      "auto_ip_detection": true,
      "bulk_update": true,
      "webhooks": true,
      "max_bulk_size": 100
    },
    "authentication": {
      "methods": ["bearer_token", "api_key_header"],
      "token_format": "{provider}_{environment}_{random}"
    },
    "endpoints": {
      "info": "/.well-known/apertodns/v1/info",
      "health": "/.well-known/apertodns/v1/health",
      "update": "/.well-known/apertodns/v1/update",
      "bulk_update": "/.well-known/apertodns/v1/bulk-update",
      "status": "/.well-known/apertodns/v1/status/{hostname}",
      "domains": "/.well-known/apertodns/v1/domains"
    },
    "rate_limits": {
      "update": {"requests": 60, "window_seconds": 60},
      "bulk_update": {"requests": 10, "window_seconds": 60}
    },
    "server_time": "2025-01-01T12:00:00.000Z"
  }
}
]]></sourcecode>
        </section>
      </section>
      <section anchor="health-endpoint-health">
        <name>Health Endpoint (/health)</name>
        <artwork><![CDATA[
GET /.well-known/apertodns/v1/health
]]></artwork>
        <t>Returns service health status. This endpoint <bcp14>MUST NOT</bcp14> require
authentication and <bcp14>SHOULD</bcp14> be used for monitoring.</t>
        <section anchor="example-response-1">
          <name>Example Response</name>
          <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "status": "healthy",
    "timestamp": "2025-01-01T12:00:00.000Z"
  }
}
]]></sourcecode>
          <t>The <tt>status</tt> field <bcp14>MUST</bcp14> be one of: "healthy", "degraded", or
"unhealthy".</t>
        </section>
      </section>
      <section anchor="update-endpoint-update">
        <name>Update Endpoint (/update)</name>
        <artwork><![CDATA[
POST /.well-known/apertodns/v1/update
Authorization: Bearer {token}
Content-Type: application/json
]]></artwork>
        <t>Updates DNS records for a single hostname. This endpoint <bcp14>MUST</bcp14>
require authentication.</t>
        <section anchor="request-fields">
          <name>Request Fields</name>
          <table>
            <thead>
              <tr>
                <th align="left">Field</th>
                <th align="left">Type</th>
                <th align="left">Required</th>
                <th align="left">Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">hostname</td>
                <td align="left">string</td>
                <td align="left">YES</td>
                <td align="left">Fully qualified domain name</td>
              </tr>
              <tr>
                <td align="left">ipv4</td>
                <td align="left">string</td>
                <td align="left">NO</td>
                <td align="left">IPv4 address or "auto"</td>
              </tr>
              <tr>
                <td align="left">ipv6</td>
                <td align="left">string</td>
                <td align="left">NO</td>
                <td align="left">IPv6 address or "auto"</td>
              </tr>
              <tr>
                <td align="left">ttl</td>
                <td align="left">integer</td>
                <td align="left">NO</td>
                <td align="left">Time to live in seconds (60-86400)</td>
              </tr>
            </tbody>
          </table>
          <t>At least one of <tt>ipv4</tt> or <tt>ipv6</tt> <bcp14>SHOULD</bcp14> be provided. If neither
is provided, implementations <bcp14>SHOULD</bcp14> use auto-detection for IPv4.</t>
          <t>The special value "auto" instructs the server to detect the
client's IP address from the incoming request.</t>
        </section>
        <section anchor="auto-detection-limitations">
          <name>Auto-Detection Limitations</name>
          <t>Auto-detection is constrained by HTTP connection semantics: the
server can only detect the address family used by the client's
TCP connection. This is a fundamental characteristic of HTTP-based
protocols, not a limitation specific to this specification.</t>
          <t>The following constraints apply:</t>
          <ul spacing="normal">
            <li>
              <t>If the client connects via IPv4: only IPv4 can be auto-detected</t>
            </li>
            <li>
              <t>If the client connects via IPv6: only IPv6 can be auto-detected</t>
            </li>
            <li>
              <t>Cross-family detection is not possible (e.g., detecting IPv4
address when connected via IPv6)</t>
            </li>
          </ul>
          <t>When a client requests auto-detection for an address family that
does not match the connection's address family, the server <bcp14>MUST</bcp14>
return an error with the appropriate error code (<tt>ipv4_auto_failed</tt>
or <tt>ipv6_auto_failed</tt>).</t>
          <t>Clients requiring dual-stack updates (both IPv4 and IPv6) <bcp14>SHOULD</bcp14>
use one of the following approaches:</t>
          <ol spacing="normal" type="1"><li>
              <t>Provide explicit IP addresses for both fields</t>
            </li>
            <li>
              <t>Make separate update requests over each address family</t>
            </li>
            <li>
              <t>Use auto-detection for the matching address family and provide
an explicit address for the other</t>
            </li>
          </ol>
        </section>
        <section anchor="example-request">
          <name>Example Request</name>
          <sourcecode type="json"><![CDATA[
{
  "hostname": "home.example.com",
  "ipv4": "auto",
  "ttl": 300
}
]]></sourcecode>
        </section>
        <section anchor="example-response-2">
          <name>Example Response</name>
          <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "hostname": "home.example.com",
    "ipv4": "203.0.113.50",
    "previous_ipv4": "203.0.113.49",
    "ttl": 300,
    "changed": true,
    "timestamp": "2025-01-01T12:00:00.000Z"
  }
}
]]></sourcecode>
          <t>The <tt>changed</tt> field indicates whether the IP address was actually
modified (false if the new IP matches the existing record).</t>
        </section>
        <section anchor="auto-detection-failure-response">
          <name>Auto-Detection Failure Response</name>
          <t>When auto-detection fails due to address family mismatch:</t>
          <sourcecode type="json"><![CDATA[
{
  "success": false,
  "error": {
    "code": "ipv4_auto_failed",
    "message": "Cannot auto-detect IPv4 from IPv6 connection"
  }
}
]]></sourcecode>
        </section>
      </section>
      <section anchor="bulk-update-endpoint-bulk-update">
        <name>Bulk Update Endpoint (/bulk-update)</name>
        <artwork><![CDATA[
POST /.well-known/apertodns/v1/bulk-update
Authorization: Bearer {token}
Content-Type: application/json
]]></artwork>
        <t>Updates multiple hostnames in a single request. Providers
advertising <tt>bulk_update: true</tt> in capabilities <bcp14>MUST</bcp14> implement
this endpoint.</t>
        <section anchor="example-request-1">
          <name>Example Request</name>
          <sourcecode type="json"><![CDATA[
{
  "updates": [
    {"hostname": "home.example.com", "ipv4": "auto"},
    {"hostname": "office.example.com", "ipv4": "203.0.113.51"}
  ]
}
]]></sourcecode>
        </section>
        <section anchor="example-response-3">
          <name>Example Response</name>
          <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "summary": {
      "total": 2,
      "successful": 2,
      "failed": 0
    },
    "results": [
      {
        "hostname": "home.example.com",
        "success": true,
        "ipv4": "203.0.113.50",
        "changed": true
      },
      {
        "hostname": "office.example.com",
        "success": true,
        "ipv4": "203.0.113.51",
        "changed": true
      }
    ]
  }
}
]]></sourcecode>
        </section>
      </section>
      <section anchor="status-endpoint-statushostname">
        <name>Status Endpoint (/status/{hostname})</name>
        <artwork><![CDATA[
GET /.well-known/apertodns/v1/status/{hostname}
Authorization: Bearer {token}
]]></artwork>
        <t>Returns current DNS record status for a hostname.</t>
        <section anchor="example-response-4">
          <name>Example Response</name>
          <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "hostname": "home.example.com",
    "ipv4": "203.0.113.50",
    "ipv6": "2001:db8::1",
    "ttl": 300,
    "last_updated": "2025-01-01T12:00:00.000Z"
  }
}
]]></sourcecode>
        </section>
      </section>
      <section anchor="domains-endpoint-domains">
        <name>Domains Endpoint (/domains)</name>
        <artwork><![CDATA[
GET /.well-known/apertodns/v1/domains
Authorization: Bearer {token}
]]></artwork>
        <t>Returns list of domains and hostnames available to the
authenticated user.</t>
        <section anchor="example-response-5">
          <name>Example Response</name>
          <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "domains": [
      {
        "domain": "example.com",
        "hostnames": ["home.example.com", "office.example.com"]
      }
    ]
  }
}
]]></sourcecode>
        </section>
      </section>
      <section anchor="txt-record-endpoint-txt">
        <name>TXT Record Endpoint (/txt)</name>
        <t>The TXT record endpoint enables management of DNS TXT records,
primarily for ACME DNS-01 challenges <xref target="RFC8555"/> used in automated
certificate issuance. Providers advertising <tt>txt_records: true</tt>
in capabilities <bcp14>MUST</bcp14> implement this endpoint.</t>
        <section anchor="design-rationale">
          <name>Design Rationale</name>
          <t>TXT record management is designed to support wildcard certificate
issuance, which requires multiple simultaneous TXT records during
the ACME validation process. The protocol supports:</t>
          <ul spacing="normal">
            <li>
              <t><strong>Accumulation</strong>: Multiple TXT values can coexist for the same
hostname prefix (e.g., <tt>_acme-challenge.example.com</tt>)</t>
            </li>
            <li>
              <t><strong>Selective deletion</strong>: Individual TXT values can be removed
without affecting others</t>
            </li>
            <li>
              <t><strong>Automatic cleanup</strong>: Providers <bcp14>MAY</bcp14> implement TTL-based
expiration for TXT records</t>
            </li>
          </ul>
        </section>
        <section anchor="set-txt-record-post">
          <name>Set TXT Record (POST)</name>
          <artwork><![CDATA[
POST /.well-known/apertodns/v1/txt
Authorization: Bearer {token}
Content-Type: application/json
]]></artwork>
          <t>Creates or adds a TXT record value for the specified hostname.
Multiple calls with different values <bcp14>MUST</bcp14> accumulate (not replace)
TXT records for the same hostname, up to the provider's limit.</t>
          <section anchor="request-fields-1">
            <name>Request Fields</name>
            <table>
              <thead>
                <tr>
                  <th align="left">Field</th>
                  <th align="left">Type</th>
                  <th align="left">Required</th>
                  <th align="left">Description</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td align="left">hostname</td>
                  <td align="left">string</td>
                  <td align="left">YES</td>
                  <td align="left">FQDN for the TXT record</td>
                </tr>
                <tr>
                  <td align="left">value</td>
                  <td align="left">string</td>
                  <td align="left">YES</td>
                  <td align="left">TXT record value (max 255 chars)</td>
                </tr>
                <tr>
                  <td align="left">ttl</td>
                  <td align="left">integer</td>
                  <td align="left">NO</td>
                  <td align="left">Time to live in seconds (default: 60)</td>
                </tr>
              </tbody>
            </table>
          </section>
          <section anchor="example-request-2">
            <name>Example Request</name>
            <sourcecode type="json"><![CDATA[
{
  "hostname": "_acme-challenge.home.example.com",
  "value": "gfj9Xq...Rg85nM",
  "ttl": 60
}
]]></sourcecode>
          </section>
          <section anchor="example-response-6">
            <name>Example Response</name>
            <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "hostname": "_acme-challenge.home.example.com",
    "value": "gfj9Xq...Rg85nM",
    "ttl": 60,
    "record_count": 1,
    "timestamp": "2026-01-01T12:00:00.000Z"
  }
}
]]></sourcecode>
            <t>The <tt>record_count</tt> field indicates the total number of TXT values
currently stored for this hostname after the operation.</t>
          </section>
        </section>
        <section anchor="delete-txt-record-delete">
          <name>Delete TXT Record (DELETE)</name>
          <artwork><![CDATA[
DELETE /.well-known/apertodns/v1/txt
Authorization: Bearer {token}
Content-Type: application/json
]]></artwork>
          <t>Removes a specific TXT record value. If <tt>value</tt> is omitted, ALL
TXT records for the hostname are removed.</t>
          <section anchor="request-fields-2">
            <name>Request Fields</name>
            <table>
              <thead>
                <tr>
                  <th align="left">Field</th>
                  <th align="left">Type</th>
                  <th align="left">Required</th>
                  <th align="left">Description</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td align="left">hostname</td>
                  <td align="left">string</td>
                  <td align="left">YES</td>
                  <td align="left">FQDN of the TXT record</td>
                </tr>
                <tr>
                  <td align="left">value</td>
                  <td align="left">string</td>
                  <td align="left">NO</td>
                  <td align="left">Specific value to delete (omit to delete all)</td>
                </tr>
              </tbody>
            </table>
          </section>
          <section anchor="example-request-selective-deletion">
            <name>Example Request (selective deletion)</name>
            <sourcecode type="json"><![CDATA[
{
  "hostname": "_acme-challenge.home.example.com",
  "value": "gfj9Xq...Rg85nM"
}
]]></sourcecode>
          </section>
          <section anchor="example-response-7">
            <name>Example Response</name>
            <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "hostname": "_acme-challenge.home.example.com",
    "deleted": true,
    "values_removed": 1,
    "remaining_count": 1,
    "timestamp": "2026-01-01T12:00:00.000Z"
  }
}
]]></sourcecode>
          </section>
        </section>
        <section anchor="get-txt-records-get">
          <name>Get TXT Records (GET)</name>
          <artwork><![CDATA[
GET /.well-known/apertodns/v1/txt/{hostname}
Authorization: Bearer {token}
]]></artwork>
          <t>Returns all TXT record values for a hostname.</t>
          <section anchor="example-response-8">
            <name>Example Response</name>
            <sourcecode type="json"><![CDATA[
{
  "success": true,
  "data": {
    "hostname": "_acme-challenge.home.example.com",
    "values": [
      "gfj9Xq...Rg85nM",
      "hK7pLm...Yt42xQ"
    ],
    "ttl": 60,
    "record_count": 2
  }
}
]]></sourcecode>
          </section>
        </section>
      </section>
    </section>
    <section anchor="error-handling">
      <name>Error Handling</name>
      <section anchor="http-status-codes">
        <name>HTTP Status Codes</name>
        <t>Implementations <bcp14>MUST</bcp14> use appropriate HTTP status codes as defined
in <xref target="RFC9110"/>:</t>
        <table>
          <thead>
            <tr>
              <th align="left">Status</th>
              <th align="left">Usage</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">200</td>
              <td align="left">Successful request</td>
            </tr>
            <tr>
              <td align="left">400</td>
              <td align="left">Invalid request (bad hostname, invalid IP)</td>
            </tr>
            <tr>
              <td align="left">401</td>
              <td align="left">Missing or invalid authentication</td>
            </tr>
            <tr>
              <td align="left">403</td>
              <td align="left">Not authorized for requested resource</td>
            </tr>
            <tr>
              <td align="left">404</td>
              <td align="left">Resource not found</td>
            </tr>
            <tr>
              <td align="left">429</td>
              <td align="left">Rate limit exceeded</td>
            </tr>
            <tr>
              <td align="left">500</td>
              <td align="left">Server error</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="error-response-format">
        <name>Error Response Format</name>
        <sourcecode type="json"><![CDATA[
{
  "success": false,
  "error": {
    "code": "error_code",
    "message": "Human-readable description"
  }
}
]]></sourcecode>
      </section>
      <section anchor="standard-error-codes">
        <name>Standard Error Codes</name>
        <table>
          <thead>
            <tr>
              <th align="left">Code</th>
              <th align="left">HTTP Status</th>
              <th align="left">Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">unauthorized</td>
              <td align="left">401</td>
              <td align="left">Missing authentication</td>
            </tr>
            <tr>
              <td align="left">invalid_token</td>
              <td align="left">401</td>
              <td align="left">Invalid or expired token</td>
            </tr>
            <tr>
              <td align="left">forbidden</td>
              <td align="left">403</td>
              <td align="left">Not authorized for resource</td>
            </tr>
            <tr>
              <td align="left">not_found</td>
              <td align="left">404</td>
              <td align="left">Hostname not found</td>
            </tr>
            <tr>
              <td align="left">rate_limited</td>
              <td align="left">429</td>
              <td align="left">Too many requests</td>
            </tr>
            <tr>
              <td align="left">invalid_hostname</td>
              <td align="left">400</td>
              <td align="left">Invalid hostname format</td>
            </tr>
            <tr>
              <td align="left">invalid_ip</td>
              <td align="left">400</td>
              <td align="left">Invalid IP address format</td>
            </tr>
            <tr>
              <td align="left">hostname_not_owned</td>
              <td align="left">403</td>
              <td align="left">User does not own hostname</td>
            </tr>
            <tr>
              <td align="left">ipv4_auto_failed</td>
              <td align="left">400</td>
              <td align="left">Cannot auto-detect IPv4 from IPv6 connection</td>
            </tr>
            <tr>
              <td align="left">ipv6_auto_failed</td>
              <td align="left">400</td>
              <td align="left">Cannot auto-detect IPv6 from IPv4 connection</td>
            </tr>
            <tr>
              <td align="left">validation_error</td>
              <td align="left">400</td>
              <td align="left">Request validation failed</td>
            </tr>
            <tr>
              <td align="left">invalid_ttl</td>
              <td align="left">400</td>
              <td align="left">TTL value out of acceptable range</td>
            </tr>
            <tr>
              <td align="left">txt_not_supported</td>
              <td align="left">400</td>
              <td align="left">Provider does not support TXT records</td>
            </tr>
            <tr>
              <td align="left">txt_limit_exceeded</td>
              <td align="left">400</td>
              <td align="left">Maximum TXT records per hostname exceeded</td>
            </tr>
            <tr>
              <td align="left">txt_invalid_name</td>
              <td align="left">400</td>
              <td align="left">TXT hostname must use allowed prefix</td>
            </tr>
            <tr>
              <td align="left">txt_value_too_long</td>
              <td align="left">400</td>
              <td align="left">TXT value exceeds 255 characters</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="rate-limiting-headers">
        <name>Rate Limiting Headers</name>
        <t>When rate limiting is applied, responses <bcp14>SHOULD</bcp14> include:</t>
        <ul spacing="normal">
          <li>
            <t><tt>Retry-After</tt>: Seconds until rate limit resets</t>
          </li>
          <li>
            <t><tt>X-RateLimit-Limit</tt>: Maximum requests per window</t>
          </li>
          <li>
            <t><tt>X-RateLimit-Remaining</tt>: Remaining requests in window</t>
          </li>
          <li>
            <t><tt>X-RateLimit-Reset</tt>: Unix timestamp when window resets</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="legacy-compatibility">
      <name>Legacy Compatibility</name>
      <t>For backward compatibility with existing DDNS clients,
providers <bcp14>MAY</bcp14> implement:</t>
      <artwork><![CDATA[
GET /nic/update?hostname={hostname}&myip={ip}
Authorization: Basic {credentials}
]]></artwork>
      <section anchor="legacy-response-codes">
        <name>Legacy Response Codes</name>
        <t>Responses <bcp14>MUST</bcp14> be plain text (not JSON):</t>
        <table>
          <thead>
            <tr>
              <th align="left">Response</th>
              <th align="left">Meaning</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">good {ip}</td>
              <td align="left">Update successful</td>
            </tr>
            <tr>
              <td align="left">nochg {ip}</td>
              <td align="left">No change needed</td>
            </tr>
            <tr>
              <td align="left">badauth</td>
              <td align="left">Authentication failed</td>
            </tr>
            <tr>
              <td align="left">notfqdn</td>
              <td align="left">Invalid hostname</td>
            </tr>
            <tr>
              <td align="left">nohost</td>
              <td align="left">Hostname not found</td>
            </tr>
            <tr>
              <td align="left">abuse</td>
              <td align="left">Account blocked</td>
            </tr>
          </tbody>
        </table>
        <t>This endpoint is provided for compatibility only. New
implementations <bcp14>SHOULD</bcp14> use the modern JSON endpoints.</t>
      </section>
    </section>
    <section anchor="comparison-with-rfc-2136">
      <name>Comparison with RFC 2136</name>
      <t>RFC 2136 <xref target="RFC2136"/> defines DNS UPDATE, a protocol for dynamic
updates to DNS zones. The ApertoDNS Protocol differs in several
key aspects:</t>
      <table>
        <thead>
          <tr>
            <th align="left">Aspect</th>
            <th align="left">RFC 2136</th>
            <th align="left">ApertoDNS Protocol</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">Transport</td>
            <td align="left">DNS (UDP/TCP)</td>
            <td align="left">HTTPS</td>
          </tr>
          <tr>
            <td align="left">Format</td>
            <td align="left">DNS wire format</td>
            <td align="left">JSON</td>
          </tr>
          <tr>
            <td align="left">Auth</td>
            <td align="left">TSIG/SIG(0)</td>
            <td align="left">Bearer tokens</td>
          </tr>
          <tr>
            <td align="left">Discovery</td>
            <td align="left">None</td>
            <td align="left">/info endpoint</td>
          </tr>
          <tr>
            <td align="left">IPv6</td>
            <td align="left">Supported</td>
            <td align="left">Native support</td>
          </tr>
          <tr>
            <td align="left">Bulk ops</td>
            <td align="left">Per-message</td>
            <td align="left">Dedicated endpoint</td>
          </tr>
        </tbody>
      </table>
      <t>The ApertoDNS Protocol is designed for consumer DDNS services
where simplicity and HTTP integration are priorities, while
RFC 2136 is suited for direct DNS zone manipulation.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <section anchor="transport-security">
        <name>Transport Security</name>
        <t>All endpoints <bcp14>MUST</bcp14> be served over HTTPS using TLS 1.2 or higher.
Implementations <bcp14>MUST NOT</bcp14> support plaintext HTTP for any protocol
endpoint.</t>
        <t>Implementations <bcp14>SHOULD</bcp14> support TLS 1.3 and <bcp14>SHOULD</bcp14> disable older
cipher suites known to be weak.</t>
      </section>
      <section anchor="token-security">
        <name>Token Security</name>
        <ul spacing="normal">
          <li>
            <t>Tokens <bcp14>MUST</bcp14> be generated using cryptographically secure random
number generators (CSPRNG)</t>
          </li>
          <li>
            <t>Tokens <bcp14>SHOULD</bcp14> have configurable expiration</t>
          </li>
          <li>
            <t>Providers <bcp14>SHOULD</bcp14> support token revocation</t>
          </li>
          <li>
            <t>Tokens <bcp14>MUST NOT</bcp14> be logged in server access logs</t>
          </li>
          <li>
            <t>Tokens <bcp14>MUST NOT</bcp14> appear in URLs or error messages</t>
          </li>
        </ul>
      </section>
      <section anchor="hostname-validation">
        <name>Hostname Validation</name>
        <t>Before processing any update request, implementations <bcp14>MUST</bcp14> verify
that the authenticated user owns or has permission to modify the
requested hostname. Failure to validate ownership could allow
unauthorized DNS modifications.</t>
      </section>
      <section anchor="rate-limiting">
        <name>Rate Limiting</name>
        <t>Providers <bcp14>SHOULD</bcp14> implement rate limiting to prevent:</t>
        <ul spacing="normal">
          <li>
            <t>Brute-force token guessing</t>
          </li>
          <li>
            <t>Denial of service attacks</t>
          </li>
          <li>
            <t>Excessive DNS propagation load</t>
          </li>
        </ul>
        <t>Rate limits <bcp14>SHOULD</bcp14> be advertised in the discovery endpoint and
communicated via response headers.</t>
      </section>
      <section anchor="dns-rebinding-prevention">
        <name>DNS Rebinding Prevention</name>
        <t>Implementations <bcp14>MUST</bcp14> validate that IP addresses in update requests
are not private, loopback, or link-local addresses unless
explicitly configured to allow such addresses.</t>
      </section>
      <section anchor="input-validation">
        <name>Input Validation</name>
        <t>All user input <bcp14>MUST</bcp14> be validated:</t>
        <ul spacing="normal">
          <li>
            <t>Hostnames <bcp14>MUST</bcp14> conform to DNS naming rules</t>
          </li>
          <li>
            <t>IP addresses <bcp14>MUST</bcp14> be valid IPv4 or IPv6 format</t>
          </li>
          <li>
            <t>TTL values <bcp14>MUST</bcp14> be within acceptable ranges</t>
          </li>
          <li>
            <t>TXT values <bcp14>MUST NOT</bcp14> exceed 255 characters</t>
          </li>
        </ul>
      </section>
      <section anchor="txt-record-abuse-prevention">
        <name>TXT Record Abuse Prevention</name>
        <t>TXT records can potentially be abused for:</t>
        <ul spacing="normal">
          <li>
            <t><strong>DNS tunneling</strong>: Encoding data in TXT records for covert
communication</t>
          </li>
          <li>
            <t><strong>Data exfiltration</strong>: Using DNS queries to leak sensitive data</t>
          </li>
          <li>
            <t><strong>Resource exhaustion</strong>: Creating excessive TXT records</t>
          </li>
        </ul>
        <t>Implementations <bcp14>MUST</bcp14> implement safeguards:</t>
        <ul spacing="normal">
          <li>
            <t>Limit TXT value length to 255 characters (DNS standard)</t>
          </li>
          <li>
            <t>Limit number of TXT records per hostname (default: 5)</t>
          </li>
          <li>
            <t>Restrict TXT hostnames to approved prefixes (e.g., <tt>_acme-challenge.</tt>)</t>
          </li>
          <li>
            <t>Implement rate limiting on TXT operations</t>
          </li>
          <li>
            <t>Consider automatic expiration of TXT records (recommended: 24 hours)</t>
          </li>
        </ul>
      </section>
      <section anchor="internationalized-domain-names">
        <name>Internationalized Domain Names</name>
        <t>When handling Internationalized Domain Names (IDNs), the following
requirements apply as specified in <xref target="RFC5891"/>:</t>
        <ul spacing="normal">
          <li>
            <t>Clients <bcp14>SHOULD</bcp14> convert IDN hostnames to their A-label (ASCII
Compatible Encoding) form before sending requests</t>
          </li>
          <li>
            <t>Servers <bcp14>MUST</bcp14> accept hostnames in A-label form</t>
          </li>
          <li>
            <t>Servers <bcp14>MAY</bcp14> accept hostnames in U-label (Unicode) form and
convert them to A-labels internally</t>
          </li>
          <li>
            <t>Servers <bcp14>MUST</bcp14> store and return hostnames in a consistent form</t>
          </li>
        </ul>
        <t>For example, a client wishing to update the hostname "例え.example.com"
<bcp14>SHOULD</bcp14> send the request with the A-label form "xn--r8jz45g.example.com".</t>
        <t>Implementations that accept U-label input <bcp14>MUST</bcp14> perform IDNA2008
validation as specified in <xref target="RFC5891"/> before processing the request.</t>
      </section>
    </section>
    <section anchor="privacy-considerations">
      <name>Privacy Considerations</name>
      <t>This section addresses privacy considerations as recommended by
<xref target="RFC6973"/>.</t>
      <section anchor="data-minimization">
        <name>Data Minimization</name>
        <t>Providers <bcp14>SHOULD</bcp14> minimize the collection and retention of personal
data. Specifically:</t>
        <ul spacing="normal">
          <li>
            <t>IP address history <bcp14>SHOULD</bcp14> have configurable retention periods</t>
          </li>
          <li>
            <t>Update timestamps <bcp14>MAY</bcp14> be retained for operational purposes</t>
          </li>
          <li>
            <t>Providers <bcp14>SHOULD</bcp14> document their data retention policies</t>
          </li>
        </ul>
      </section>
      <section anchor="user-control">
        <name>User Control</name>
        <t>Users <bcp14>SHOULD</bcp14> have mechanisms to:</t>
        <ul spacing="normal">
          <li>
            <t>View their stored data</t>
          </li>
          <li>
            <t>Delete their accounts and associated data</t>
          </li>
          <li>
            <t>Export their data in a portable format</t>
          </li>
        </ul>
      </section>
      <section anchor="traffic-analysis">
        <name>Traffic Analysis</name>
        <t>DDNS updates inherently reveal:</t>
        <ul spacing="normal">
          <li>
            <t>That a user's IP address has changed</t>
          </li>
          <li>
            <t>The timing of IP address changes</t>
          </li>
          <li>
            <t>The association between a hostname and IP address</t>
          </li>
        </ul>
        <t>Providers should be aware that this information could be used to
track user behavior or network changes.</t>
      </section>
      <section anchor="encryption">
        <name>Encryption</name>
        <t>All communications <bcp14>MUST</bcp14> be encrypted via HTTPS, preventing
passive observation of update requests and tokens.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <section anchor="well-known-uri-registration">
        <name>Well-Known URI Registration</name>
        <t>This document requests registration of the following well-known
URI suffix:</t>
        <dl>
          <dt>URI Suffix:</dt>
          <dd>
            <t>apertodns</t>
          </dd>
          <dt>Change Controller:</dt>
          <dd>
            <t>IETF</t>
          </dd>
          <dt>Specification Document:</dt>
          <dd>
            <t>This document</t>
          </dd>
          <dt>Related Information:</dt>
          <dd>
            <t>None</t>
          </dd>
        </dl>
        <t>The well-known URI <tt>/.well-known/apertodns/</tt> is used as the base
path for all protocol endpoints.</t>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC9110">
          <front>
            <title>HTTP Semantics</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes.</t>
              <t>This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="97"/>
          <seriesInfo name="RFC" value="9110"/>
          <seriesInfo name="DOI" value="10.17487/RFC9110"/>
        </reference>
        <reference anchor="RFC6750">
          <front>
            <title>The OAuth 2.0 Authorization Framework: Bearer Token Usage</title>
            <author fullname="M. Jones" initials="M." surname="Jones"/>
            <author fullname="D. Hardt" initials="D." surname="Hardt"/>
            <date month="October" year="2012"/>
            <abstract>
              <t>This specification describes how to use bearer tokens in HTTP requests to access OAuth 2.0 protected resources. Any party in possession of a bearer token (a "bearer") can use it to get access to the associated resources (without demonstrating possession of a cryptographic key). To prevent misuse, bearer tokens need to be protected from disclosure in storage and in transport. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6750"/>
          <seriesInfo name="DOI" value="10.17487/RFC6750"/>
        </reference>
        <reference anchor="RFC8615">
          <front>
            <title>Well-Known Uniform Resource Identifiers (URIs)</title>
            <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
            <date month="May" year="2019"/>
            <abstract>
              <t>This memo defines a path prefix for "well-known locations", "/.well-known/", in selected Uniform Resource Identifier (URI) schemes.</t>
              <t>In doing so, it obsoletes RFC 5785 and updates the URI schemes defined in RFC 7230 to reserve that space. It also updates RFC 7595 to track URI schemes that support well-known URIs in their registry.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8615"/>
          <seriesInfo name="DOI" value="10.17487/RFC8615"/>
        </reference>
        <reference anchor="RFC8259">
          <front>
            <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
            <author fullname="T. Bray" initials="T." role="editor" surname="Bray"/>
            <date month="December" year="2017"/>
            <abstract>
              <t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t>
              <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability guidance.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="90"/>
          <seriesInfo name="RFC" value="8259"/>
          <seriesInfo name="DOI" value="10.17487/RFC8259"/>
        </reference>
        <reference anchor="RFC5891">
          <front>
            <title>Internationalized Domain Names in Applications (IDNA): Protocol</title>
            <author fullname="J. Klensin" initials="J." surname="Klensin"/>
            <date month="August" year="2010"/>
            <abstract>
              <t>This document is the revised protocol definition for Internationalized Domain Names (IDNs). The rationale for changes, the relationship to the older specification, and important terminology are provided in other documents. This document specifies the protocol mechanism, called Internationalized Domain Names in Applications (IDNA), for registering and looking up IDNs in a way that does not require changes to the DNS itself. IDNA is only meant for processing domain names, not free text. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5891"/>
          <seriesInfo name="DOI" value="10.17487/RFC5891"/>
        </reference>
        <reference anchor="RFC8555">
          <front>
            <title>Automatic Certificate Management Environment (ACME)</title>
            <author fullname="R. Barnes" initials="R." surname="Barnes"/>
            <author fullname="J. Hoffman-Andrews" initials="J." surname="Hoffman-Andrews"/>
            <author fullname="D. McCarney" initials="D." surname="McCarney"/>
            <author fullname="J. Kasten" initials="J." surname="Kasten"/>
            <date month="March" year="2019"/>
            <abstract>
              <t>Public Key Infrastructure using X.509 (PKIX) certificates are used for a number of purposes, the most significant of which is the authentication of domain names. Thus, certification authorities (CAs) in the Web PKI are trusted to verify that an applicant for a certificate legitimately represents the domain name(s) in the certificate. As of this writing, this verification is done through a collection of ad hoc mechanisms. This document describes a protocol that a CA and an applicant can use to automate the process of verification and certificate issuance. The protocol also provides facilities for other certificate management functions, such as certificate revocation.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8555"/>
          <seriesInfo name="DOI" value="10.17487/RFC8555"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="RFC2136">
          <front>
            <title>Dynamic Updates in the Domain Name System (DNS UPDATE)</title>
            <author fullname="P. Vixie" initials="P." role="editor" surname="Vixie"/>
            <author fullname="S. Thomson" initials="S." surname="Thomson"/>
            <author fullname="Y. Rekhter" initials="Y." surname="Rekhter"/>
            <author fullname="J. Bound" initials="J." surname="Bound"/>
            <date month="April" year="1997"/>
            <abstract>
              <t>Using this specification of the UPDATE opcode, it is possible to add or delete RRs or RRsets from a specified zone. Prerequisites are specified separately from update operations, and can specify a dependency upon either the previous existence or nonexistence of an RRset, or the existence of a single RR. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="2136"/>
          <seriesInfo name="DOI" value="10.17487/RFC2136"/>
        </reference>
        <reference anchor="RFC6973">
          <front>
            <title>Privacy Considerations for Internet Protocols</title>
            <author fullname="A. Cooper" initials="A." surname="Cooper"/>
            <author fullname="H. Tschofenig" initials="H." surname="Tschofenig"/>
            <author fullname="B. Aboba" initials="B." surname="Aboba"/>
            <author fullname="J. Peterson" initials="J." surname="Peterson"/>
            <author fullname="J. Morris" initials="J." surname="Morris"/>
            <author fullname="M. Hansen" initials="M." surname="Hansen"/>
            <author fullname="R. Smith" initials="R." surname="Smith"/>
            <date month="July" year="2013"/>
            <abstract>
              <t>This document offers guidance for developing privacy considerations for inclusion in protocol specifications. It aims to make designers, implementers, and users of Internet protocols aware of privacy-related design choices. It suggests that whether any individual RFC warrants a specific privacy considerations section will depend on the document's content.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6973"/>
          <seriesInfo name="DOI" value="10.17487/RFC6973"/>
        </reference>
      </references>
    </references>
    <?line 1002?>

<section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>Thanks to the dynamic DNS community for decades of service
enabling home users and small businesses to maintain stable
hostnames with dynamic IP addresses.</t>
      <t>Thanks to the IETF DNSOP working group participants for their
review and feedback on this specification.</t>
    </section>
    <section anchor="implementation-status">
      <name>Implementation Status</name>
      <t>Note to RFC Editor: Please remove this appendix before publication.</t>
      <t>This section records the status of known implementations of the
protocol defined by this specification.</t>
      <section anchor="apertodns">
        <name>ApertoDNS</name>
        <dl>
          <dt>Organization:</dt>
          <dd>
            <t>ApertoDNS</t>
          </dd>
          <dt>Implementation:</dt>
          <dd>
            <t>Reference implementation</t>
          </dd>
          <dt>Description:</dt>
          <dd>
            <t>Full protocol support including all endpoints, bulk updates,
webhooks, and legacy compatibility</t>
          </dd>
          <dt>Level of Maturity:</dt>
          <dd>
            <t>Production</t>
          </dd>
          <dt>Coverage:</dt>
          <dd>
            <t>Complete</t>
          </dd>
          <dt>Licensing:</dt>
          <dd>
            <t>Proprietary service, open protocol</t>
          </dd>
          <dt>Contact:</dt>
          <dd>
            <t>support@apertodns.com</t>
          </dd>
          <dt>URL:</dt>
          <dd>
            <t>https://apertodns.com</t>
          </dd>
        </dl>
      </section>
    </section>
    <section anchor="openapi-specification">
      <name>OpenAPI Specification</name>
      <t>A complete OpenAPI 3.0.3 specification for this protocol is
available at:</t>
      <t>https://github.com/apertodns/apertodns-protocol/blob/main/openapi.yaml</t>
      <t>This specification can be used to:</t>
      <ul spacing="normal">
        <li>
          <t>Generate client libraries in various programming languages</t>
        </li>
        <li>
          <t>Create interactive API documentation</t>
        </li>
        <li>
          <t>Validate implementations for conformance</t>
        </li>
      </ul>
    </section>
    <section anchor="example-update-flow">
      <name>Example Update Flow</name>
      <t>The following illustrates a typical update flow:</t>
      <ol spacing="normal" type="1"><li>
          <t>Client discovers provider capabilities:
~~~
GET /.well-known/apertodns/v1/info
~~~</t>
        </li>
        <li>
          <t>Client authenticates and requests update:
~~~
POST /.well-known/apertodns/v1/update
Authorization: Bearer example_live_abc123
Content-Type: application/json  </t>
          <t>
{"hostname": "home.example.com", "ipv4": "auto"}
~~~</t>
        </li>
        <li>
          <t>Provider validates token and hostname ownership</t>
        </li>
        <li>
          <t>Provider updates DNS record</t>
        </li>
        <li>
          <t>Provider returns result:
~~~json
{
  "success": true,
  "data": {
    "hostname": "home.example.com",
    "ipv4": "203.0.113.50",
    "changed": true
  }
}
~~~</t>
        </li>
        <li>
          <t>DNS propagates the new record</t>
        </li>
      </ol>
    </section>
    <section anchor="changes-from-legacy-ddns-protocols">
      <name>Changes from Legacy DDNS Protocols</name>
      <t>For implementers familiar with legacy HTTP-based DDNS protocols
(commonly referred to as "dyndns2" in client implementations
such as ddclient), key differences include:</t>
      <ul spacing="normal">
        <li>
          <t>JSON responses instead of plain text</t>
        </li>
        <li>
          <t>Bearer token authentication instead of HTTP Basic</t>
        </li>
        <li>
          <t>Explicit capability negotiation via /info endpoint</t>
        </li>
        <li>
          <t>Dedicated endpoints for different operations</t>
        </li>
        <li>
          <t>Standardized error codes and response formats</t>
        </li>
        <li>
          <t>Native IPv6 support with separate fields</t>
        </li>
        <li>
          <t>Bulk update support for multiple hostnames</t>
        </li>
        <li>
          <t>Well-known URI path for consistent discovery</t>
        </li>
      </ul>
    </section>
    <section anchor="changes-from-00">
      <name>Changes from -00</name>
      <t>This section summarizes changes from draft-ferro-dnsop-apertodns-protocol-00:</t>
      <section anchor="version-123-changes">
        <name>Version 1.2.3 Changes</name>
        <ul spacing="normal">
          <li>
            <t>Added <tt>ipv4_auto_failed</tt> and <tt>ipv6_auto_failed</tt> error codes
to Section 8.3 (Standard Error Codes)</t>
          </li>
          <li>
            <t>Added "Auto-Detection Limitations" subsection to Section 7.3
(Update Endpoint) documenting HTTP connection semantics constraints</t>
          </li>
          <li>
            <t>Added <tt>validation_error</tt> and <tt>invalid_ttl</tt> error codes</t>
          </li>
          <li>
            <t>Added example response for auto-detection failure</t>
          </li>
          <li>
            <t>Updated protocol version in examples from "1.2.0" to "1.3.0"</t>
          </li>
          <li>
            <t>Added acknowledgment of IETF DNSOP working group</t>
          </li>
        </ul>
      </section>
      <section anchor="version-130-changes-txt-records">
        <name>Version 1.3.0 Changes (TXT Records)</name>
        <ul spacing="normal">
          <li>
            <t>Added TXT record management endpoint (/txt) for ACME DNS-01 challenges</t>
          </li>
          <li>
            <t>Added <tt>txt_records</tt> and <tt>txt_max_records</tt> capability fields</t>
          </li>
          <li>
            <t>Added TXT-related error codes: <tt>txt_not_supported</tt>, <tt>txt_limit_exceeded</tt>,
<tt>txt_invalid_name</tt>, <tt>txt_value_too_long</tt></t>
          </li>
          <li>
            <t>Added "TXT Record Abuse Prevention" section to Security Considerations</t>
          </li>
          <li>
            <t>Added RFC 8555 (ACME) to normative references</t>
          </li>
          <li>
            <t>Added TXT Record and ACME DNS-01 terminology definitions</t>
          </li>
          <li>
            <t>Updated protocol version to 1.3.0</t>
          </li>
        </ul>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA819+3LjVnL3/3iKE7kqkVwidZmRPKPaZCNLGlvZucgjzXqd
LZcEEiAJDwhwAVASPTNblf9SlZf4nuT743uVLw+S/nX3uQAkNfLGW7tba1sE
zrW7T99Po9frRU3W5OmR2TiepVVTnr6+NBdV2ZTDMj8yx+ZVmaRVYU4XRTzN
hgav382SuEldq40oHgyq9HblEBtRUg6pK02QVPGo6Y3Sqip7SVGXs17Mzenv
3kyb93b3oiENPi6rxZGpmySq54NpVtdZWTSLGY1yfnb1Ispm1ZFpqnnd7O/u
Pt/dj+IqjY/MGxovbqhpbeIiMa/iIh6n07Rooruyej+uyvnsiHfgG0bv0wW9
TI4iY3om0V3SkuS3+4OGnPO2+efbs8src3xxzj+OT16d8R80MtYf1Q3Nfh3n
ZUHrXaR1NMswPG1QfhpTl1VTpaPa/V5Mw5/DcjqLh438jOJ5MykrXiD9Y0xW
UMPjvnkBSPITge9xkRAUgsdlNY6L7GfeKL22uOF36TTOCL/1fDajtfyrw0Sf
5uYGw3JeNEDCeRPniygqympKI92mWMjbFyf7e3vP9c9ne1891T+f7+3t6p+H
Xx3YP58d7h3YP/cPbLeDZ8/37NODA2oQZcVoaZYnh3a85189oTa9Xs/Eg7qp
CEBRdDXJakMUNgeWTT1Lh9koS2vTTFKzTIzbJjZToWdgcDTPI0t4hmZ26Eef
zVP695Yive4TGAy1vc0SGj02dTqcV+l2pI+qXjwuyrqhvnHe0Pi8B8K4ydNx
PFwYO029be6yZmKkQaTg58nPL26fbuPfh9tmMM/f26lp0fOmBFSG9NYkaZMO
gdHt6OoPV6ZKh0S9ZupInccCSSo5muEkzvO0GPNIRSLUGVdJ9nOaYOgJdcqG
TCRmmlLrIqundR+wTd26zbymfd+led57X5R3hXn39rw2m4QWA+RubZt/u3zz
2sziRV7GSR3JG8L1Fk9qBimd0IoA8j4tupNyW1DLFgCWFvEgT4kUCIwljin9
aiGmTqvbbAgsDKuyJuxnI+Ip2LlFBhYPMplmSUJDRV+YcyLlMpkz3KLodBnN
ftA8L++w26oWTOnU9HxhYuJD4yJNIsJDnNBpqwEVWjQdpqKhf4gyhsRUsrrB
eiZEETiaRI1x47GIoSJFrrkjSIBaMxCAHRQ4A8L6hul7GM/iQZZnzcLQL0xK
wIvzCJielDQ+L3fb1FMamminzgpemYD+vLwiopHd8UKKlBBPix6kEfELmooh
nNazjJh6Hg/fZ8WYWK8lOLdRgur3k4zaAl84mObDBz2inz7RACNMKwLi4vT4
6owpkXAyruKpkC+YD50/OqKCelrhlGDEMKMTXPVG8RCTn7bwTLszdTad5WkV
fXt1ddEbxDXtwB0pQAkbMNSbtmXpm6e3I/OQER2QakxdhTEKToHkcs7HhsBn
WYisr68MBkAx5cj4oyOUO4npHQMTjImoLEA+LxgH0gokoVZHo9T+EkwEWL2d
5wUoHTgG9xpV5ZTg3puUQyCGaA7NX2ZTwhDtK40bYj4EoIaOYNof97dNUSpL
YQZi2foW9fp9WiQEiLwcvu8RgSZzZku0jFmVpU1cLUx6TwuuWRj2zOvSQiKg
uoLkMVGcnJ5fxnLpzDimu+3YJuiSuC+Bv33OQ+YpG08FjxicuuKYR+foUqQN
oaVIalpmSnj64gs/5e8JvLRUoqQOE7uVF27RiQFEsnpY0psF8dJ6RlBIHVQ3
9vpP+rsbW3RORmAIBDgspCbhCfblxiPSaMJ5WkRksqZO81G/A7gqndF89JdA
bpRVdBCg3CxRGY0eu7EjPsIgvEFKnIPWP3OcTU9KMUzN/u7+UzkXdo3FfDqg
c5AVEabzmybymJUZL2iUk2TR5XgaM/EtqQpAD8kunH8ewCKhdwqtzs1iAUeC
Z4PYOQnp9zIg78xunuB5m3F7WvwQDK9OZzFpZGm+EFy+Tf80zyo+P7V5Scxw
TuJNsEkKm4HGVpuNV+8urza25b/m9Rv+++3Zd+/O356d4u/Lb49fvnR/RNri
8ts3716e+r98z5M3r16dvT6VzvTUtB5FG6+Of9gQprrx5uLq/M3r45cbQEHT
wixJOmGvQtyEZpzauI6IoodVNhCy+/rk4v/9n72nxEP/QbUpYqLyA/oU/YBo
kNnKAoyKfxIsF1E8m5E8xShg+HQCMtLRwO4JkBNI5wkJRALkl38EZH48Mr8Z
DGd7T/9FH2DDrYcWZq2HDLPlJ0udBYgrHq2YxkGz9bwD6fZ6j39o/bZwDx7+
5rc5SR7T23v223+JmHq+KQkcQi0rOBJwZXkLi3gm+BKCH8JnjM7Mz7/88qKr
3n35JfTshUgoy8sJA4Xn90wNpLIGqhOGFRkP5CTllFUFqEUV/Rt8CpOxOEjN
YAFZGs/zBpNB4F3S2eTjkGw/pEjxIGKuoScrZI6lbTPLp54Y0HEwehyIDR7g
VDkDDjyGuSTe1VPKxT5us3gF9+CuZyJItOPJSvkhChaJuDnzl7QgTWco55zH
+Jo4xh2kN9tAjR3szQydSSqpPu24FoRDek8yF2sb5hkPRBrfVVpNs6LMy/Gi
K7JYlW3jnI7pFDgHWo+io9Da7ZMNrKrICj3OKums9oguDtyzVhfrev6pXqXa
RZElLkx4XLSsNfrhJnWEJVSU1Z6yiMuUUH5pxrbKRC9YJ6RZvlUllGdRofun
eZyL/FNaZC1188V3p6+31JRIQIcq1HiVNAcollTgckiotGcn5olIu2F7EQoT
KFO31FH0h0TBorrSGazny3NsYzCoU5iMrV4yUmBn8wFI6wYbOib495wVhJku
adt0Rmsags0jYN6JTtYcVuCBdSx6GcGgJmIDdPls6FS6Fquf6xiBvrMBQtjA
SlXCXZjbOJ+D755wW15aOWruIBBgXaaeiKbxexrC7gr4ijs8hYEg1BUSFwDQ
I2mc5hieOdzlyfl578QdF3NG2wFTMZvHJ2dbrM6xDlGo0I7lKMH+A+EIBbwG
BfC4LEZEm2dBxUo+bPVPn4Besjnf8lKEoGRpdTmvaGtqjMJRYzFJ2kxJ24+r
QUbaAHGMhtRNQ7uKt8XRMWXhxq3ZBJflED69AgW6W23RAhr+hazIvZV1dHcC
V4MIV1qWzkZcmQ7LJJuBGERHJ6wPFoIN1SWBIdqsN7qhqXip8uYWhy+9e0js
xNbtwDQtcoHZNJipsPp+dEwi3Z1wy+dq1ipIieeTNy+YQmietkVO9ncziW52
+v7xjvPs7Nzu7dyIdvU1GVDU/iVRaskuFyyka7CwpgCOkrKW4VfCsxOz/POf
/xxNmmZWH+3sfHCOEAHpp/Vr4H4MJKirRJhdr4Kg6XAPaCJ5QmKiDq1qJ3K8
FOraVrJL2ht3uCIyiBiset6YoKxkNAM6LKluFysCWG9Iw8qV/HZ+qsviJpqm
CUk+JilZ4P4BNLZ5kYOblNSrusugf1vbwiqyOs0L9mzZdVhDg2cl/pPPiXfF
tJYyT+mg3tTzIfTiG7IL0py4bsPLaspZlKe3OPuAIhYWfSCa3dDmG+wUTXGy
NnDE6PcH0+/3zafok4D9TSUSs6rKql4/yohUIBmGW2IcdgpuEGdJ6Zc8vuZf
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
xESzMbKj/wHo6j6Iw3UAAA==

-->

</rfc>
