# Authentication and API keys

Canonical URL: https://docs.viralspy.com/docs/authentication



## API keys [#api-keys]

REST requests use a bearer API key:

```http
Authorization: Bearer vsp_live_prefix_secret
```

Keys are bound to both a user and an organisation. If the user belongs to several organisations, create or reveal a separate key while the intended organisation is selected. ViralSpy stores only a versioned HMAC digest, shows the secret once, masks prefixes in the UI, and records reveal, create, rotate, revoke, and use events.

Available scopes are:

* `content:read` — videos, feeds, creators, advertisers, trends, and usage.
* `agent:request` — the ViralSpy analyst. This is optional when creating additional keys.

## Safe storage [#safe-storage]

* Put keys in a server-side secret manager or environment variable.
* Never commit keys, embed them in browser JavaScript, place them in URLs, or paste them into support messages.
* Use one key per deployed workload. Names make audit and revocation safer.
* Rotate immediately if a key may have been exposed. Rotation invalidates the old secret.

## MCP authentication [#mcp-authentication]

During the API beta, connect MCP clients with an API key stored in an environment variable. This works with Codex, Claude Code, and any Streamable HTTP client that supports bearer headers.

ViralSpy also supports OAuth 2.1 with PKCE for explicitly registered clients. It publishes Protected Resource Metadata and validates issuer, the exact `https://api.viralspy.com/mcp` audience, token type, asymmetric signature, client ID, user, organisation grant, membership, and subscription on every request. Public dynamic client registration is deliberately disabled during beta to prevent unreviewed clients from creating phishing or consent-spam flows.

If you are building an interactive integration that needs OAuth, contact support to register the client and redirect URIs. The consent screen names the organisation and capabilities explicitly.

<Callout type="warn" title="OAuth tokens are MCP-only">
  Ordinary application sessions and MCP OAuth tokens have different audiences and database roles. An app session is rejected by the MCP endpoint, and an MCP token cannot inherit the app's database privileges.
</Callout>
