OAuth endpoint reference
Use this reference to implement a remote MCP client. All URLs below use the production origin https://infinityflow.stream. These are public PKCE clients, without a client secret. Tokens authorize the MCP resource only.
Discovery endpoints
Section titled “Discovery endpoints”| Method and path | Successful response |
|---|---|
GET /.well-known/oauth-protected-resource/mcp |
resource, authorization_servers, scopes_supported, bearer_methods_supported, resource_documentation |
GET /.well-known/oauth-protected-resource |
Same resource metadata; alias |
GET /.well-known/oauth-authorization-server |
issuer, authorization/token/registration/revocation endpoint URLs and supported response/grant/auth/PKCE methods and scopes |
curl -sS https://infinityflow.stream/.well-known/oauth-protected-resource/mcpcurl -sS https://infinityflow.stream/.well-known/oauth-authorization-serverResource metadata identifies resource: "https://infinityflow.stream/mcp", authorization_servers: ["https://infinityflow.stream"] and bearer_methods_supported: ["header"]. Server metadata advertises response_types_supported: ["code"], grant_types_supported: ["authorization_code","refresh_token"], token_endpoint_auth_methods_supported: ["none"] and code_challenge_methods_supported: ["S256"]. Discovery GET responses allow cross-origin reads. Unsupported methods return 405.
Scopes
Section titled “Scopes”account:read usage:read generations:read generations:writeprojects:read projects:write references:read references:write media:readThe authorization scope parameter is space-delimited. Omitted scope requests all supported scopes; request the minimum needed. At least one supported scope is required, duplicates/unknown scopes are rejected. offline_access is accepted and removed from stored permissions; refresh tokens are issued regardless of its presence. Permission-to-tool mapping is in the tool reference.
POST /oauth/register
Section titled “POST /oauth/register”Send JSON, up to 16,384 bytes. No existing access token or browser session is required.
| Field | Required | Contract |
|---|---|---|
redirect_uris |
Yes | Array of 1–10 distinct exact URLs, each at most 2,048 characters; HTTPS, or HTTP only for localhost, 127.0.0.1 or [::1]; no fragment or embedded credentials |
client_name |
No | Trimmed nonempty string up to 100 characters; defaults to MCP client |
token_endpoint_auth_method |
No | If supplied, none |
grant_types |
No | Array containing only authorization_code and/or refresh_token |
response_types |
No | Exactly ["code"] if supplied |
curl -sS https://infinityflow.stream/oauth/register \ -H 'Content-Type: application/json' \ --data '{"client_name":"My MCP client","redirect_uris":["http://localhost:8765/callback"],"token_endpoint_auth_method":"none","grant_types":["authorization_code","refresh_token"],"response_types":["code"]}'{ "client_id": "ifc_PUBLIC_CLIENT_ID", "client_id_issued_at": 1794240000, "client_name": "My MCP client", "redirect_uris": ["http://localhost:8765/callback"], "token_endpoint_auth_method": "none", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"]}Success is 201; save client_id. The example client ID/timestamp are illustrative, not reusable. No client secret or registration management token is returned. Registration is limited to 20 requests per IP per hour. Errors include invalid_redirect_uri and invalid_client_metadata (400).
GET /oauth/authorize
Section titled “GET /oauth/authorize”Open this URL in the user’s browser, not a background cURL request. Authorization needs the native Infinity Flow login and explicit consent.
| Query parameter | Required | Contract |
|---|---|---|
client_id |
Yes | Registered client ID |
redirect_uri |
Yes | Exact registered redirect URI |
response_type |
Yes | code |
code_challenge |
Yes | S256 challenge: 43 base64url characters |
code_challenge_method |
Yes | S256 |
scope |
No | Space-delimited permissions; defaults to all supported |
state |
Recommended | Client-generated CSRF correlation value, up to 1,024 characters; validate exact returned value |
resource |
Recommended | https://infinityflow.stream/mcp; omission defaults to this resource; other values rejected |
Generate and retain a verifier of 43–128 characters from [A-Za-z0-9._~-]; derive BASE64URL(SHA256(verifier)), without padding. Example URL with placeholders:
https://infinityflow.stream/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=http%3A%2F%2Flocalhost%3A8765%2Fcallback&response_type=code&code_challenge=YOUR_S256_CHALLENGE&code_challenge_method=S256&resource=https%3A%2F%2Finfinityflow.stream%2Fmcp&scope=account%3Aread%20usage%3Aread%20generations%3Aread%20generations%3Awrite%20media%3Aread&state=YOUR_RANDOM_STATEDuplicate query parameters are rejected. Initial authorization requests are limited to 60 per IP per minute and expire after 15 minutes. If login is needed, the server returns 303 to native login with an opaque saved request; GET /oauth/authorize?request=UUID resumes that flow. The client should not fabricate this resume ID.
POST /oauth/authorize: user consent
Section titled “POST /oauth/authorize: user consent”This is the native consent form endpoint, not a client credentials endpoint. It requires the logged-in user, the saved request bound to that user and an approved same-origin form submission. Its fields are request (saved UUID) and decision (approve or deny). Clients should let the user submit the rendered form.
Approval returns 303 to redirect_uri with code, iss=https://infinityflow.stream and the original state if present. Denial returns 303 with error=access_denied, iss and state. Validate state and issuer before using the code. A code is valid for 120 seconds and one exchange. Invalid/expired/consumed flows return invalid_request; another user’s flow returns access_denied (403). Without active automation the page links to Integrations rather than approving access.
POST /oauth/token: code exchange
Section titled “POST /oauth/token: code exchange”Use application/x-www-form-urlencoded (JSON is also accepted), with a maximum body of 16,384 bytes. Duplicate form fields are rejected. No Basic auth or client secret.
| Field | Required | Contract |
|---|---|---|
grant_type |
Yes | authorization_code |
client_id |
Yes | Same registered ID |
redirect_uri |
Yes | Exact URI used for authorization |
code |
Yes | Unused 43-character authorization code |
code_verifier |
Yes | Original verifier, 43–128 allowed characters |
resource |
Recommended | Exact MCP resource; another target returns invalid_target |
curl -sS https://infinityflow.stream/oauth/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'client_id=YOUR_CLIENT_ID' \ --data-urlencode 'redirect_uri=http://localhost:8765/callback' \ --data-urlencode 'code=YOUR_AUTHORIZATION_CODE' \ --data-urlencode 'code_verifier=YOUR_ORIGINAL_VERIFIER' \ --data-urlencode 'resource=https://infinityflow.stream/mcp'{ "access_token": "ifa_REDACTED", "token_type": "Bearer", "expires_in": 900, "refresh_token": "ifr_REDACTED", "scope": "account:read generations:read generations:write media:read usage:read"}Success is 200. Access tokens live 900 seconds; each refresh token expires 30 days after its issuance. This is a rotating window, not an absolute 30-day connection lifetime. Keep tokens secret and store returned scopes. resource is enforced even though it is optional in the request. The endpoint is limited to 120 requests per IP per minute across both grant types.
POST /oauth/token: refresh
Section titled “POST /oauth/token: refresh”Required fields: grant_type=refresh_token, client_id, refresh_token. Optional resource must be the MCP resource. No redirect_uri or verifier is required for refresh; no scope narrowing parameter is implemented.
curl -sS https://infinityflow.stream/oauth/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=refresh_token' \ --data-urlencode 'client_id=YOUR_CLIENT_ID' \ --data-urlencode 'refresh_token=YOUR_CURRENT_REFRESH_TOKEN' \ --data-urlencode 'resource=https://infinityflow.stream/mcp'Response shape matches code exchange. Atomically replace both tokens: successful refresh revokes the previous access token and consumes its refresh token. Reusing a consumed refresh token revokes the whole connection and returns invalid_grant; do not perform parallel refreshes. Reconnect through user consent after reuse detection. Expiry, revocation, account epoch changes or loss of automation also prevent refresh.
POST /oauth/revoke
Section titled “POST /oauth/revoke”Send form-encoded (or JSON) client_id and token, where token is an access or refresh token. This revokes the matching token record, including its access/refresh pair; it is not a whole-connection revocation endpoint. Revoke the connection in Integrations to disable all its tokens.
curl -sS https://infinityflow.stream/oauth/revoke \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=YOUR_CLIENT_ID' \ --data-urlencode 'token=TOKEN_TO_REVOKE'Success is 200 with {} even when the token/client pair is unknown or required fields are missing. Do not use this as a credential-validity probe. Maximum body: 16,384 bytes; rate limit: 60 requests per IP per minute.
Error reference
Section titled “Error reference”OAuth endpoints use a different error shape from REST/tools:
{"error":"invalid_grant","error_description":"This code expired or was already used."}| Error | HTTP status | Meaning |
|---|---|---|
invalid_client_metadata |
400 | Unsupported registration settings or invalid client name. |
invalid_redirect_uri |
400 | Invalid/duplicate redirect URI or URI count. |
invalid_request |
400 | Invalid query, duplicate parameter, expired flow; unsupported endpoint/method returns 404 (discovery method: 405). |
invalid_client |
400 | Missing/non-string client_id at token endpoint. |
invalid_target |
400 | Resource differs from the MCP audience. |
invalid_grant |
400 | Expired/reused code, bad verifier, revoked/expired refresh or refresh reuse. |
unsupported_grant_type |
400 | Anything except authorization_code or refresh_token. |
access_denied |
403 | Invalid consent origin, wrong account or missing entitlement; user denial instead redirects with this error. |
temporarily_unavailable |
429 | OAuth rate limit reached. |
invalid_request |
413 / 415 / 422 | Oversized body, unsupported content type, or invalid scope respectively. |
invalid_request |
500 / other underlying status | Unexpected backend failure; description is sanitized. Authentication failures can use 401 with this code. |
Do not assume OAuth responses carry the REST error requestId or Retry-After header. Token/revocation endpoints are meant for client/server calls; permissive browser CORS is not advertised there. No client credentials, password grant, implicit flow, token introspection or arbitrary client metadata URL fetching is implemented.
Use the token on MCP
Section titled “Use the token on MCP”Send Authorization: Bearer YOUR_ACCESS_TOKEN to https://infinityflow.stream/mcp using a compatible MCP SDK. The endpoint checks live entitlement, account epoch, expiry and revocation, not just token syntax. Limits are 180 credential requests/minute and 360 account requests/minute. Other keys/connections share the account limit.
A missing/expired credential returns HTTP 401 with WWW-Authenticate: Bearer resource_metadata="https://infinityflow.stream/.well-known/oauth-protected-resource/mcp". HTTP authentication errors use the automation {error:{code,message,requestId}} envelope, not the OAuth error shape above. A revoked/missing plan or add-on returns 403. Consult the transport contract and complete tool reference for protocol headers and calls. Never send OAuth MCP tokens to the video provider or a signed media host.