Crear una transacción de inicio de sesión
POST /fapi/v1/transactions · llamado desde el host de inicio de sesión del entorno
Inicia una transacción de inicio de sesión para una aplicación. La página alojada de inicio de sesión, los componentes de interfaz y los clientes headless llaman a este
endpoint en el host de inicio de sesión del entorno (un subdominio keenauth.app o un dominio personalizado verificado). La respuesta establece la
cookie de transacción __Host-idp_ltx (Secure, HttpOnly, SameSite=Lax, válida durante 15 minutos); los pasos posteriores usan esa cookie.
Solicitud
Encabezados:
| Encabezado | Obligatorio | Descripción |
|---|---|---|
Idp-Client |
sí | Identificador del SDK, <package>/<version> (<runtime>/<version>). |
Origin |
sí | Debe ser exactamente https://<sign-in host>. |
Cuerpo:
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
client_id |
string | sí | El ID de cliente de la aplicación. |
redirect_uri |
string (URI) | sí | Una de las URI de redirección registradas de la aplicación. |
Respuesta
201 Created con el objeto de transacción:
{
"schema_version": 1,
"state": "identifier_pending",
"next_steps": [{ "step": "identifier", "fields": ["identifier"] }],
"csrf_token": "<token>",
"expires_at": "2026-10-05T10:15:00Z"
}
Envíe csrf_token de vuelta en el encabezado Idp-Csrf-Token en cada solicitud de esta transacción que modifique el estado.
Cuando la solicitud de autorización indica una organización que requiere SSO, la respuesta puede ser ya
federated_redirect con redirect_url (una sola conexión: navegue allí en la ventana de nivel superior) o incluir
sso_connections (varias: envíe la elección con el paso sso_start).
Transacciones headless vinculadas a DPoP
Una SPA o una aplicación nativa de primera parte en su propio origen inicia un inicio de sesión headless con un encabezado DPoP (RFC 9449): una prueba
firmada con una clave que conserva el cliente (una clave no extraíble de WebCrypto en un navegador, el almacén de claves de la plataforma en un dispositivo),
con htm POST y htu https://<sign-in host>/fapi/v1/transactions. La transacción queda entonces vinculada a esa clave
en lugar de a una cookie: no se establece ninguna cookie y el objeto no tiene csrf_token. Cada solicitud posterior de la transacción envía una
nueva prueba firmada con la misma clave.
Campos adicionales del cuerpo, verificados con las reglas del endpoint de autorización:
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
code_challenge |
string | sí | Desafío PKCE S256 (RFC 7636). |
code_challenge_method |
string | sí | S256. |
scope |
string | no | Ámbitos separados por espacios, por ejemplo openid profile email offline_access. |
state |
string | no | Se devuelve con el código de autorización. |
nonce |
string | no | El nonce del ID token. |
organization |
string | no | ID o nombre de la organización. |
ui_locales |
string | no | Idiomas preferidos. |
resource |
string (URI) | no | Indicador de recurso (RFC 8707). |
Origin puede ser el host de inicio de sesión o uno de los orígenes web permitidos de la aplicación; una aplicación nativa no envía ninguno. Solo
las aplicaciones de primera parte pueden iniciar una de estas transacciones. Un campo que el endpoint de autorización rechaza devuelve 422 validation_failed con
el código de error OAuth en errors[].code. Cuando el servidor responde 401 use_dpop_nonce, firme una nueva prueba con el valor
del encabezado de respuesta DPoP-Nonce y reintente. Enviar estos campos sin un encabezado DPoP devuelve
422 validation_failed (dpop_required).
Cambiar de organización
Una aplicación que posee un token de acceso a la Front API para el usuario con sesión iniciada (véase Token de acceso de Front API)
cambia al usuario a otra organización sin mostrar ninguna pantalla. Envíe el token en Authorization: DPoP <token> con una prueba
de la clave del token (con ath), y en el cuerpo, flow organization_switch, los campos headless vinculados a DPoP indicados arriba
(client_id de la aplicación del token, redirect_uri, code_challenge, state, nonce, scope) y
organization, el ID org_… de una organización obtenida de GET /fapi/v1/me/organizations.
La solicitud se resuelve de inmediato con la sesión del token, como lo haría un inicio de sesión que reutiliza la sesión: la
política de la organización (MFA, límite de inactividad, SSO, lista de IP), el consentimiento y los documentos legales pendientes. La respuesta es 201 con una
transacción completed que incluye authorization_response; canjee su code en el endpoint de token con su
code_verifier y una prueba de la misma clave. Los nuevos tokens incluyen la organización en org_id. No queda ninguna transacción abierta
ni se establece ninguna cookie.
{
"schema_version": 1,
"state": "completed",
"next_steps": [],
"authorization_response": { "code": "<code>", "state": "<state>", "iss": "https://example.keenauth.app" },
"expires_at": "2026-10-05T10:15:00Z"
}
| Estado | Código | Cuándo |
|---|---|---|
| 401 | unauthenticated |
El token no es válido, ha caducado, ha sido revocado o no está vinculado a una clave, su aplicación no es una aplicación de primera parte activa, o su sesión ha terminado. |
| 422 | validation_failed |
flow no es organization_switch, client_id no es la aplicación del token, organization no es un ID org_…, o el usuario no puede cambiar a ella en esta aplicación (not_eligible). |
| 403 | authorization_failed |
La organización necesita una pantalla que el cambio no puede mostrar; error es el error OAuth (login_required, interaction_required, consent_required). Inicie un nuevo inicio de sesión con organization definido. |
flow organization_switch sin el token devuelve 422 validation_failed (access_token_required).
Errores
| Estado | Código | Cuándo |
|---|---|---|
| 400 | malformed_request |
Falta Idp-Client o el cuerpo no es JSON válido. |
| 403 | origin_not_allowed |
Origin no es el host de inicio de sesión. |
| 403 | headless_not_allowed |
Una aplicación de terceros intentó iniciar un flujo headless. |
| 404 | not_found |
El host no es un host de inicio de sesión de ningún entorno. |
| 422 | validation_failed |
client_id no es una aplicación de este entorno, redirect_uri no está registrada para ella, o un campo no es válido. |
| 401 | invalid_dpop_proof |
La prueba DPoP falta, no es válida o se reutilizó, o el host no sirve transacciones vinculadas a DPoP. |
| 401 | use_dpop_nonce |
Firme una nueva prueba con el valor del encabezado de respuesta DPoP-Nonce. |
| 503 | temporarily_unavailable |
Una dependencia no está disponible; reintente más tarde. |
Ejemplo
curl -X POST https://example.keenauth.app/fapi/v1/transactions \
-H "Idp-Client: my-app/1.0.0 (node/22.0.0)" \
-H "Origin: https://example.keenauth.app" \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{"client_id":"<client_id>","redirect_uri":"https://app.example.com/callback"}'
Datos personales
Este endpoint trata datos personales: el perfil del usuario final. Datos personales en las APIs de KeenAuth describe qué se almacena, durante cuánto tiempo se conserva y cómo se elimina. No envíe en ningún campo categorías especiales de datos personales (salud, datos biométricos, religión, opiniones políticas, orientación sexual).