API reference
The update API is compatible with the DynDNS v2 ("dyndns2") protocol, plus a JSON response mode. Everything is served over HTTPS only.
Endpoint
GET https://ddns.justasrv.com/nic/update
POST https://ddns.justasrv.com/nic/update
/update and /v1/update are aliases.
Authentication
Every hostname has its own token. Send it in one of these ways, in order of preference:
- HTTP Basic: username = the hostname (informational), password = the token.
curl -u 'host:token'. This is what routers do. - Bearer:
Authorization: Bearer jas_… - Parameter:
token=jas_…(orpassword=) in the query or POST body, for devices that cannot set headers. Query strings can end up in proxy or browser histories on the client side; use Basic where possible.
A request without credentials receives 401 with a WWW-Authenticate challenge, which is how many clients discover they must authenticate. It does not count as a failed attempt.
Parameters
| Name | Required | Meaning |
|---|---|---|
hostname | No | Full hostname. If omitted, the token's own hostname is used. If present it must match the token's hostname exactly. One hostname per request. |
myip | No | The address the client believes it has. By default ignored: JustASRV publishes the address the request came from. Honoured only for hosts an administrator set to "accept public myip=", and only if it is a public unicast IPv4 address. ip, myipv4 are accepted aliases; auto means "use the caller's address". |
format | No | json returns JSON (also selected by Accept: application/json). |
POST accepts the same fields as application/x-www-form-urlencoded or a JSON object.
Responses
Text mode returns the dyndns2 code as the body, followed by the address for success codes. HTTP status codes are meaningful too.
| Body | HTTP | Meaning | Client should |
|---|---|---|---|
good 198.51.100.7 | 200 | Address changed and was published (or accepted and queued if the host is changing too quickly). | Remember the address. |
nochg 198.51.100.7 | 200 | Address unchanged; no DNS write was made. Still counts as a heartbeat. | Carry on. |
badauth | 401 | Missing, unknown, revoked or expired token. | Stop and alert a human. Do not retry rapidly. |
nohost | 404 / 403 | The hostname does not belong to this token (404), or the host or customer is disabled (403; JSON status disabled). | Stop and alert a human. |
numhost | 400 | More than one hostname in a request. | Send one per request. |
badip | 400 | The address to publish is not a public IPv4 address (private, CGNAT, reserved, or IPv6 while IPv6 is not enabled). | Fix the configuration. |
abuse | 429 | Rate limit or source block. Retry-After says how long. | Wait at least Retry-After. |
dnserr | 503 | The DNS provider refused or failed. The new address is stored and retried automatically server-side. | Retry later (Retry-After: 300). |
911 | 500 | Unexpected server error. | Retry with backoff. |
JSON mode
{"status": "good", "hostname": "acme-main.ddns.justasrv.com", "ip": "198.51.100.7", "message": ""}
Other endpoints
GET /ip | Caller's public address as plain text (?format=json for {"ip": "…"}). Subject to the per-IP limit. |
GET /healthz | {"status": "ok"} when the API and its database are up; 503 otherwise. |
GET https://status.justasrv.com/api/status.json | Machine-readable service status. |
Rate limits
Defaults (SoMo can tune them). All are enforced server-side across every node.
| Per credential | 20 requests per 10 minutes |
| Per source address | 120 requests per 10 minutes (update + /ip combined) |
| Failed authentication | 10 failures from one address in 15 minutes blocks that address for the rest of the window, even with a valid token |
| DNS writes | more than 12 address changes per hour for one host are accepted but published at most every 5 minutes |
A well-behaved client checks its address every 2–5 minutes and calls the update API only on change, plus an optional heartbeat every 10–20 minutes.
Examples
# curl
curl -u 'acme-main.ddns.justasrv.com:jas_TOKEN' 'https://ddns.justasrv.com/nic/update?hostname=acme-main.ddns.justasrv.com'
# PowerShell
$h = @{ Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('acme-main.ddns.justasrv.com:jas_TOKEN')) }
Invoke-RestMethod 'https://ddns.justasrv.com/nic/update?format=json' -Headers $h
# Python
import requests
r = requests.get("https://ddns.justasrv.com/nic/update", params={"format": "json"},
headers={"Authorization": "Bearer jas_TOKEN"}, timeout=30)
print(r.status_code, r.json())
Security requirements for integrators
- HTTPS only, with certificate verification enabled. Plain HTTP is redirected and never processes credentials.
- Store the token like a password. Never log request URLs or headers that contain it.
- Honour
Retry-After; treatbadauthandnohostas permanent until a human intervenes. - Identify your client with a
User-Agentsuch asYourTool/1.2. It is shown in the update history.
IPv6
The data model and API are IPv6-ready (AAAA records), but IPv6 publication is not enabled yet. ddns.justasrv.com has only an IPv4 address, so clients update over IPv4.