REST API Reference

All endpoints return JSON. Errors use standard HTTP status codes with a {"error": "..."} body.

Base URL: http://localhost:3000 (configurable via DUNENA_PORT / DUNENA_HOST)

Interactive API Explorer

Try out all endpoints directly from your browser with our interactive Swagger UI explorer.

Open Explorer

Health Check

GET /health

Returns server health. Does not require authentication.

curl http://localhost:3000/health
{ "status": "ok", "uptime": 42.5 }

Get a Value

GET /cache/:key

Retrieve a cached value by key. Returns 404 if the key does not exist.

Query Parameters

ParamTypeDescription
nsstringOptional namespace to scope the key
# Simple get
curl http://localhost:3000/cache/mykey

# Namespaced get
curl "http://localhost:3000/cache/mykey?ns=sessions"

Response (200)

{ "key": "mykey", "value": "hello world" }

Response (404)

{ "error": "Key not found" }

Set a Value

POST /cache/:key

Store a value in the cache. Creates or overwrites the key.

Query Parameters

ParamTypeDescription
nsstringOptional namespace (also accepted in body)

Request Body

FieldTypeRequiredDescription
valuestringYesThe value to store (max 4 MB)
ttlintegerNoTime-to-live in milliseconds
nsstringNoNamespace (query param takes precedence)
# Set with TTL of 60 seconds
curl -X POST http://localhost:3000/cache/session-abc \
  -H "Content-Type: application/json" \
  -d '{"value": "{\"user\":\"alice\"}", "ttl": 60000}'

# Namespaced set
curl -X POST "http://localhost:3000/cache/token?ns=auth" \
  -H "Content-Type: application/json" \
  -d '{"value": "abc123"}'

Response (201)

{ "ok": true }

Delete a Value

DELETE /cache/:key

Remove a key from the cache.

Query Parameters

ParamTypeDescription
nsstringOptional namespace
curl -X DELETE "http://localhost:3000/cache/mykey?ns=sessions"

Response (200)

{ "deleted": true }

Batch Operations

Multi-Get (mget)

POST /cache

Retrieve multiple keys in one request.

curl -X POST http://localhost:3000/cache \
  -H "Content-Type: application/json" \
  -d '{"action": "mget", "keys": ["k1", "k2", "k3"]}'
{ "result": { "k1": "val1", "k2": "val2", "k3": null } }

Multi-Set (mset)

POST /cache

Store multiple key-value pairs in one request.

curl -X POST http://localhost:3000/cache \
  -H "Content-Type: application/json" \
  -d '{
    "action": "mset",
    "entries": [
      {"key": "k1", "value": "v1"},
      {"key": "k2", "value": "v2", "ttl": 30000}
    ],
    "ns": "myapp"
  }'
{ "stored": 2 }

Key Scanning

GET /keys

Scan and list keys matching a pattern. Supports cursor-based pagination.

Query Parameters

ParamTypeDefaultDescription
patternstring*Glob pattern (* and ? wildcards)
nsstringFilter to a namespace
cursorinteger0Pagination cursor
countinteger100Max keys to return (cap: 1000)
curl "http://localhost:3000/keys?pattern=user-*&ns=sessions&count=50"
{ "cursor": 0, "keys": ["user-1", "user-2", "user-3"] }

When cursor is 0 in the response, there are no more results. Pass the returned cursor to get the next page.

Stats & Info

GET /stats

Returns cache statistics and latency data.

{
  "cache": {
    "hits": 1245, "misses": 302, "evictions": 10,
    "puts": 1500, "deletes": 45, "currentSize": 1444,
    "maxSize": 100000, "hitRate": 0.805
  },
  "latency": {
    "mean": 0.52, "p50": 0.38, "p95": 1.2,
    "p99": 2.8, "min": 0.1, "max": 15.3, "stdDev": 0.6
  }
}
GET /stats/history

Returns 60 most recent analytics snapshots (taken every 60 seconds).

GET /info

Server metadata.

{ "name": "dunena", "version": "0.2.0", "entries": 42, "uptime": 3600 }

Prometheus Metrics

GET /metrics

Returns metrics in Prometheus exposition format.

Published Metrics

MetricTypeDescription
dunena_cache_hits_totalcounterTotal cache hits
dunena_cache_misses_totalcounterTotal cache misses
dunena_cache_evictions_totalcounterTotal LRU evictions
dunena_cache_puts_totalcounterTotal writes
dunena_cache_deletes_totalcounterTotal deletes
dunena_cache_entriesgaugeCurrent entry count
dunena_cache_max_entriesgaugeMaximum capacity
dunena_cache_hit_rategaugeHit rate (0–1)
dunena_request_latency_msgaugeLatency quantiles (avg, p50, p95, p99)
dunena_uptime_secondsgaugeServer uptime
# Prometheus scrape config
scrape_configs:
  - job_name: 'dunena'
    static_configs:
      - targets: ['localhost:3000']
    metrics_path: '/metrics'

Flush

POST /flush

Clear all entries from the cache. This also clears the bloom filter and all TTL timers.

curl -X POST http://localhost:3000/flush
{ "flushed": true }

Snapshot

POST /snapshot

Trigger an immediate save of the entire cache to disk. Requires persistence to be enabled. The file is written atomically (temp file + rename).

curl -X POST http://localhost:3000/snapshot
{ "saved": true }
If persistence is disabled, returns { "saved": false }.

SQLite Database Endpoints

Dunena includes a durable SQLite-backed key-value layer exposed under /db*.

MethodPathDescription
GET/db/:keyGet a stored entry (includes metadata/tags)
POST/db/:keyStore/update a DB entry
DELETE/db/:keyDelete a DB entry
POST/dbBatch operations: mget, mset, mdelete, query, deleteByTags
GET/db-statsDatabase statistics
GET/db-keysList DB keys
POST/db-clearClear DB entries
POST/db-purgePurge expired DB entries
# Durable write
curl -X POST http://localhost:3000/db/user:42 \
  -H "Content-Type: application/json" \
  -d '{"value":"{\"name\":\"Alice\"}","tags":["users","active"],"ttl":3600000}'

# Durable read
curl http://localhost:3000/db/user:42

Query Cache Endpoints

MethodPathDescription
GET/query-cache/:keyGet cached query result
POST/query-cacheStore query cache entry
POST/query-cache/invalidateInvalidate by tags or key
GET/query-cache/statsQuery cache stats
POST/query-cache/clearClear query cache

Database Proxy Endpoints

MethodPathDescription
GET/db-proxy/connectorsList registered connectors
POST/db-proxy/registerRegister connector
POST/db-proxy/unregisterUnregister connector
POST/db-proxy/queryExecute proxied query (cache-aware)
POST/db-proxy/invalidateInvalidate cached proxy queries by tags
# Register connector
curl -X POST http://localhost:3000/db-proxy/register \
  -H "Content-Type: application/json" \
  -d '{"name":"supabase","type":"http","connectionString":"https://example.com/query"}'

# Execute query via connector
curl -X POST http://localhost:3000/db-proxy/query \
  -H "Content-Type: application/json" \
  -d '{"connector":"supabase","query":"SELECT * FROM users"}'

Error Responses

StatusMeaning
400Validation error (invalid key, value, TTL, or JSON body)
401Missing or invalid Bearer token
404Key not found or route not found
413Request body exceeds 5 MB
429Rate limit exceeded
500Internal server error

Validation Rules

FieldConstraint
keyNon-empty string, max 512 chars, printable ASCII only
valueString, max 4 MB (UTF-8 encoded)
ttlNon-negative integer (milliseconds), optional