Authentication

Runnev authenticates every request with a bearer token. There are no request signatures and no OAuth dance; a single header is all you need.

The Authorization header

Send your key as a bearer token on every request:

bash
curl https://runnev.dev/v1/streams \
  -H "Authorization: Bearer rnv_live_00112233445566778899aabbccddeeff"

Three endpoints are public and need no key: GET /v1/health, GET /v1/version, and read-only access to the public demo stream. Everything else returns 401 without a valid key.

Key format

A key is a prefix followed by exactly 32 lowercase hexadecimal characters:

PrefixMeaningExample
rnv_live_Live key, full access to its projectrnv_live_00112233445566778899aabbccddeeff
rnv_test_Test key, lower rate limitsrnv_test_2f8c41a6d90b47e3ba15c7e08d3f6a24

The full pattern is rnv_(live|test)_[0-9a-f]{32}. Anything that does not match that shape is rejected as invalid_api_key before we even look it up, so a truncated or mistyped key fails fast.

The public demo key

This key is intentionally public. It can only read the demo stream, it cannot publish, and it is rate limited to 60 requests per minute per IP. It is safe to put in client-side code, and it is what powers the live demo on the home page.

public, read-only
rnv_test_2f8c41a6d90b47e3ba15c7e08d3f6a24

What failures look like

Authentication problems return a structured error. The three you will meet:

Missing key

401 Unauthorized
{
  "error": {
    "type": "authentication_error",
    "code": "missing_api_key",
    "message": "No API key was provided. Send it as: Authorization: Bearer rnv_live_...",
    "request_id": "req_0Kj2wq8ULn4mAe1s",
    "doc_url": "https://runnev.dev/docs/errors#missing_api_key"
  }
}

Malformed or unknown key

401 Unauthorized
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The API key is malformed or does not exist.",
    "request_id": "req_7Za1popL2mn4Ae0s",
    "doc_url": "https://runnev.dev/docs/errors#invalid_api_key"
  }
}

Valid key, wrong project

A key belongs to one project. Using it against a stream in a different project returns 403 with project_forbidden. This is distinct from a 404: the stream exists, your key just may not touch it.

403 Forbidden
{
  "error": {
    "type": "authentication_error",
    "code": "project_forbidden",
    "message": "This key cannot access streams in another project.",
    "request_id": "req_Q3ee1l0Pmn4bAe2s",
    "doc_url": "https://runnev.dev/docs/errors#project_forbidden"
  }
}

Rotation and revocation

Create keys in the dashboard and revoke them there. A revoked key returns 401 with key_revoked on its next use. Rotate without downtime by issuing a new key, deploying it, and revoking the old one once traffic has moved. Keys carry no expiry of their own; a key is valid until you revoke it.

Keep live keys server-side

A rnv_live_ key can publish and delete. Never ship one in a browser bundle, a mobile app, or a public repository. For anything a client device can read, use the read-only demo key or mint a narrowly scoped key and treat it as public. If a key leaks, revoke it; that is the whole remediation.