| Internet-Draft | ApertoDNS Protocol | December 2025 |
| Ferro | Expires 4 July 2026 | [Page] |
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.¶
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.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 4 July 2026.¶
Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Discussion of this document takes place on the DNS Operations Working Group mailing list (dnsop@ietf.org).¶
Source for this draft and an issue tracker can be found at https://github.com/apertodns/apertodns-protocol.¶
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.¶
While RFC 2136 [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.¶
This lack of standardization has led to:¶
Inconsistent implementations across providers¶
Security vulnerabilities from ad-hoc designs¶
Limited feature sets (e.g., no native IPv6 support)¶
Vendor lock-in due to proprietary extensions¶
No formal capability negotiation¶
This document specifies the ApertoDNS Protocol as a modern, secure, and fully interoperable alternative designed for the current Internet landscape.¶
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.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The ApertoDNS Protocol is designed with the following goals:¶
Provider-agnostic: Any DDNS provider can implement this protocol using their own domain and branding¶
Secure by default: HTTPS required, bearer token authentication¶
Modern: JSON responses, proper HTTP semantics, native IPv6¶
Discoverable: Self-describing via discovery endpoint¶
Extensible: Capability negotiation allows future enhancements¶
Backward compatible: Optional legacy endpoint for existing clients¶
This document uses the following terms:¶
Dynamic DNS. A service that automatically updates DNS records when a client's IP address changes.¶
An organization or service implementing this protocol to offer DDNS services to users.¶
A fully qualified domain name (FQDN) managed by the provider and associated with a user account.¶
An authentication credential issued by the provider, used to authorize API requests.¶
Server-side determination of the client's IP address from the incoming HTTP request, used when the client specifies "auto" as the IP value.¶
Software or device that makes requests to a DDNS provider to update DNS records.¶
The ASCII-Compatible Encoding (ACE) form of an Internationalized Domain Name label, as defined in [RFC5891].¶
The ApertoDNS Protocol is a RESTful API using JSON over HTTPS.
All protocol endpoints are located under the well-known URI path
/.well-known/apertodns/v1/.¶
Conforming implementations MUST serve all endpoints under:¶
https://{provider-domain}/.well-known/apertodns/v1/
¶
The use of well-known URIs [RFC8615] ensures consistent endpoint discovery across providers.¶
All request and response bodies MUST use the application/json
media type [RFC8259] unless otherwise specified.¶
This section defines the requirements for conforming implementations.¶
This protocol defines two conformance levels:¶
A conforming implementation MUST implement the following endpoints: /info, /health, and /update. A conforming implementation MUST support bearer token authentication. A conforming implementation MUST serve all endpoints over HTTPS.¶
In addition to core conformance requirements, a fully conforming implementation MUST implement: /bulk-update, /status/{hostname}, and /domains endpoints.¶
Implementations MUST accurately advertise their capabilities in the /info endpoint response. Implementations MUST NOT advertise capabilities they do not support.¶
Implementations SHOULD accept requests from any conforming client. Implementations MUST NOT require proprietary extensions for basic DDNS functionality.¶
Protected endpoints require authentication via one of the following methods:¶
Bearer Token (RECOMMENDED) [RFC6750]: Authorization: Bearer {token}¶
API Key Header: X-API-Key: {token}¶
HTTP Basic (legacy only): Authorization: Basic {credentials}¶
Implementations MUST support bearer token authentication. Implementations MAY support additional methods.¶
Tokens SHOULD follow the format:¶
{provider}_{environment}_{random}
¶
Where:¶
{provider}: Provider identifier (e.g., "apertodns", "example")¶
{environment}: Token environment ("live", "test", "sandbox")¶
{random}: Cryptographically secure random string (minimum 32
characters recommended)¶
Example: apertodns_live_Kj8mP2xL9nQ4wR7vY1zA3bC6dE0fG5hI¶
This format enables:¶
Tokens MUST be transmitted only in HTTP headers. Tokens MUST NOT appear in URLs, query parameters, or request bodies where they might be logged.¶
GET /.well-known/apertodns/v1/info¶
The discovery endpoint returns provider information, capabilities, and configuration. This endpoint MUST NOT require authentication.¶
| Field | Type | Required | Description |
|---|---|---|---|
| protocol | string | YES | MUST be "apertodns" |
| protocol_version | string | YES | Semantic version (e.g., "1.2.0") |
| provider | object | YES | Provider information |
| capabilities | object | YES | Supported features |
| authentication | object | YES | Supported auth methods |
| endpoints | object | YES | Available endpoint paths |
| rate_limits | object | NO | Rate limiting configuration |
| server_time | string | NO | Current server time (ISO 8601) |
The capabilities object MUST include the following fields:¶
| Field | Type | Description |
|---|---|---|
| ipv4 | boolean | IPv4 address updates supported |
| ipv6 | boolean | IPv6 address updates supported |
| auto_ip_detection | boolean | Automatic IP detection supported |
| bulk_update | boolean | Bulk update endpoint available |
| max_bulk_size | integer | Maximum hostnames per bulk request |
The capabilities object MAY include the following OPTIONAL fields:¶
| Field | Type | Description |
|---|---|---|
| webhooks | boolean | Provider-specific webhook support available |
When webhooks 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 SHOULD document their webhook
API separately.¶
The capabilities object MAY include additional fields for future extensions. Unknown capability fields SHOULD be ignored by clients.¶
{
"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"
}
}
¶
GET /.well-known/apertodns/v1/health¶
Returns service health status. This endpoint MUST NOT require authentication and SHOULD be used for monitoring.¶
{
"success": true,
"data": {
"status": "healthy",
"timestamp": "2025-01-01T12:00:00.000Z"
}
}
¶
The status field MUST be one of: "healthy", "degraded", or
"unhealthy".¶
POST /.well-known/apertodns/v1/update
Authorization: Bearer {token}
Content-Type: application/json
¶
Updates DNS records for a single hostname. This endpoint MUST require authentication.¶
| Field | Type | Required | Description |
|---|---|---|---|
| hostname | string | YES | Fully qualified domain name |
| ipv4 | string | NO | IPv4 address or "auto" |
| ipv6 | string | NO | IPv6 address or "auto" |
| ttl | integer | NO | Time to live in seconds (60-86400) |
At least one of ipv4 or ipv6 SHOULD be provided. If neither
is provided, implementations SHOULD use auto-detection for IPv4.¶
The special value "auto" instructs the server to detect the client's IP address from the incoming request.¶
{
"hostname": "home.example.com",
"ipv4": "auto",
"ttl": 300
}
¶
{
"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"
}
}
¶
The changed field indicates whether the IP address was actually
modified (false if the new IP matches the existing record).¶
POST /.well-known/apertodns/v1/bulk-update
Authorization: Bearer {token}
Content-Type: application/json
¶
Updates multiple hostnames in a single request. Providers
advertising bulk_update: true in capabilities MUST implement
this endpoint.¶
{
"updates": [
{"hostname": "home.example.com", "ipv4": "auto"},
{"hostname": "office.example.com", "ipv4": "203.0.113.51"}
]
}
¶
{
"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
}
]
}
}
¶
GET /.well-known/apertodns/v1/status/{hostname}
Authorization: Bearer {token}
¶
Returns current DNS record status for a hostname.¶
{
"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"
}
}
¶
GET /.well-known/apertodns/v1/domains
Authorization: Bearer {token}
¶
Returns list of domains and hostnames available to the authenticated user.¶
{
"success": true,
"data": {
"domains": [
{
"domain": "example.com",
"hostnames": ["home.example.com", "office.example.com"]
}
]
}
}
¶
Implementations MUST use appropriate HTTP status codes as defined in [RFC9110]:¶
| Status | Usage |
|---|---|
| 200 | Successful request |
| 400 | Invalid request (bad hostname, invalid IP) |
| 401 | Missing or invalid authentication |
| 403 | Not authorized for requested resource |
| 404 | Resource not found |
| 429 | Rate limit exceeded |
| 500 | Server error |
{
"success": false,
"error": {
"code": "error_code",
"message": "Human-readable description"
}
}
¶
| Code | HTTP Status | Description |
|---|---|---|
| unauthorized | 401 | Missing authentication |
| invalid_token | 401 | Invalid or expired token |
| forbidden | 403 | Not authorized for resource |
| not_found | 404 | Hostname not found |
| rate_limited | 429 | Too many requests |
| invalid_hostname | 400 | Invalid hostname format |
| invalid_ip | 400 | Invalid IP address format |
| hostname_not_owned | 403 | User does not own hostname |
For backward compatibility with existing DDNS clients, providers MAY implement:¶
GET /nic/update?hostname={hostname}&myip={ip}
Authorization: Basic {credentials}
¶
Responses MUST be plain text (not JSON):¶
| Response | Meaning |
|---|---|
| good {ip} | Update successful |
| nochg {ip} | No change needed |
| badauth | Authentication failed |
| notfqdn | Invalid hostname |
| nohost | Hostname not found |
| abuse | Account blocked |
This endpoint is provided for compatibility only. New implementations SHOULD use the modern JSON endpoints.¶
RFC 2136 [RFC2136] defines DNS UPDATE, a protocol for dynamic updates to DNS zones. The ApertoDNS Protocol differs in several key aspects:¶
| Aspect | RFC 2136 | ApertoDNS Protocol |
|---|---|---|
| Transport | DNS (UDP/TCP) | HTTPS |
| Format | DNS wire format | JSON |
| Auth | TSIG/SIG(0) | Bearer tokens |
| Discovery | None | /info endpoint |
| IPv6 | Supported | Native support |
| Bulk ops | Per-message | Dedicated endpoint |
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.¶
All endpoints MUST be served over HTTPS using TLS 1.2 or higher. Implementations MUST NOT support plaintext HTTP for any protocol endpoint.¶
Implementations SHOULD support TLS 1.3 and SHOULD disable older cipher suites known to be weak.¶
Before processing any update request, implementations MUST verify that the authenticated user owns or has permission to modify the requested hostname. Failure to validate ownership could allow unauthorized DNS modifications.¶
Providers SHOULD implement rate limiting to prevent:¶
Rate limits SHOULD be advertised in the discovery endpoint and communicated via response headers.¶
Implementations MUST validate that IP addresses in update requests are not private, loopback, or link-local addresses unless explicitly configured to allow such addresses.¶
All user input MUST be validated:¶
When handling Internationalized Domain Names (IDNs), the following requirements apply as specified in [RFC5891]:¶
Clients SHOULD convert IDN hostnames to their A-label (ASCII Compatible Encoding) form before sending requests¶
Servers MUST accept hostnames in A-label form¶
Servers MAY accept hostnames in U-label (Unicode) form and convert them to A-labels internally¶
Servers MUST store and return hostnames in a consistent form¶
For example, a client wishing to update an IDN hostname (U-label form) SHOULD send the request with the A-label form (e.g., "xn--r8jz45g.example.com").¶
Implementations that accept U-label input MUST perform IDNA2008 validation as specified in [RFC5891] before processing the request.¶
This section addresses privacy considerations as recommended by [RFC6973].¶
Providers SHOULD minimize the collection and retention of personal data. Specifically:¶
Users SHOULD have mechanisms to:¶
DDNS updates inherently reveal:¶
That a user's IP address has changed¶
The timing of IP address changes¶
The association between a hostname and IP address¶
Providers should be aware that this information could be used to track user behavior or network changes.¶
All communications MUST be encrypted via HTTPS, preventing passive observation of update requests and tokens.¶
This document requests registration of the following well-known URI suffix:¶
apertodns¶
IETF¶
This document¶
None¶
The well-known URI /.well-known/apertodns/ is used as the base
path for all protocol endpoints.¶
Thanks to the dynamic DNS community for decades of service enabling home users and small businesses to maintain stable hostnames with dynamic IP addresses.¶
Note to RFC Editor: Please remove this appendix before publication.¶
This section records the status of known implementations of the protocol defined by this specification.¶
ApertoDNS¶
Reference implementation¶
Full protocol support including all endpoints, bulk updates, webhooks, and legacy compatibility¶
Production¶
Complete¶
Proprietary service, open protocol¶
support@apertodns.com¶
https://apertodns.com¶
A complete OpenAPI 3.0.3 specification for this protocol is available at:¶
https://github.com/apertodns/apertodns-protocol/blob/main/openapi.yaml¶
This specification can be used to:¶
The following illustrates a typical update flow:¶
Client discovers provider capabilities: ~~~ GET /.well-known/apertodns/v1/info ~~~¶
Client authenticates and requests update: ~~~ POST /.well-known/apertodns/v1/update Authorization: Bearer example_live_abc123 Content-Type: application/json¶
{"hostname": "home.example.com", "ipv4": "auto"} ~~~¶
Provider validates token and hostname ownership¶
Provider updates DNS record¶
Provider returns result: ~~~json { "success": true, "data": { "hostname": "home.example.com", "ipv4": "203.0.113.50", "changed": true } } ~~~¶
DNS propagates the new record¶
For implementers familiar with legacy HTTP-based DDNS protocols (commonly referred to as "dyndns2" in client implementations such as ddclient), key differences include:¶
JSON responses instead of plain text¶
Bearer token authentication instead of HTTP Basic¶
Explicit capability negotiation via /info endpoint¶
Dedicated endpoints for different operations¶
Standardized error codes and response formats¶
Native IPv6 support with separate fields¶
Bulk update support for multiple hostnames¶
Well-known URI path for consistent discovery¶