| name | oauth |
| description | Prizmad OAuth 2.1 — Authorization Code + PKCE + Dynamic Client Registration is the primary path (powers Claude Desktop / Claude.ai / ChatGPT / Cursor "Connect" flow). client_credentials remains for headless / programmatic clients. |
| version | 2.0.0 |
Prizmad OAuth 2.1
Prizmad publishes a full OAuth 2.1 authorization server with Dynamic Client Registration. Three grant types are supported, each for a different audience:
| Grant | When | Output |
|---|
authorization_code (PKCE S256, public client) | Interactive MCP / connector flow — Claude Desktop, Claude.ai, ChatGPT, Cursor, Zed | RS256 JWT, audience https://prizmad.com/api/mcp, 1 h, refresh-rotated |
refresh_token | Companion to authorization_code | Same shape; old refresh is single-use, reuse revokes the chain |
client_credentials | Headless / server-to-server using an API key as client_secret | HS256 JWT, audience https://prizmad.com/api, 1 h |
The MCP server also accepts the raw API key (przmad_sk_live_...) as a Bearer token directly, without going through OAuth at all.
Discovery
Authorization Code + PKCE (the "Connect" flow)
This is what runs when a user clicks Add custom connector → enter https://prizmad.com/api/mcp in Claude Desktop, Claude.ai, ChatGPT, Cursor, etc. The client implements RFC 7591 / 8414 / 9728 / 7636 / 8707; no manual app registration is needed.
1. POST /api/mcp without auth
← 401 + WWW-Authenticate: Bearer resource_metadata="…"
2. GET /.well-known/oauth-protected-resource
GET /.well-known/oauth-authorization-server
3. POST /oauth/register
Body (RFC 7591):
{
"client_name": "<your app>",
"redirect_uris": ["<your callback URL>"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}
← 201 { "client_id": "mcp_…", … } (no client_secret — public client)
4. Browser to /oauth/authorize?
response_type=code
& client_id=<from step 3>
& redirect_uri=<from step 3>
& code_challenge=<S256(verifier)>
& code_challenge_method=S256
& scope=videos:read videos:write
& resource=https://prizmad.com/api/mcp
& state=<csrf>
User signs in (NextAuth) and approves on the consent screen.
← 302 redirect_uri?code=…&state=…
5. POST /oauth/token
grant_type=authorization_code
code=<from step 4>
redirect_uri=<from step 3>
client_id=<from step 3>
code_verifier=<original PKCE verifier>
resource=https://prizmad.com/api/mcp
← 200 { "access_token": "<RS256 JWT>", "refresh_token": "…", "expires_in": 3600, "token_type": "Bearer" }
6. POST /api/mcp with Authorization: Bearer <access_token>
← MCP traffic.
Refresh:
curl -X POST https://prizmad.com/oauth/token \
-d grant_type=refresh_token \
-d refresh_token=<previous refresh_token> \
-d client_id=<client_id>
Returns a fresh access token + a new refresh token; the previous refresh is single-use. Reusing a revoked refresh token revokes the entire chain (defence against token theft).
client_credentials (headless / programmatic)
Quickest way to turn a long-lived API key into a short-lived bearer for server-to-server calls.
Form-encoded
curl -X POST https://prizmad.com/oauth/token \
-d grant_type=client_credentials \
-d client_id=my-app \
-d client_secret=przmad_sk_live_...
JSON
curl -X POST https://prizmad.com/oauth/token \
-H "Content-Type: application/json" \
-d '{"grant_type":"client_credentials","client_id":"my-app","client_secret":"przmad_sk_live_..."}'
Basic Auth
curl -X POST https://prizmad.com/oauth/token \
-u "my-app:przmad_sk_live_..." \
-d grant_type=client_credentials
Response
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "videos:read videos:write"
}
Scopes
| Scope | Description |
|---|
videos:read | Read video status, projects, assets |
videos:write | Create videos, upload images, mutate projects |
Notes
- All endpoints (
/oauth/authorize, /oauth/token, /oauth/register) live on the same origin as the MCP server (https://prizmad.com). This sidesteps the Claude.ai web bug that ignores cross-origin authorization endpoints.
- Access tokens expire after 1 hour. Refresh tokens last 30 days, single-use with rotation.
- API keys (
przmad_sk_live_...) continue to work directly as Bearer tokens — OAuth is only needed when the client requires it.
- Rate limit: 10 token requests per minute per identity.
client_secret field, when used, is your Prizmad API key.
client_id for client_credentials is a free-form identifier.