Keys

The four key kinds, what each can do, and which ones may reach a browser.

dev · https://api.dev.oprag.ai

Two kinds of key, each with a live and a test variant. The split that matters is not live versus test — it is integration versus embed, because only one of them may be seen by a visitor.

The one key table. Every other page links here rather than restating it.
PrefixSafe in a browserWhat it can doWhere it is storedBlast radius
embed_test_…YesPublic chat against a fixed test answer. Never reaches your documents, never counts against message quota.Anywhere a browser can read it — HTML attribute, public env var, committed config.None. A leaked test embed key returns the same canned answer to anyone who tries it.
embed_live_…YesThe same calls a live integration key can make, from an allowlisted browser origin only. Cannot read leads, conversations, documents, or keys.Browser-visible config: a data-embed-key attribute or a PUBLIC_-prefixed build variable.Bounded by your origin allowlist and the project it belongs to. Someone who copies it cannot use it from their own domain.
sk_test_…NoThe same reach as a live integration key, but chat returns the fixed test answer instead of touching your documents.Server-side secret store or .env that is not bundled for the browser.Writes real leads and tickets into the workspace even though chat is stubbed. Treat it like a live secret.
sk_live_…NoServer-to-server: chat and streaming chat, message feedback, creating a lead, opening a ticket, and escalating a conversation — plus Extract. Cannot read leads, conversations, or documents: those need a dashboard JWT.Server-side secret store only. Never in a repository, never in a client bundle.Every project in the workspace. A leaked live key can ask anything of your documents and read the answers, and can write leads and tickets. It cannot read back stored leads, conversations, or documents.

What a key can reach

Keys authenticate a caller, not a person, so they reach only the endpoints that were designed to be called without a signed-in user. That is a short list, and it is worth knowing before you plan an integration around it:

  • POST /v1/chat
  • POST /v1/chat/stream
  • POST /v1/chat/feedback
  • POST /v1/projects/{projectId}/leads
  • POST /v1/projects/{projectId}/tickets
  • POST /v1/projects/{projectId}/conversations/{conversationId}/escalate

Extract is in addition to these, on its own service. Everything else needs a dashboard session:

  • Reading or exporting leads
  • Reading conversations
  • Listing, uploading, or deleting documents
  • Managing projects, keys, members, or billing

Choosing

  • Calling from a browser? Embed key. Always.
  • Calling from your server? Integration key.
  • Wiring things up? The test variant of either, which answers from a fixture and never touches your documents.
  • Need browser code to do something an embed key cannot? Put it behind your own endpoint — the BFF recipe.

Naming that carries the boundary

.env Shell
# Ships to the browser. Public by construction.
PUBLIC_OPRAG_EMBED_KEY=embed_live_...

# Server only. Never referenced from client code.
OPRAG_SECRET_KEY=sk_live_...

Bundlers expose variables by prefix. If the browser key is the only one named PUBLIC_, the build tooling refuses to leak the other one for you.

Rotation and revocation

Keys are issued and revoked per project. Rotating issues a new key and retires the old one; revoking a key takes effect immediately and returns 401 on the next call. See the keys reference.

Ready to ship?

Get started free