DynDNS API Reference & Setup Guide

Everything you need to keep your DNS record updated automatically.

The update endpoint

Method GET or POST
URL https://ddns.coffee/dyndns/update/
Authentication Authorization: Bearer your-api-token
How to get a token: register a hostname via the registration flow. After an administrator approves your request, you will receive an API token by email. Lost your token? Recover it here.

Parameters

Both query-string (GET) and form-body (POST) parameters are accepted.

Name Required Description
ip No One or more IP addresses, comma-separated. Both IPv4 and IPv6 are accepted. If omitted (and neither clearv4 nor clearv6 is set), the server auto-detects the client's IP. Existing A and AAAA records for the affected hostnames are replaced on every successful update.
clearv4 No Set to true to remove all A records for the affected hostnames without writing new ones.
clearv6 No Set to true to remove all AAAA records for the affected hostnames without writing new ones.
hostname No One or more fully-qualified domain names, comma-separated. Each must be either your registered hostname (e.g. myhost.example.com) or a subdomain of it (e.g. vpn.myhost.example.com). Subdomains are created automatically on first use. When omitted, only the registered hostname is updated. The server returns 403 for any entry that does not belong to your token.

Response format

Success — 200 OK

{
  "status": "ok",
  "updated": ["myhost.example.com.", "vpn.myhost.example.com."],
  "ipv4": ["203.0.113.1"],
  "ipv6": ["2001:db8::1"]
}

updated lists every hostname that was written. ipv4 and ipv6 contain all addresses that were written. Either list may be empty if no addresses of that family were provided.

Error responses

Code Meaning
400 No IP address provided, detected, or parseable.
403 Missing or invalid Authorization header; token does not match any active registration; DynDNS is disabled for the zone; or the supplied hostname does not match the token's registration.
429 Your IP address is currently rate-limited.

Quick examples

Replace YOUR_API_TOKEN and YOUR_HOSTNAME with your own values.

Auto-detect IP

The server uses the IP of the incoming request. Works for both IPv4 and IPv6, but only one address family at a time depending on how your network connects.

curl -s \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://ddns.coffee/dyndns/update/"

Explicit IPv4 address

curl -s \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://ddns.coffee/dyndns/update/?ip=203.0.113.1&hostname=YOUR_HOSTNAME"

Dual-stack (IPv4 + IPv6 in one call)

curl -s \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://ddns.coffee/dyndns/update/?ip=203.0.113.1,2001:db8::1&hostname=YOUR_HOSTNAME"

Detect each address family separately

Useful when your host is dual-stack but you want the server to detect both addresses independently. Note that each call replaces all A/AAAA records, so the second call will overwrite the first. Use the explicit comma-separated form above if you need both in one transaction.

# Force IPv4 connection for the A record
curl -s -4 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://ddns.coffee/dyndns/update/?hostname=YOUR_HOSTNAME"

# Force IPv6 connection for the AAAA record (replaces the above)
curl -s -6 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://ddns.coffee/dyndns/update/?hostname=YOUR_HOSTNAME"

Setting up automatic updates

Shell script + cron

The simplest approach for any Linux/macOS host or server.

Save this as /usr/local/bin/dyndns-update.sh and make it executable (chmod +x):

#!/bin/sh
# Replace with your values
TOKEN="YOUR_API_TOKEN"
HOSTNAME="YOUR_HOSTNAME"
UPDATE_URL="https://ddns.coffee/dyndns/update/"

curl -s \
  -H "Authorization: Bearer $TOKEN" \
  "$UPDATE_URL?hostname=$HOSTNAME" \
  | logger -t dyndns

Add to your crontab (crontab -e) to run every five minutes:

*/5 * * * * /usr/local/bin/dyndns-update.sh

systemd service + timer

A more robust option that integrates with journald logging and waits for the network to be available before the first run.

Create /etc/systemd/system/dyndns-update.service:

[Unit]
Description=DynDNS update
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
Environment=TOKEN=YOUR_API_TOKEN
Environment=HOSTNAME=YOUR_HOSTNAME
Environment=UPDATE_URL=https://ddns.coffee/dyndns/update/
ExecStart=curl -s \
  -H "Authorization: Bearer ${TOKEN}" \
  "${UPDATE_URL}?hostname=${HOSTNAME}"

Create /etc/systemd/system/dyndns-update.timer:

[Unit]
Description=Run DynDNS update every 5 minutes

[Timer]
OnBootSec=30sec
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target

Enable and start the timer:

systemctl daemon-reload
systemctl enable --now dyndns-update.timer

Check the last run:

journalctl -u dyndns-update.service -n 20

Router clients & ddclient

Most consumer DynDNS clients (ddclient, inadyn, OpenWrt/LuCI DynDNS) speak the dyndns2 protocol, which uses HTTP Basic auth with a fixed URL shape. This service uses Bearer token authentication instead, so direct protocol compatibility is not available.

The recommended approach is to use your router's built-in script execution capability or a custom update script. For example, in OpenWrt you can install curl and call the update URL from a hotplug script or a cron job as shown above.

With ddclient 3.11+ you can call an arbitrary URL using the fw-login-by / fw-bannedfailurecount directives or by setting use=cmd with a custom cmd script that calls the endpoint and prints the new IP. Refer to the ddclient documentation for custom protocols.

Tip: if your router only supports dyndns2 and cannot run custom scripts, consider setting up a small cron job on any always-on Linux host inside your network (a Raspberry Pi, NAS, or VPS) and pointing it at your public IP detection service of choice.

Back to DynDNS home