UQRP Protocol

Universal Query Response Protocol for DNS-Based Data Storage

Quick Reference: This is a condensed overview. For the complete technical specification including formal grammar (ABNF), encryption wire formats, and implementation requirements, see the Full Protocol Specification.

Shared Answering Contract (Implemented)

The shared UQRP contract is implemented across native DNS, DoT, wire DoH and both JSON entry forms, with real Rails, Go/JavaScript and MCP conformance:

  • Resource versions use v1, v2, and so on, separately from envelope formats and dataset release versions. Zero and leading-zero versions are rejected.
  • Encoded query parameters use case-stable b32- or hex-; Base64 query-label encodings are retired. TXT payload e=b64 means standard padded Base64.
  • All ordinary successes use v=rdb1;s=ok;t=data, including units, sun, and moon; dataset formats remain distinct. When present, d= consumes the remainder.
  • Final DNS responses preserve the agreed error outcomes, validity-bounded TTLs, and zero cache lifetime for authenticated positive and negative answers.
  • Requested DNSSEC material and query analytics extend to DoH.

Repository implementation is distinct from operator deployment and SDK publication.

The hosted-payload slice is implemented in the repository: Rails write/sync, native DNS and DoH, preview Go/JavaScript decoders, and MCP preserve d= content and standard padded Base64 binary. The final d= consumes all remaining text; hello;s=error stays payload, not status metadata.

The hosted-lifecycle slice is implemented too: authorization precedes semantic parameter validation; private positive and negative DNS lifetimes are zero, including SOA/proofs; public positive TTLs are bounded by record expiry. Requested DNSSEC uses one signing generation, and usage counts successful authenticated evaluation even if later signing or delivery fails. Missing/expired values are NOERROR absence, malformed input is FORMERR, denial is REFUSED, and corrupt-state or lookup failure is SERVFAIL. Hosted and schema statistics now include DoH.

The computed-public slice is also implemented: units, moon, and gated mock-only BTC use shared native/DoH answering, flat ordinary success fields, resource TTLs, and requested DNSSEC.

Financial lookups (stock, forex, crypto) also use shared native/DoH answering in the repository. They retain their flat fields, provider fallback, market-aware TTLs, and optional stock reference-provenance triple. Invalid input/MIC returns FORMERR, absent symbols empty NOERROR, provider failures SERVFAIL, and public credential/policy denials REFUSED. Requested signing fails closed; financial statistics cover both transports without private usage. Only get in public.v1 selects a financial provider. Payload ttl= remains a hint; wire HTTP caching uses effective RR TTLs, while JSON remains no-store. Generic and typed Go/JS/MCP conformance is covered by just client-conformance.

Dataset manifests and attestation keys now use shared answering too. Manifests retain rdb-attest.v1, license/provenance, the signed display name, and opaque Ed25519 attestation bytes. manifest.keys.datasets.public.v1.resolvedb.net returns a distinct rdb-attest-keys.v1 public-key envelope, not DNSSEC DNSKEY. Use manifest.bin-acme-v-1d2d0.datasets.public.v1.resolvedb.net for release 1.2.0; omit -v-... for the latest attested release. Public TXT TTL is 3600 seconds; JSON remains no-store. Go/JS/MCP decoding is covered by actual transport fixtures and does not automatically verify either signature layer.

Dataset identity/as-of answering is also shared, with coherent observations and transition-bounded TTLs. Case-stable query encoding and canonical resource versions and all-family native/DoH evaluation analytics are implemented too. Statistics use the selected family (records for hosted units, explicit datasets) with verified private attribution through miss/expiry. Public and dataset reads remain unattributed; canonical versions are preserved through 63 bytes, with absent/malformed versions represented as null on revised errors/denials. During the consumer-first rollout, older analytics rows carry event_contract=query_stats.v1 and a Legacy class label: their resource was label-classified rather than the evaluated family, and unknown/noncanonical legacy versions display null even on hits. Revised events/rows are query_stats.v2; verified legacy namespace attribution is retained. Complete repository conformance does not imply deployment or package publication.

Try it now

Live DNS Query
dig TXT
Query breakdown:
operation:getparams:quebecresource:weathernamespace:publicversion:v1

Overview

ResolveDB encodes public service data and hosted-record reads in DNS queries and responses. Public answers can use shared DNS caching; successful authenticated private answers use TTL 0.

Client                    DNS Resolver              ResolveDB
   |                           |                          |
   |-- get.quebec.weather.public.v1.resolvedb.net ------>|
   |                           |                          |
   |<-- TXT "v=rdb1;s=ok;t=data;e=b64;f=json;d=..." ------|
   |                           |                          |
   |-- (cached locally) ------>|                          |

Query Format

UQRP queries are structured DNS hostnames with each component serving a specific purpose:

<operation>.<params>.<resource>.<namespace>.<version>.resolvedb.<tld>
ComponentRequiredDescription
operationYesShipped DNS operation such as get, geoip, or info
paramsNoEncoded parameters
resourceYesData resource name
namespaceYespublic or one hosted namespace label
versionYesResource version scoped to resource and namespace, such as v1
resolvedbYesProtocol marker
tldYes.net (the only delegated authoritative UQRP TLD today)

Examples

# Weather by city (public service)
dig TXT get.seattle.weather.public.v1.resolvedb.net +short

# Weather by coordinates (d = decimal point, _ separates lat/lon)
dig TXT get.47d6062_-122d3321.weather.public.v1.resolvedb.net +short

# Weather by IP location
dig TXT get.ip-8-8-8-8.weather.public.v1.resolvedb.net +short

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

# 3-day forecast
dig TXT get.seattle.forecast.public.v1.resolvedb.net +short

# GeoIP lookup
dig TXT geoip.ip-8-8-8-8.public.v1.resolvedb.net +short

# Stock quote
dig TXT get.AAPL.stock.public.v1.resolvedb.net +short

# Forex rate
dig TXT get.USD-EUR.forex.public.v1.resolvedb.net +short

# Crypto price
dig TXT get.BTC-USD.crypto.public.v1.resolvedb.net +short

# Authenticated hosted-record request
get.auth-rdbq<52>.config.acme-catalog.v1.resolvedb.net

Operations

OperationDescriptionAuth RequiredTransport
getRetrieve public data or a hosted recordNo (public) / Yes (hosted)DNS
infoResource metadata & JSON SchemaNoDNS + HTTP
geoipGeolocation for an explicit IP parameterNoDNS
manifestAttested dataset manifestNoDNS
identityAttested dataset identity factNoDNS

Note: Write operations (put, delete) are handled via the REST API at api.resolvedb.com, not via DNS queries. DNS is optimized for reads; writes flow through the API.

Schema Discovery (info Operation)

Get JSON Schema for a registered public resource to understand its response format:

# Via DNS
dig TXT info.weather.public.v1.resolvedb.net +short

# Via HTTP (copy-paste any query - operation and params are ignored)
curl 'https://doh.resolvedb.io/schema?q=weather.public.v1.resolvedb.net'
curl 'https://doh.resolvedb.io/schema?q=get.seattle.weather.public.v1.resolvedb.net'

The HTTP /schema response includes:

  • schema: JSON Schema with field types, descriptions, and examples
  • meta: Auth requirements, rate limits, default TTL
  • dns_format: Query template and example response
  • error_responses: Expected error codes and descriptions

The UQRP info query returns only the JSON Schema inside its TXT payload, rather than the complete HTTP metadata document.

See Schema Access in the full spec.

Parameter Encoding

Query parameters use case-stable encodings for parameters requiring special characters. Prefixes use hyphens (-); colons are not valid in DNS labels. Core, Rails hosted-key validation, and preview Go/JS SDK support are implemented.

PrefixEncodingUse Case
(none)ASCII letters, digits, -, _Hosted key labels; public operation-specific grammar
ip-IP addressDots replaced with hyphens (8-8-8-8)
w3w-what3wordsDots replaced with hyphens (filled-count-soap)
b32-Unpadded Base32, canonical lowercaseCase-stable encoded parameters
hex-HexadecimalBinary hashes
auth-Opaque rdbq namespace query tokenPrivate hosted-record authorization

Base64 query labels are unsuitable because DNS treats case variants as the same name while Base64 can decode them to different bytes. This does not affect Base64 inside TXT data or the Base64url dns= HTTP parameter.

b32- uses unpadded RFC4648 a-z2-7, with canonical lowercase output and case-insensitive decoding. The token alphabet is separately 0-9a-v. Padding, nonzero trailing bits, malformed hex, and retired b64-/base64-/rdb- forms are rejected. Decoded bytes keep their case; only DNS spelling is normalized. Private-query authorization runs before semantic decoding.

Public operations interpret decoded text with their normal parameter grammar. For coordinate JSON {"lat":51.4769,"lon":0}, query:

dig TXT get.b32-pmrgyyluei5dkmjogq3tmojmejwg63rchiyh2.weather.public.v1.resolvedb.net +short

The JSON fields are exactly lat and lon; decoded Lat is not silently lowercased. Use Go B32Param or JavaScript b32Param to encode UTF-8 bytes. Hosted keys retain encoded-label order and spelling: Base32, hex, and plain labels remain different keys, even if their decoded values match.

Coordinate Encoding

For lat/lon coordinates, use d as decimal point and _ as separator:

# 47.6062, -122.3321 becomes:
dig TXT get.47d6062_-122d3321.weather.public.v1.resolvedb.net +short

Namespace Query Tokens

Private hosted records use an opaque token minted under the namespace API. The token is placed in the first label after the operation and is returned only once. Parameterized records place their key-parameter labels after it:

get.auth-rdbq<52>.config.acme-catalog.v1.resolvedb.net

