Guías

OAuth

Filmo implementa OAuth 2.1 para clientes públicos: código de autorización con PKCE, sin secreto de cliente. El token que emite es una clave de API de tipo OAuth, así que funciona en toda la API REST y en MCP, con los permisos (scopes) que concedió el administrador.

Estás construyendoUso
Un proceso de backend o una integración para tu propia empresa que llama a la API REST de forma programada o ante eventosUna clave de API, creada por un administrador. Consulta Autenticación.
Una integración que actúa en nombre de muchas cuentas, o que necesita un consentimiento que el cliente puede revocarOAuth. El administrador de cada cuenta aprueba la conexión y puede revocarla en cualquier momento.
Un cliente MCP remoto, como un conector de asistente, que se conecta a https://app.filmo.io/api/v1/mcpOAuth. El cliente descubre por sí mismo dónde autenticarse.

OAuth no es un segundo sistema de autenticación. El token de acceso que emite es una clave de API de tipo OAuth: empieza por fk_live_, viaja igual, como Authorization: Bearer, y funciona en todas las operaciones REST y en MCP. Se aplican los mismos permisos (scopes), el propietario se revalida en cada petición y cuentan los mismos límites de peticiones. Las diferencias son que el token caduca tras 1 hora y que se renueva con un token de refresco. Para trabajo sencillo entre servidores, una clave es más simple y es lo que recomienda Filmo; elige OAuth cuando actúes en nombre de muchas cuentas o necesites un consentimiento revocable. Los pasos de conexión para asistentes están en Autenticación de MCP.

El cliente no guarda ningún secreto y demuestra la posesión del código de autorización con PKCE. No hay concesión client_credentials ni cliente confidencial: toda conexión necesita el consentimiento de un administrador de la cuenta.

PasoEndpointNotas
DescubrimientoGET /.well-known/oauth-authorization-server (RFC 8414) y GET /.well-known/oauth-protected-resource (RFC 9728)Ambos son públicos. El 401 de /api/v1/mcp lleva una cabecera WWW-Authenticate con resource_metadata, de modo que un cliente los encuentra sin configuración.
RegistroPOST /api/v1/oauth/register (RFC 7591)Abierto, solo JSON. Cliente público: recibes un client_id y ningún client_secret.
AutorizaciónGET /oauth/authorizePKCE con S256 es obligatorio. Un administrador de la cuenta ve la pantalla de consentimiento.
TokenPOST /api/v1/oauth/tokengrant_type=authorization_code, o grant_type=refresh_token para rotar.

Lee los metadatos en lugar de fijar los endpoints a mano. Ambos documentos se sirven bajo /.well-known/ y se pueden guardar en caché cinco minutos. En producción el emisor, los endpoints y el resource protegido están siempre en https://app.filmo.io: una petición a /api/v1/mcp o a un documento .well-known en cualquier otro host de producción se responde con una redirección 308 hacia él.

