API reference

Base URL https://cache.rucdn.pro/v1. JSON in, JSON out, except the raw object body. Bearer token in Authorization. Everything is idempotent on Idempotency-Key except the raw PUT.

Objects

MethodPathPurpose
PUT/v1/objects/{key}Store or replace an object
GET/v1/objects/{key}Fetch metadata, not the bytes
GET/o/{key}Fetch the cached bytes, byte-range aware
DELETE/v1/objects/{key}Purge immediately
POST/v1/warmPull a key from origin ahead of first request

States

freshstalerevalidatingfresh, or evicted with a reason string. There is no intermediate percentage; ask for ?expand=origin if you want the last upstream response code.

Example

GET /v1/objects/obj_e371bd33?expand=origin

{
  "key": "obj_e371bd33",
  "state": "fresh",
  "size_bytes": 145409,
  "etag": "\"obj_69a44ae4\"",
  "ttl_seconds": 3600,
  "origin": {"status": 200, "cache_control": "max-age=3600"}
}

Warm ahead of traffic

POST /v1/warm
{"key":"obj_69a44ae4","origin_url":"https://example.org/reports/annual.pdf"}

# -> {"key":"obj_69a44ae4","state":"revalidating"}

The warmer follows at most three redirects and refuses anything larger than the configured object ceiling.

Rules

A rule is a named TTL policy in config.toml. Changing a rule does not touch objects already cached under it — call warm again if you want the new TTL applied immediately.

[rule.reports]
match = "/reports/*"
ttl_seconds = 3600
stale_while_revalidate = 600
respect_origin_headers = true

Byte ranges

Range requests are served straight from the on-disk copy once an object is fresh; a partial object is never served as complete. Conditional GET with If-None-Match returns 304 without touching the origin.

Webhooks

EventWhen
object.warmedObject pulled from origin and marked fresh
object.evictedRemoved by TTL, LRU pressure or explicit purge
origin.errorOrigin responded with 5xx or timed out during warm

Delivery is at-least-once with exponential backoff for six hours. Signature is X-Signature: sha256=<hex> over the raw body.

Errors

CodeMeaning
400 invalid_requestBody failed validation, see field
401 unauthenticatedMissing or unknown token
404 not_cachedKey has no entry and no origin_url was given to warm it
413 object_too_largeAbove limits.max_object_bytes
502 origin_unreachableOrigin did not respond within the warm timeout
429 slow_downPer-token bucket empty, honour Retry-After

Limits

Defaults, all configurable: 512 MB per object, 200 GB total cache floor before LRU eviction kicks in, 600 API requests per minute per token. Byte-range GETs are not counted against the API bucket.