Response Format

Successful data answers are DNS TXT records with a semicolon-delimited UQRP envelope. Units, sun, moon, enabled BTC, weather, forecast, and GeoIP begin v=rdb1;s=ok;t=data followed by their flat resource fields. Hosted records use this core shape:

v=rdb1;s=ok;t=data;e=<plain|b64>;f=<json|text>;ttl=<seconds>;d=<payload>

TXT RDATA can contain multiple 255-byte character strings. Concatenate them in order before parsing. Split the envelope at ;d= so payload characters are not mistaken for metadata. Decode d according to e before parsing f=json. The envelope ttl= field is a configured hint. Inspect the DNS answer RR TTL for the effective resolver cache lifetime; successful private RR TTL is always 0.

The query-level failure taxonomy is represented by DNS RCODE. Shared schema, zone-control, hosted, computed-public, location, financial, and dataset answering preserve it on native DNS and DoH, and the preview SDKs and MCP retain these distinctions. Evaluation analytics records the product outcome before response assembly; signing/encoding/delivery failures remain separate transport observations. Only successful authenticated evaluations emit usage.

RCODEMeaning
NOERRORAnswer or NODATA
FORMERRMalformed operation or parameters
SERVFAILProvider, storage, or rendering failure
REFUSEDAuthorization, namespace, or reserved-resource denial

The larger status/error-envelope vocabulary in the full draft is not a promise that every listed status is emitted by the production v1 request paths. E014 is reserved and is not emitted.

Namespaces

ResolveDB places one namespace label in every UQRP name. public selects the public service surface; another non-reserved label identifies a hosted namespace.

Public Namespace

Globally accessible data through standardized interfaces:

get.london.weather.public.v1.resolvedb.net
get.AAPL.stock.public.v1.resolvedb.net

Hosted Namespace

Hosted namespaces are private by default. Use the opaque query token returned by the API over DoH or DoT so passive observers between the client and TLS endpoint cannot read the bearer credential:

get.auth-rdbq<52>.config.acme-catalog.v1.resolvedb.net

Namespace Rules

RuleConstraint
Length3-32 characters
CharactersLowercase a-z, 0-9, - (hyphen)
StartMust be a letter
EndMust be a letter or number
UniquenessGlobally unique, enforced case-insensitively

The dashboard and API enforce a server-maintained reserved-name denylist. Namespace UUIDs identify API resources only and are not DNS aliases.

TTL & Caching

Public service, dataset, and operator-managed public-read answers can be cached according to their DNS TTL. Successful authenticated private-record answers always use TTL 0, regardless of the record's configured ttl_seconds.

Write Operations

Write operations (put, delete) use the HTTP API, not DNS. See API Reference for details.

# Create a record after creating the `acme-catalog` namespace
curl -X POST https://api.resolvedb.com/api/v1/records \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"record": {"key": "config.acme-catalog.v1", "data": "eyJoZWxsbyI6IndvcmxkIn0="}}'

# Delete a record
curl -X DELETE https://api.resolvedb.com/api/v1/records/<record-uuid> \
  -H "Authorization: Bearer YOUR_API_KEY"

After the sync fleet applies the write, the record is available through the private-record gate using a namespace query token.

Record listing is provided by GET /api/v1/records; DNS list, search, and chunk retrieval are not implemented in UQRP v1. Hosted record payloads are limited to 2,586 decoded bytes by the API so the complete rendered UQRP value fits the core's 3,500-byte DNS envelope limit.

Security

ResolveDB implements multiple security layers:

Layer 1: DNSSEC

Native DNS uses ECDSA P-256 and Ed25519 signing with automatically refreshed RRSIGs and NSEC black lies. The shared serving lifecycle pins a coherent zone, DNSKEY set, signer, and validity window for each native response through refresh. The same lifecycle initializes in HTTP-only mode. All shared query families provide requested DoH signatures, denial proofs, and supporting DNSKEY access. Required signing failures return SERVFAIL; signing does not set AD.

Layer 2: Content Integrity

Dataset facts include a separate Ed25519 operator attestation in addition to DNSSEC answer authenticity and integrity.

Layer 3: Encryption

Applications can encrypt hosted values before storing them. ResolveDB does not manage customer plaintext encryption keys.

Layer 4: Query Privacy

DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT) encrypt queries in transit:

MethodEndpointUse Case
DoH JSONdoh.resolvedb.io/resolveBrowsers, debugging
DoH Wiredoh.resolvedb.io/dns-queryRFC 8484 clients
DoTdot.resolvedb.io:853Native TLS clients

See DNS Access Methods for details and code examples.

Authentication

Hosted-product query tokens are passed via the auth- prefix:

get.auth-rdbq<52>.resource.namespace.v1.resolvedb.net

Complete Specification

This quick reference covers the essentials. For comprehensive details, see:


Ready to build?

Create an account and start using the UQRP protocol.