Unit, Sun & Moon Services

Tokenless public DNS services for unit conversion, solar events, and lunar phase.

Overview

ResolveDB ships three pure-compute public data services. Like weather and GeoIP, they live in the public.v1 namespace, require no token, are unmetered, and are fully cacheable. Every result is computed from mathematical constants on the server (no external provider, no network), so the same query always returns the same answer.

ServiceResourceWhat it returns
Unit conversionunitsA value converted between two units in the same category
SunsunSunrise, sunset, solar noon, civil twilight, day length
MoonmoonMoon phase, illumination, age, next full/new moon

Try any of these live in the Query Console or the Try It Live runner.


Unit Conversion

Convert a numeric value between two units in the same category. Cross-category conversions (e.g. length to mass) are rejected.

Query Format

# Single params label: <value>-<from>-to-<to>
dig TXT get.100-c-to-f.units.public.v1.resolvedb.net +short

# DoH (HTTPS) JSON API
curl -s "https://api.resolvedb.io/resolve?name=get.100-c-to-f.units.public.v1.resolvedb.net&type=TXT" | jq

The value uses DNS-safe encoding: d is the decimal point and a leading n is a negative sign (DNS labels cannot contain . or a leading -).

You wantValue tokenExample query
0.50d5get.0d5-c-to-f.units...
-40n40get.n40-c-to-f.units...
55get.5-km-to-mi.units...

Categories & Unit Slugs

CategoryUnit slugs
temperaturec (celsius), f (fahrenheit), k (kelvin)
lengthm, km, cm, mm, mi, yd, ft, in
masskg, g, mg, t (tonne), lb, oz
volumel, ml, gal (US), qt (US), floz (US)
speedms (m/s), kmh, mph, kn (knot)

Examples

# Temperature: 100 C to F
dig TXT get.100-c-to-f.units.public.v1.resolvedb.net +short

# Length: 5 km to miles
dig TXT get.5-km-to-mi.units.public.v1.resolvedb.net +short

# Mass: 1 lb to kg
dig TXT get.1-lb-to-kg.units.public.v1.resolvedb.net +short

# Volume: 1 US gallon to litres
dig TXT get.1-gal-to-l.units.public.v1.resolvedb.net +short

# Speed: 60 mph to km/h
dig TXT get.60-mph-to-kmh.units.public.v1.resolvedb.net +short

Response Format

in=100;from=celsius;to=fahrenheit;r=212;cat=temperature

Response Fields

FieldDescriptionExample
inInput value (parsed)100
fromCanonical source unit namecelsius
toCanonical target unit namefahrenheit
rConversion result (6 significant figures)212
catUnit categorytemperature

Errors

CauseResult
Malformed expression (not <value>-<from>-to-<to>)FormErr
Invalid numeric value (NaN, exponent, double decimal)FormErr
Unknown unit slugFormErr
Units in different categoriesFormErr

Sun

Sunrise, sunset, solar noon, civil twilight, and day length for a location on the current UTC day. The location grammar is identical to the weather service.

Query Format

# By city name
dig TXT get.london.sun.public.v1.resolvedb.net +short

# By coordinates (d = decimal point, _ separates lat/lon)
dig TXT get.40d7128_-74d0060.sun.public.v1.resolvedb.net +short

# By IP geolocation
dig TXT get.ip-8-8-8-8.sun.public.v1.resolvedb.net +short

# By what3words (hyphens replace dots)
dig TXT get.w3w-filled-count-soap.sun.public.v1.resolvedb.net +short

# DoH (HTTPS)
curl -s "https://api.resolvedb.io/resolve?name=get.london.sun.public.v1.resolvedb.net&type=TXT" | jq

Location Input Formats

FormatExampleDescription
City nameget.london.sun...City name, hyphens for multi-word
Coordinatesget.51d5074_-0d1278.sun...Lat/lon with d as decimal, _ separator
IP addressget.ip-8-8-8-8.sun...Location of the IP
what3wordsget.w3w-filled-count-soap.sun...3m x 3m precision

Response Format

