<?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-00" 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-00"/>
    <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="2025" month="December" day="31"/>
    <area>Operations and Management</area>
    <workgroup>DNS Operations</workgroup>
    <keyword>dynamic dns</keyword>
    <keyword>ddns</keyword>
    <keyword>dns update</keyword>
    <keyword>REST API</keyword>
    <abstract>
      <?line 44?>

<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, 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 56?>

<section anchor="note-to-readers">
      <name>Note to Readers</name>
      <t>Discussion of this document takes place on the DNS Operations
Working Group mailing list (dnsop@ietf.org).</t>
      <t>Source for this draft and an issue tracker can be found at
https://github.com/apertodns/apertodns-protocol.</t>
    </section>
    <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.2.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., "-00") 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>
      </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.2.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>
            </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>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.2.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="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>
      <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>
    <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>
          </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>
        </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 an IDN hostname (U-label form)
<bcp14>SHOULD</bcp14> send the request with the A-label form (e.g., "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>
      </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 789?>

<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>
    </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>
  </back>
  <!-- ##markdown-source:
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
T92F0oL/BqXtKaA4WQAA

-->

</rfc>
