# LiveReacting auth.md

How to authenticate with the LiveReacting API and MCP server.

This document tells an automated client — a script, an integration, or an AI
agent acting for a customer — how to get credentials for the LiveReacting API
and how to use them.

- **API base URL:** `https://api.livereacting.com/v1/external`
- **Machine-readable description:** <https://developers.livereacting.com/openapi.yaml> (OpenAPI 3.0.3)
- **Reference documentation:** <https://developers.livereacting.com>
- **API catalog:** <https://www.livereacting.com/.well-known/api-catalog>
- **MCP server:** `https://mcp.livereacting.com/mcp` (the same API key; see below)

## Getting access

API access is included with **every paid LiveReacting plan**. Accounts on the
Free plan do not get it, unless we have granted it to that account specifically.
A paused subscription does not count as active.

There are two ways in: an **API key**, which a person creates and hands to the
client, or **OAuth sign-in**, which ChatGPT and Claude use on the MCP server
(see below). There is **no dynamic client registration**: an agent cannot
provision its own credentials. For an API key, a person does this once:

1. The account owner subscribes to any paid plan
   (<https://www.livereacting.com/pricing>).
2. The account owner creates an API key in the Developer section of
   LiveReacting Studio (<https://studio.livereacting.com/developer>).
3. The account owner gives that key to the agent.

Entitlement is checked on every request, not when the key is issued. If the
subscription lapses or moves to Free, the key stops working immediately.

## Authenticating a request

Send the key as a bearer token. Keys begin with `lr_`.

```
Authorization: Bearer lr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

Example:

```
curl https://api.livereacting.com/v1/external/projects \
  -H "Authorization: Bearer lr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

A key identifies one LiveReacting account and carries that account's full
permissions. Treat it as a password: never put it in a URL, a page, a client-side
bundle, or a log.

## Connecting over MCP

The LiveReacting MCP server lets an AI agent use the same account through tools
instead of REST calls. It takes the same API key, sent the same way.

- **Endpoint:** `https://mcp.livereacting.com/mcp` (Streamable HTTP)
- **Header:** `Authorization: Bearer lr_...`
- **Read-only:** add `?read_only=1` to the URL and the client is offered only
  the tools that read.
- **Setup for each client and every tool:** <https://www.livereacting.com/mcp>
  and <https://developers.livereacting.com/mcp/REFERENCE.md>

### OAuth sign-in (ChatGPT, Claude)

Apps that cannot take a pasted key sign in with OAuth 2.1 instead. The customer
adds the MCP URL, logs in with their normal livereacting.com account and clicks
Allow.

- **Discovery:** an unauthenticated call to `/mcp` returns `401` with a
  `WWW-Authenticate` header that points at
  `https://mcp.livereacting.com/.well-known/oauth-protected-resource/mcp`.
  Authorization server metadata is at
  `https://mcp.livereacting.com/.well-known/oauth-authorization-server`.
- **Clients:** identified by a Client ID Metadata Document from `chatgpt.com`,
  `openai.com` or `claude.ai`. A client that needs dynamic client
  registration (Cursor, Gemini CLI) uses an API key.
- **Flow:** authorization code with PKCE `S256`, public clients
  (`token_endpoint_auth_method: none`), the `resource` parameter (RFC 8707),
  and `iss` on every authorization response (RFC 9207).
- **Scope:** one, `livereacting`. It grants what an API key grants.
- **Tokens:** access tokens last one hour. Refresh tokens last 90 days from
  their last use and work once; a second use of an old one ends the connection,
  and the customer connects again. An expired or revoked access token returns
  `401` with `error="invalid_token"`.
- **Plan:** the same paid-plan rule applies, checked on every tool call. An
  account without API access can finish the sign-in, and every tool call then
  returns a tool error (`isError: true`) with `API_ACCESS_REQUIRES_PAID_PLAN`,
  not an HTTP `403`. The tools work on the next call once the plan includes API
  access, with no new sign-in.

## Errors you should handle

| Status | `code` | Meaning |
|---|---|---|
| 401 | `INVALID_API_KEY` | The key is missing, malformed, or revoked. |
| 403 | `API_ACCESS_REQUIRES_PAID_PLAN` | The key is valid, but the account's plan does not include API access. Tell the user; do not retry. Over OAuth this arrives as a tool error, not a 403. |
| 429 | `RATE_LIMITED` | Too many requests. Back off and retry. |

Errors are returned as JSON: `{ "error": true, "code": "...", "message": "..." }`.

## Rate limits

150 requests per minute per account.

A second limit of 500 requests per minute applies per source network address,
and it covers **every** request, authenticated or not. It is a flood backstop
rather than a quota. If several accounts share one outbound address -- an
office, a VPN, an integration platform -- they share that ceiling. Normal use
stays well inside it.

Over MCP, the same 150 per minute per account counts tool calls; connecting and
listing the tools are free. The MCP endpoint has its own flood backstop of 3,000
requests per minute per source address in place of the 500.

Responses carry the standard `RateLimit-*` headers, so read them rather than
guessing.

## Current limits on what the API can do

Stated plainly so an agent does not promise a customer something it cannot
deliver:

- **Connecting or reauthorizing a streaming destination is Studio-only.** The
  API can list and validate destinations a customer has already connected; it
  cannot add one. Connecting YouTube, Facebook, Twitch or another platform
  happens once, by hand, in Studio.
- Text, image and other graphic layers are Studio-only. The API creates and
  changes video, video playlist and audio playlist layers.

Media files are not a limit: the API uploads a file from the client's own
machine (`POST /files/upload`, then `POST /files/upload/complete`), and imports
one from YouTube, Google Drive, Dropbox or a direct link to a media file
(`POST /files/import`).

## Revoking access

The account owner deletes the key in the Developer section of LiveReacting
Studio. Revocation takes effect on the next request. An OAuth client revokes
its tokens at `POST https://mcp.livereacting.com/oauth/revoke`.

## Contact

Support and API questions: <https://www.livereacting.com/api>
