Skip to main content
Peeve has three credentials. They are not interchangeable, and no endpoint accepts a fallback — an endpoint declares which kinds it takes, and anything else is refused with a message naming what was wanted.

The user token is the one to understand

A user token’s role is resolved live, on every call. Nothing is frozen onto the credential.Demote a teammate and their token narrows immediately. Remove them from the workspace and it stops working entirely — the membership read is the existence check, so there is no window in which a removed person’s token still works.This is the model’s main advantage, and it changes how you manage access: revoking someone’s reach is a membership change, not a credential hunt.
A role frozen onto a credential is a copy of an authorization decision, and copies go stale. That is why user tokens are also not cached, where key lookups are cached for 20 seconds — caching a live role would reintroduce exactly the staleness the design exists to remove.

One person, many tokens

A teammate can hold several named tokens — one per script, one per laptop — and revoke them individually. Create, name, list and revoke them in Settings → API keys. They all carry the same role, because they all carry that person’s role.
A user token is not scoped to one surface. The same pv_ut_… that connects an assistant to MCP also reaches the whole /v1 API at that person’s role — including, for an owner or admin, writing guardrails and operating the kill switch.Treat handing one out as handing out that person’s account reach, not “an MCP key”. If you want a narrow credential, issue it to a teammate whose role is narrow.

Which credential each surface takes

/v1 is deliberately not uniform. The data and config endpoints are a person acting with their own reach, so only a user token can express them. /v1/users and /v1/answer are machine paths that run in your backend on a schedule or a signup hook — a user token there would tie a production pipeline to one employee’s continued employment.
Publishable keys are accepted nowhere on /v1 or MCP. A pk_… ships inside your page’s script tag, so every script on that page can read it — including a prompt-injection payload. A publishable key that could read /v1/leads would put your whole pipeline one XSS away.

Sending a credential

Header only, on both /v1 and MCP:
Never in a query string. URLs end up in proxy logs, browser history and Referer headers; a credential in one is a credential leaked to every hop. /v1 and MCP read credentials from headers only, by design.
The widget is the exception — its publishable key belongs in the page, because it is public by construction:
Never put a secret key or a user token in browser code. This is the highest-stakes rule on this page. Client-side, publishable only.

Who can see which credential

Admin, Responder and Viewer cannot see the workspace keys — deliberately, and it surprises people. The reasoning: the publishable and secret keys are the workspace’s integration credentials — the widget, the CLI, the SDK. Whoever reads the secret key holds whatever it holds, so that list is the people whose job is wiring Peeve up: the Owner, and the Developer whose whole remit is the install. An Admin’s reach is over how the AI behaves — guardrails, drift, the team — which is a different axis, served by their own user token.

No CORS, no origin

/v1 sends no CORS headers and checks no Origin. Both are deliberate:
  • No CORS means the API is not callable from a page by construction, so a credential can never be exercised from a victim’s browser.
  • No origin check because a backend sends no Origin header — applying the browser gate here would reject every legitimate call.
The origin gate belongs to the widget surface, and only there.

What survives the kill switch

The kill switch is not enforced on /v1. It stops the agent acting on your app; it must not stop you reading your own data — and it must certainly not lock you out of the endpoint that turns it back off.

Next

Roles

Which role reaches which endpoint.

API conventions

The envelope, pagination and error shape shared by every /v1 endpoint.