Protocol

The wire format and the rules for interpreting it. Everything an SDK does is here. If you are writing your own client, this page plus the golden vectors is the whole contract.

Endpoint

HTTP
GET https://cfg.ripstop.dev/v1/config?key=rs_pub_your_key

No authentication beyond the key in the query string. The key only reads, and everything it returns is signed, so it is safe in a shipped binary.

Request headers

All optional. Each one only adds a column to what the panel can show you.

HeaderSet byWhat it is
x-ripstop-devicethe SDKA random install id, minted on first launch
x-ripstop-useryour codeYour own user id: a Firebase uid, say
x-ripstop-platformthe SDKios · android · web
x-ripstop-app-versionthe SDKThe running build
x-ripstop-modelthe SDKDevice model, e.g. iPhone15,3
if-none-matchthe SDKThe cached ETag; a match answers 304

Response

HeaderWhat it carries
x-ripstop-sigbase64 Ed25519 signature over the raw body bytes
x-ripstop-key-idWhich pinned key signed it. This is how rotation works
etagOpaque version tag for conditional requests
cache-controlIncludes stale-if-error so CDNs keep serving during an outage

Verification

Verify the signature against the raw response bytes, before parsing. There is no canonicalization step anywhere in this protocol: two JSON documents that mean the same thing but order keys differently have different signatures, on purpose.

  • Decode the body as UTF-8 without re-encoding it.
  • Look up the public key by x-ripstop-key-id from your pinned set.
  • Verify. Any failure (unknown key, bad base64, wrong length) is a plain failure.
  • Only then parse the JSON.

Evaluation

maintenance → force → soft → none, first match wins. The exact conditions are on How decisions are made, and encoded as executable cases in the vectors below.

Golden vectors

Every Ripstop SDK runs the same vectors.jsonin CI: version ordering, evaluation order, message fallback, snooze accounting and the fail-open state machine. It is what makes “the SDKs agree” a fact rather than an intention. Adding a vector is a feature; changing one requires an architecture decision record.

⌘K