API Version 2

Advanced dynamic DNS API with domain-specific tokens

Back to API Overview
Overview

The V2 API provides enhanced security and features with domain-specific tokens. Each domain has its own token, providing better access control and security.

Recommended for new integrations: V2 API offers better security, detailed error responses, and more granular control.
Authentication

V2 API uses domain-specific tokens. Each domain has its own token that can only update that specific domain. You can manage tokens in your domain settings.

Better Security: Domain-specific tokens limit access to individual domains, reducing security risks.
Update Records
Endpoint:
POST /api/v2/update
Method:
  • POST - updates modify state
Parameters:
  • token - Domain-specific token (required)
  • ipv4 - IPv4 address (optional)
  • ipv6 - IPv6 address (optional)
  • txt - TXT record value (optional)
Request Body: Parameters may be sent via application/json body, form-encoded body, or query string. Example JSON body:
{
  "token": "domain_token",
  "ipv4": "192.0.2.10",
  "ipv6": "2001:db8::1",
  "txt": "Hello World"
}
Optional Parameter Behavior:
  • Omit parameter: Retains the existing value for the field omitted
  • Include with empty value: Clears the field
Examples:

Update IPv4 only:

POST /api/v2/update?token=domain_token&ipv4=192.168.1.100

Update IPv6 only:

POST /api/v2/update?token=domain_token&ipv6=2001:db8::1

Update TXT record only:

POST /api/v2/update?token=domain_token&txt=Hello World

Update multiple records:

POST /api/v2/update?token=domain_token&ipv4=192.168.1.100&ipv6=2001:db8::1&txt=Hello World

Clear/unset a field (pass empty value):

POST /api/v2/update?token=domain_token&ipv4=&txt=
This clears the IPv4 and TXT records, but leaves IPv6 unchanged
Efficient: You can update any combination of IPv4, IPv6, and TXT records in a single request.
TXT Record Behavior: Any TXT records you set will be served as wildcards on the subdomain. This means the TXT record will be available for any subdomain of your domain (e.g., if you set a TXT record for example.puffindns.org, it will also be available for *.example.puffindns.org).
Auto-Detect Endpoints

For clients that cannot determine their own IPs, the following specialized endpoints accept only a token and update a single record based on the request's source IP address:

Endpoint Method Params Effect
/api/v2/auto-ipv4 POST token (required) Sets IPv4 to the request's IPv4 address. Leaves IPv6/TXT unchanged. Returns 400 if no IPv4 is detectable (e.g., IPv6-only connection).
/api/v2/auto-ipv6 POST token (required) Sets IPv6 to the request's IPv6 address. Leaves IPv4/TXT unchanged. Returns 400 if no IPv6 is detectable (e.g., IPv4-only connection).
Reverse proxy headers are honored when determining the caller IP. If an address family cannot be determined, the endpoint returns 400.
Response

The endpoint returns JSON. Successful responses include previous and new values with per-field change flags, zone serial, and rate limit info. When no change is needed, the response is still 200 with idempotent: true.

HTTP Shape Notes
200
{
  "status": "success",
  "domain": "...",
  "a": "...",
  "aaaa": "...",
  "txt": "...", // optional
  "ttl": 300,
  "updated_at": "2024-01-01T00:00:00Z",
  "idempotent": true, // optional
  "previous": {
    "ipv4": "...",
    "ipv6": "...",
    "txt": "..."
  },
  "changed": {
    "ipv4": true,
    "ipv6": false,
    "txt": true
  },
  "ratelimit_remaining": 100,
  "zone_serial": 2024010101
}
  • idempotent is present and true only when nothing changed
  • txt is included when provided in the request
401 { error: "missing token" } Token not provided
403 { error: "unauthorised" } Token invalid or expired
400 { error: string } Validation error (see examples below)
429 { error: "Rate limit exceeded", retry_after: epochSeconds } Too many requests
500 { error: string } Unexpected server error (temporary)
Success Examples

Updated records:

{
  "status": "success",
  "domain": "example.puffindns.org.",
  "a": "192.0.2.10",
  "aaaa": "2001:db8::1",
  "txt": "Hello World",
  "ttl": 300,
  "updated_at": "2025-09-12T12:34:56+00:00",
  "previous": { "ipv4": "192.0.2.5", "ipv6": "2001:db8::1", "txt": null },
  "changed": { "ipv4": true, "ipv6": false, "txt": true },
  "ratelimit_remaining": 9,
  "zone_serial": 2025091201
}

No change needed (idempotent):

{
  "status": "success",
  "domain": "example.puffindns.org.",
  "a": "192.0.2.10",
  "aaaa": "2001:db8::1",
  "ttl": 300,
  "updated_at": "2025-09-12T12:34:56+00:00",
  "idempotent": true,
  "previous": { "ipv4": "192.0.2.10", "ipv6": "2001:db8::1", "txt": null },
  "changed": { "ipv4": false, "ipv6": false, "txt": false },
  "ratelimit_remaining": 9,
  "zone_serial": 2025091201
}
Error Examples
{ "error": "missing token" }
{ "error": "unauthorised" }
{ "error": "Invalid IPv4 address" }
{ "error": "Private IPv6 addresses not allowed" }
{ "error": "No IP addresses or TXT record provided" }
{ "error": "Rate limit exceeded", "retry_after": 1736700000 }
{ "error": "There was a temporary problem updating DNS records. Please try again in a few moments." }
Tips
  • Use HTTPS for all API calls
  • Keep tokens secure
  • Check HTTP status codes
  • Rate limit: 10 requests/minute
  • Use combined updates when possible
Security Features
  • Domain-specific tokens
  • Rate limiting
  • Token expiration
  • Audit logging