rise=2024-09-01T05:13:00Z;set=2024-09-01T18:42:00Z;noon=2024-09-01T11:57:00Z;dawn=2024-09-01T04:40:00Z;dusk=2024-09-01T19:15:00Z;daylen=13h29m

Response Fields

FieldDescriptionExample
riseSunrise (ISO 8601 UTC)2024-09-01T05:13:00Z
setSunset (ISO 8601 UTC)2024-09-01T18:42:00Z
noonSolar noon (always present)2024-09-01T11:57:00Z
dawnCivil dawn (ISO 8601 UTC)2024-09-01T04:40:00Z
duskCivil dusk (ISO 8601 UTC)2024-09-01T19:15:00Z
daylenDay length (XhYm)13h29m

Polar Day & Night

At high latitudes a day may have no sunrise or sunset. In that case the response replaces rise/set with a single polar field, and daylen reflects the extreme. Solar noon is always defined.

# Midnight sun (Svalbard, June solstice)
polar=day;noon=2024-06-21T11:00:00Z;daylen=24h0m

# Polar night (Svalbard, December solstice)
polar=night;noon=2024-12-21T11:00:00Z;daylen=0h0m
FieldDescriptionExample
polarday (midnight sun) or night (polar night)day

Moon

Moon phase, illuminated fraction, age, and the next full and new moon dates. Location-independent.

Query Format

# Today (UTC) — no params
dig TXT get.moon.public.v1.resolvedb.net +short

# A specific UTC date (strict YYYY-MM-DD)
dig TXT get.2024-01-25.moon.public.v1.resolvedb.net +short

# DoH (HTTPS)
curl -s "https://api.resolvedb.io/resolve?name=get.2024-01-25.moon.public.v1.resolvedb.net&type=TXT" | jq

The date label is validated strictly as a real calendar date (leap years and month lengths are checked); a malformed or impossible date returns FormErr.

Response Format

phase=Full Moon;illum=0.999;age=14.8;next_full=2024-02-24;next_new=2024-02-09

Response Fields

FieldDescriptionExample
phasePhase nameFull Moon
illumIlluminated fraction of the disc (0.0–1.0)0.999
ageAge in days since the last new moon14.8
next_fullDate of the next full moon (UTC)2024-02-24
next_newDate of the next new moon (UTC)2024-02-09

Phase Names

phase is one of eight canonical names:

New Moon, Waxing Crescent, First Quarter, Waxing Gibbous, Full Moon, Waning Gibbous, Last Quarter, Waning Crescent.


Parsing Responses

All three services use the same ;-separated key=value UQRP body, so one parser handles every service.

const dns = require('dns').promises;

async function query(qname) {
  const records = await dns.resolveTxt(qname);
  const response = records[0].join('');
  const fields = {};
  for (const part of response.split(';')) {
    const [key, value] = part.split('=');
    if (key) fields[key] = value;
  }
  return fields;
}

// Unit conversion
const conv = await query('get.100-c-to-f.units.public.v1.resolvedb.net');
console.log(`${conv.in} ${conv.from} = ${conv.r} ${conv.to}`); // 100 celsius = 212 fahrenheit

// Sunrise/sunset for London (today, UTC)
const sun = await query('get.london.sun.public.v1.resolvedb.net');
console.log(`Sunrise ${sun.rise}, sunset ${sun.set}, day ${sun.daylen}`);

// Moon phase for a date
const moon = await query('get.2024-01-25.moon.public.v1.resolvedb.net');
console.log(`${moon.phase} (${Math.round(moon.illum * 100)}% illuminated)`);
import dns.resolver

def query(qname):
    answers = dns.resolver.resolve(qname, 'TXT')
    response = str(answers[0]).strip('"')
    fields = {}
    for part in response.split(';'):
        if '=' in part:
            key, value = part.split('=', 1)
            fields[key] = value
    return fields

# 5 km to miles
conv = query('get.5-km-to-mi.units.public.v1.resolvedb.net')
print(f"{conv['in']} {conv['from']} = {conv['r']} {conv['to']}")

# Moon phase today
moon = query('get.moon.public.v1.resolvedb.net')
print(f"{moon['phase']}: {float(moon['illum']) * 100:.0f}% illuminated")

Next Steps