UQRP Protocol
Universal Query Response Protocol for DNS-Based Data Storage
Overview
ResolveDB transforms DNS infrastructure into a data distribution platform. Data is encoded in DNS queries and responses, leveraging global DNS caching for sub-millisecond access.
Client DNS Resolver ResolveDB
| | |
|-- get.newyork.weather.public.v1.resolvedb.net ----->|
| | |
|<-- TXT "v=rdb1;s=ok;d={"temp":72}" -----------------|
| | |
|-- (cached locally) ------>| |Query Format
UQRP queries are structured DNS hostnames with each component serving a specific purpose:
<operation>.<params>.<resource>.<namespace>.<version>.resolvedb.<tld>| Component | Required | Description |
|---|---|---|
| operation | Yes | Action to perform (get, put, delete, etc.) |
| params | No | Encoded parameters |
| resource | Yes | Data resource name |
| namespace | Yes | Scope (public, user, system) |
| version | Yes | Protocol version (v1) |
| resolvedb | Yes | Protocol marker |
| tld | Yes | .com, .net, .org, .io |
Examples
# Weather by city name
get.newyork.weather.public.v1.resolvedb.net
# Weather by GPS coordinates (Base64 encoded JSON)
# {"lat":40.7128,"lon":-74.0060} -> eyJsYXQiOjQwLjcxMjgsImxvbiI6LTc0LjAwNjB9
get.b64-eyJsYXQiOjQwLjcxMjgsImxvbiI6LTc0LjAwNjB9.weather.public.v1.resolvedb.net
# Authenticated request
get.auth-eyJhbGciOiJFZDI1NTE5In0.profile.acme.v1.resolvedb.netOperations
| Operation | Description | Auth Required | Transport |
|---|---|---|---|
get | Retrieve data | No (public) / Yes (user) | DNS |
put | Store data | Yes | HTTP API |
delete | Remove data | Yes | HTTP API |
list | List resources | Depends | DNS |
search | Search resources | Depends | DNS |
watch | Subscribe to changes | Yes | DNS (returns WebSocket URL) |
info | Resource metadata | No | DNS |
health | System health | No | DNS |
geoip | Client IP geolocation | No | DNS |
Note: Write operations (
put,delete) are handled via the HTTP API atapi.resolvedb.io, not via DNS queries. DNS is optimized for reads; writes flow through the API.
Parameter Encoding
Parameters requiring special characters are encoded using DNS-safe prefixes. All prefixes use hyphens (-) as separators since colons are not valid in DNS labels per RFC 1035.
| Prefix | Encoding | Use Case |
|---|---|---|
| (none) | Plain alphanumeric | Simple keys |
b64- | Base64 URL-safe | JSON, binary, complex params |
b32- | Base32 | Case-insensitive |
hex- | Hexadecimal | Binary hashes |
auth- | JWT token | Authentication |
chunk- | Chunk reference | Large data |
h- | Hash reference | Content-addressed |
ts- | Unix timestamp | Replay protection |
nonce- | Random string | Replay protection |
cursor- | Pagination cursor | List/search pagination |
limit- | Result limit | Pagination (1-1000) |
offset- | Result offset | Pagination |
geo- | Coordinates | GeoIP queries |
Token Hash References
JWT tokens often exceed the 63-character DNS label limit. Use hash references for long tokens:
# Full token (may exceed label limit)
get.auth-eyJhbGciOi...longtoken....resource.namespace.v1.resolvedb.net
# Hash reference (always fits)
get.auth-h-a1b2c3d4e5f6g7h8i9j0k1l2.resource.namespace.v1.resolvedb.netRegister your token via the API to receive a hash reference. Hash references require at least 32 hex characters (128 bits).
Response Format
Responses are returned as DNS TXT records with a structured format:
v=rdb1;s=<status>;t=<type>;e=<encoding>;f=<format>;ttl=<seconds>;d=<data>| Field | Description | Values |
|---|---|---|
v | Protocol version | rdb1 |
s | Status code | ok, notfound, auth, error... |
t | Response type | data, url, multi, stream, encrypted |
e | Encoding | plain, b64, b32, hex, compressed, encrypted |
f | Format | json, xml, text, binary |
h | SHA-256 hash | First 16+ hex chars |
ttl | Cache duration | Seconds |
err | Error code | E001-E017 |
retry | Retry after | Seconds |
d | Data payload | Encoded data |
Response Examples
# Success with JSON
v=rdb1;s=ok;t=data;e=plain;f=json;ttl=300;d={"temp":72,"unit":"F"}
# URL redirect for large data
v=rdb1;s=redirect;t=url;ttl=3600;d=https://cdn.resolvedb.cloud/blob/abc123
# Rate limited
v=rdb1;s=ratelimit;err=E010;retry=60;ttl=1;d=Rate limit exceededStatus Codes
| Code | HTTP Equiv | Description |
|---|---|---|
ok | 200 | Success |
partial | 206 | Partial content |
redirect | 301 | See URL in data |
invalid | 400 | Malformed query |
auth | 401 | Authentication required |
forbidden | 403 | Access denied |
notfound | 404 | Resource not found |
ratelimit | 429 | Too many requests |
toolarge | 413 | Response exceeds limits |
secviol | 400 | Security violation (signature invalid, replay detected) |
error | 500 | Server error |
unavail | 503 | Service unavailable |
Error Codes
Machine-readable error codes for programmatic handling:
| Code | Status | Description | Retryable |
|---|---|---|---|
E001 | invalid | Malformed query syntax | No |
E002 | invalid | Unknown operation | No |
E003 | invalid | Invalid encoding prefix | No |
E004 | notfound | Resource does not exist | No |
E005 | notfound | Namespace does not exist | No |
E006 | auth | Missing authentication | No |
E007 | auth | Token expired | No |
E008 | auth | Token invalid | No |
E009 | forbidden | Insufficient permissions | No |
E010 | ratelimit | Rate limit exceeded | Yes |
E011 | toolarge | Payload exceeds 64KB | No |
E012 | error | Internal server error | Yes |
E013 | unavail | Service temporarily unavailable | Yes |
E014 | secviol | Encrypted transport required | Yes |
E015 | toolarge | Response requires TCP | Yes |
E016 | secviol | Replay attack detected | No |
E017 | invalid | Cursor validation failed | No |
Namespaces
ResolveDB organizes data into hierarchical namespaces:
resolvedb.<tld>
├── public.resolvedb.<tld> # Public data services
├── user.resolvedb.<tld> # User-owned namespaces
├── system.resolvedb.<tld> # System operations
└── registry.resolvedb.<tld> # Service registryPublic Namespace
Globally accessible data through standardized interfaces:
current.celsius.newyork.weather.v1.public.resolvedb.net
price.aapl.nasdaq.stock.v1.public.resolvedb.netUser Namespace
Isolated data storage for individuals and organizations:
profile.settings.alice.user.resolvedb.net
config.myapp.prod.acme-corp.user.resolvedb.netNamespace Rules
| Rule | Constraint |
|---|---|
| Length | 1-32 characters |
| Characters | a-z, 0-9, - (hyphen) |
| Start/End | Must be alphanumeric |
| Case | Case-insensitive (normalized to lowercase) |
Reserved Namespaces: public, system, registry, admin, root, api, www, cdn, dns, ns*, mail, resolvedb, rdb, and all underscore-prefixed names (_*).
Dual Addressing
Organizations receive both a vanity name and a stable hash ID:
config.myapp.acme-corp.user.resolvedb.net # vanity (readable)
config.myapp.a7f3b2c4e8d9f012.user.resolvedb.net # hash ID (stable)Hash IDs are 16 hex characters (64-bit) and remain stable across renames.
TTL & Caching
ResolveDB leverages the global DNS caching infrastructure. When a response is returned with a TTL, every resolver in the hierarchy caches it independently, dramatically reducing origin queries.
TTL Classes
| Class | TTL | Use Case |
|---|---|---|
immutable | 7 days | Hash-addressed content, versioned data |
stable | 24 hours | Reference data, documentation |
standard | 1 hour | Default for most data |
dynamic | 5 min | User data, frequently changing content |
volatile | 30-60 sec | Real-time status, health checks |
nocache | 0 | Write confirmations, errors |
Write Operations
Write operations (put, delete) use the HTTP API, not DNS. See API Reference for details.
# Create/update a record
curl -X POST https://api.resolvedb.io/api/v1/records \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"record": {"key": "config.myapp.v1", "data": "eyJoZWxsbyI6IndvcmxkIn0="}}'
# Delete a record
curl -X DELETE https://api.resolvedb.io/api/v1/records/rec_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"After a write, data is immediately available via DNS queries.
Pagination
For list and search operations, use cursor-based pagination:
# First page (50 results)
list.limit-50.resources.myapp.v1.resolvedb.net
# Next page (use cursor from previous response)
list.cursor-eyJsYXN0IjoiZm9vIn0.resources.myapp.v1.resolvedb.netResponse includes pagination metadata:
{"items": [...], "cursor": "eyJsYXN0IjoiYmFyIn0", "hasMore": true}Large Data
For data exceeding 4KB, use chunked retrieval:
# 1. Get manifest
dig get.manifest.bigfile.tenant.v1.resolvedb.net TXT
# 2. Retrieve chunks in parallel (format: chunk-index-total-hash)
dig get.chunk-0-5-abc123def4567890.bigfile.tenant.v1.resolvedb.net TYPE=NULL
dig get.chunk-1-5-abc123def4567890.bigfile.tenant.v1.resolvedb.net TYPE=NULLVerify each chunk's hash before reassembly. See PROTOCOL.md for full chunking specification.
Security
ResolveDB implements multiple security layers:
Layer 1: DNSSEC
ECDSA P-256 signing, automatic key rotation, NSEC3 for authenticated denial.
Layer 2: Content Integrity
SHA-256 hash verification, Ed25519 signatures, Unix timestamps for replay protection.
Layer 3: Encryption
AES-256-GCM symmetric encryption, X25519 key exchange, ChaCha20-Poly1305.
Layer 4: Query Privacy
DNS-over-HTTPS (DoH) / DNS-over-TLS (DoT) for sensitive queries.
Authentication
JWT tokens are passed via the auth- prefix:
get.auth-<jwt>.resource.namespace.v1.resolvedb.net
# JWT Claims
{
"sub": "user-id",
"tenant": "namespace",
"exp": 1234567890,
"scopes": ["read", "write"]
}Complete Specification
For the full protocol specification including formal grammar (ABNF), encryption wire formats, WebSocket security, and implementation requirements, see PROTOCOL.md.
Ready to build?
Create an account and start using the UQRP protocol.