DocumentoCampos
/.well-known/oauth-authorization-serverissuer, authorization_endpoint (/oauth/authorize), token_endpoint (/api/v1/oauth/token), registration_endpoint (/api/v1/oauth/register), scopes_supported, response_types_supported (code), grant_types_supported (authorization_code, refresh_token), code_challenge_methods_supported (S256), token_endpoint_auth_methods_supported (none), service_documentation
/.well-known/oauth-protected-resourceresource (el endpoint MCP, https://app.filmo.io/api/v1/mcp), authorization_servers, scopes_supported, bearer_methods_supported (header), resource_documentation

Los metadatos no tienen revocation_endpoint, ni endpoint de introspección, ni response_modes_supported. Los endpoints de OAuth y MCP no envían cabeceras CORS, así que llama a estos endpoints desde un servidor, no desde código de navegador.

El registro es abierto: no necesita credencial y solo acepta JSON. El cliente es público, así que no hay client_secret ni token de acceso al registro.

  • redirect_uris es obligatorio, con 10 entradas como máximo. Cada una es un URI absoluto sin fragmento, y es https, o http en un host de loopback como 127.0.0.1 o [::1] (cualquier puerto y ruta), o un esquema personalizado de una app nativa.
  • client_name es opcional, y se rechaza un nombre de más de 200 caracteres. El resto de metadatos que envíes (grant_types, response_types, token_endpoint_auth_method, scope, logo_uri, software_id) se ignora: el cliente es siempre un cliente público con token_endpoint_auth_method establecido en none.
  • La respuesta es 201 con client_id, client_id_issued_at, client_name, redirect_uris, grant_types, response_types, token_endpoint_auth_method y token_endpoint.
  • Un cliente que nunca se usa puede purgarse a los 30 días, así que regístralo una vez y conserva el client_id.
Registrar un cliente
# Register a public client once (no credentials needed). JSON only.
curl -sS -X POST "${FILMO_BASE_URL:-https://app.filmo.io}/api/v1/oauth/register" \
  -H "Content-Type: application/json" \
  -d '{"client_name": "Acme Sync", "redirect_uris": ["https://example.com/oauth/callback"]}'

Envía el navegador del administrador a /oauth/authorize en https://app.filmo.io. Lee estos parámetros e ignora cualquier otro.

ParámetroRegla
client_idObligatorio. El cliente registrado.
redirect_uriObligatorio. Debe ser exactamente igual a una de las URI que registraste: sin comodines y sin puerto flexible para loopback.
response_typeDebe ser code.
scopeOpcional. Permisos separados por espacios que se preseleccionan en la pantalla de consentimiento. Los scopes desconocidos se ignoran.
code_challengeRequired.
code_challenge_methodSolo S256; plain se rechaza.
stateOpcional, se devuelve sin cambios a tu redirect_uri.

Los errores que ocurren antes de que Filmo pueda fiarse del redirect_uri (un cliente desconocido o un redirect_uri que no coincide) se muestran en la página de Filmo y no se redirigen. Cualquier error posterior se envía a tu redirect_uri como error, error_description y state. El código de autorización se entrega siempre en la query string, nunca en un fragmento.

El código es válido durante 60 segundos y se puede usar una vez. Su code_verifier debe tener entre 43 y 128 caracteres.

Solo un administrador puede conceder una conexión. La pantalla de consentimiento permite al administrador elegir la suscripción que usará la conexión y los permisos (scopes) que concede: concede el mínimo que necesita la integración. Solo vienen preseleccionados los permisos de lectura: los que pide el cliente, o todos los de lectura si no pide ninguno. Los permisos de escritura, workflows:run y ai:ask empiezan siempre sin seleccionar, aunque el cliente los pida; los que pidió llevan la etiqueta *Lo pide la integración*, y el administrador los activa a mano. El token queda vinculado a esa suscripción, y todo lo que escribe la conexión se atribuye a ese administrador, igual que con una clave. La conexión queda registrada en el registro de actividad de la cuenta.

Aprueba una conexión solo si la iniciaste tú, y comprueba el nombre del cliente y el host al que redirige. Una conexión a la que se concedieron menos scopes de los que pidió funciona con los que tiene: lee scope en la respuesta del token.

Haz POST a /api/v1/oauth/token como formulario (application/x-www-form-urlencoded) o como JSON. El cliente es público: envía client_id y ningún secreto.

  • grant_type=authorization_code requiere redirect_uri, code y code_verifier.
  • grant_type=refresh_token requiere refresh_token.
  • Cualquier otro tipo de grant se rechaza con unsupported_grant_type. No existe client_credentials.
  • scope y resource en la petición del token se ignoran: los permisos son los concedidos en la pantalla de consentimiento.
Intercambiar un código y renovar
# Exchange the authorization code (all values come from your own flow).
curl -sS -X POST "${FILMO_BASE_URL:-https://app.filmo.io}/api/v1/oauth/token" \
  -d grant_type=authorization_code \
  -d client_id="$FILMO_OAUTH_CLIENT_ID" \
  -d redirect_uri="https://example.com/oauth/callback" \
  -d code="$AUTH_CODE" \
  -d code_verifier="$CODE_VERIFIER"

# Later, rotate: send the latest refresh token and keep the new pair.
curl -sS -X POST "${FILMO_BASE_URL:-https://app.filmo.io}/api/v1/oauth/token" \
  -d grant_type=refresh_token \
  -d client_id="$FILMO_OAUTH_CLIENT_ID" \
  -d refresh_token="$REFRESH_TOKEN"

La respuesta es 200 con Cache-Control: no-store:

{
  "access_token": "<the access token, starts with fk_live_>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "<the refresh token>",
  "scope": "<the scopes actually granted, space-separated>"
}
  • El token de acceso caduca tras 1 hora. Después, las llamadas responden 401 api_key_expired hasta que lo refresques.
  • El token de refresco dura 30 días, contados desde la última rotación. Cada refresco emite uno nuevo, así que una conexión que se refresca al menos cada 30 días sigue activa.
  • La rotación reescribe la misma conexión: el access token anterior deja de funcionar al instante, y la conexión sigue siendo una única entrada en la sección API y MCP de los ajustes.
  • Si envías un refresh token que ya se rotó, dentro de 10 segundos y desde el mismo cliente, recibes de nuevo el mismo par nuevo, lo que te protege de un reintento tras una respuesta perdida. Más tarde, la reutilización se trata como una fuga: se revoca toda la cadena y recibes invalid_grant.
  • Guarda el refresh token más reciente y deja que solo un worker renueve cada vez.
  • Antes de rotar, Filmo comprueba que el administrador que dio su consentimiento sigue siendo un administrador activo. Si no, la renovación falla con invalid_grant.

Envíalo como Authorization: Bearer a cualquier operación REST o al endpoint MCP. Los scopes son los que lista la respuesta del token, y el propietario de la clave se comprueba en cada petición, igual que con una clave: si el administrador que dio el consentimiento se va o deja de ser administrador, las llamadas fallan con 401 api_key_owner_inactive o api_key_owner_not_admin. Un 401 de la API REST no lleva cabecera WWW-Authenticate; solo la lleva el 401 del endpoint MCP, que nombra los scopes de lectura en scope, de modo que un cliente pide acceso de lectura por defecto.

Los indicadores de recurso de RFC 8707 no están soportados. Un parámetro resource en la petición de autorización o de token se ignora, y el token no queda vinculado a una audiencia.

No hay endpoint de revocación (RFC 7009). El administrador revoca la conexión en la sección API y MCP de los ajustes (*Ajustes → API y MCP*), donde aparece etiquetada como integración conectada. El acceso termina de inmediato, y a partir de entonces un refresco falla con invalid_grant, así que el usuario tiene que volver a dar su consentimiento. Consulta Autenticación. Las conexiones cuentan en el total de 50 claves no revocadas por suscripción, pero solo se rechaza en el límite la creación manual de una clave.

Los endpoints de OAuth no usan el sobre del resto de la API ni responden en application/problem+json. Responden en el formato plano de OAuth 2.1, que es lo que esperan los clientes estándar. El error_description está siempre en español: ramifica según error, nunca según el texto.

{ "error": "invalid_grant", "error_description": "..." }
Estadoerror
400invalid_request, invalid_grant, unsupported_grant_type, invalid_scope, invalid_redirect_uri, invalid_client_metadata
401invalid_client
403unauthorized_client, access_denied
500server_error

Los endpoints de OAuth no devuelven X-Request-Id. Un 401 invalid_client no tiene cabecera WWW-Authenticate.

Los endpoints de OAuth tienen sus propios límites, contados por dirección IP en una ventana de un minuto: 5 peticiones por minuto en /api/v1/oauth/register y 120 por minuto en /api/v1/oauth/token. Al superar el límite recibes 429 con Retry-After. Gestiona cualquier 429 de estos endpoints esperando Retry-After, no leyendo el cuerpo: el cuerpo no es igual en todos los casos. Estas respuestas no llevan cabeceras RateLimit-*. Los límites de REST se describen en Límites de peticiones.

Usa el soporte de OAuth de tu cliente MCP o una biblioteca estándar de OAuth 2.1 en lugar de peticiones construidas a mano. Para integraciones de servidor a servidor que actúan sobre una cuenta, crea una clave de API en su lugar.

  • Guías

    Autenticación

    Cada operación requiere una clave de API enviada como bearer token. Solo un administrador puede crear una clave, y la clave actúa como ese administrador, así que decide quién la posee antes de crearla.

  • Acceso

    Autenticación y permisos

    Autentica con una clave de API en una cabecera o deja que el cliente inicie sesión con OAuth 2.1. En ambos casos los permisos deciden qué herramientas existen.

  • Guías

    Integraciones con varias cuentas

    Da a cada cuenta de cliente su propia credencial, guárdala con la zona horaria y la moneda de esa cuenta, y trata una credencial que falla como el estado de una conexión, no de todo tu producto. OAuth está disponible para un servidor que ejecutes tú, y las claves de API son más sencillas para el trabajo entre servidores.

¿Te ha resultado útil esta página?