Crea una transazione di accesso
POST /fapi/v1/transactions · chiamato dall'host di accesso dell'ambiente
Avvia una transazione di accesso per un'applicazione. La pagina di accesso ospitata, i componenti UI e i client headless chiamano questo
endpoint sull'host di accesso dell'ambiente (un sottodominio keenauth.app o un dominio personalizzato verificato). La risposta imposta il
cookie di transazione __Host-idp_ltx (Secure, HttpOnly, SameSite=Lax, valido per 15 minuti); i passaggi successivi usano quel cookie.
Richiesta
Intestazioni:
| Intestazione | Obbligatoria | Descrizione |
|---|---|---|
Idp-Client |
sì | Identificatore dell'SDK, <package>/<version> (<runtime>/<version>). |
Origin |
sì | Deve essere esattamente https://<sign-in host>. |
Corpo:
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
client_id |
string | sì | L'ID client dell'applicazione. |
redirect_uri |
string (URI) | sì | Uno dei redirect URI registrati dell'applicazione. |
Risposta
201 Created con l'oggetto transazione:
{
"schema_version": 1,
"state": "identifier_pending",
"next_steps": [{ "step": "identifier", "fields": ["identifier"] }],
"csrf_token": "<token>",
"expires_at": "2026-10-05T10:15:00Z"
}
Invia csrf_token di nuovo nell'intestazione Idp-Csrf-Token in ogni richiesta di questa transazione che modifica lo stato.
Quando la richiesta di autorizzazione indica un'organizzazione che richiede SSO, la risposta può essere già
federated_redirect con redirect_url (una sola connessione: naviga la finestra di primo livello verso quell'URL) oppure contenere
sso_connections (più connessioni: invia la scelta con il passaggio sso_start).
Transazioni headless vincolate a DPoP
Una SPA o un'app nativa di prima parte sulla propria origine avvia un accesso headless con un'intestazione DPoP (RFC 9449): una prova
firmata con una chiave che il client conserva (chiave WebCrypto non estraibile in un browser, key store della piattaforma su un dispositivo),
con htm POST e htu https://<sign-in host>/fapi/v1/transactions. La transazione è quindi vincolata a quella chiave
anziché a un cookie: non viene impostato alcun cookie e l'oggetto non ha csrf_token. Ogni richiesta successiva della transazione invia
una nuova prova dalla stessa chiave.
Campi aggiuntivi nel corpo, verificati con le regole dell'endpoint di autorizzazione:
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
code_challenge |
string | sì | Challenge PKCE S256 (RFC 7636). |
code_challenge_method |
string | sì | S256. |
scope |
string | no | Scope separati da spazi, per esempio openid profile email offline_access. |
state |
string | no | Restituito insieme al codice di autorizzazione. |
nonce |
string | no | Il nonce dell'ID token. |
organization |
string | no | ID o nome dell'organizzazione. |
ui_locales |
string | no | Lingue preferite. |
resource |
string (URI) | no | Indicatore di risorsa (RFC 8707). |
Origin può essere l'host di accesso o una delle origini web consentite dell'applicazione; un'app nativa non invia alcuna origine. Solo
le applicazioni di prima parte possono avviarne una. Un campo che l'endpoint di autorizzazione rifiuta restituisce 422 validation_failed con
il codice di errore OAuth in errors[].code. Quando il server risponde 401 use_dpop_nonce, firma una nuova prova con il valore
dell'intestazione di risposta DPoP-Nonce e riprova. Inviare questi campi senza un'intestazione DPoP restituisce
422 validation_failed (dpop_required).
Cambio di organizzazione
Un'applicazione che possiede un access token della front API per l'utente connesso (vedi Access token della front API)
può spostare l'utente su un'altra organizzazione senza mostrare schermate. Invia il token in Authorization: DPoP <token> con una prova
della chiave del token (con ath), e nel corpo il flow organization_switch, i campi headless vincolati a DPoP descritti sopra
(client_id dell'applicazione del token, redirect_uri, code_challenge, state, nonce, scope) e
organization, cioè l'ID org_… di un'organizzazione da GET /fapi/v1/me/organizations.
La richiesta viene decisa subito con la sessione del token, come avverrebbe per un accesso che riutilizza la sessione: si applicano la
policy dell'organizzazione (MFA, limite di inattività, SSO, lista IP), il consenso e i documenti legali in attesa. La risposta è 201 con una
transazione completed che contiene authorization_response; scambia il suo code all'endpoint dei token con il tuo
code_verifier e una prova della stessa chiave. I nuovi token riportano l'organizzazione in org_id. Nessuna transazione resta aperta
e non viene impostato alcun 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"
}
| Stato | Codice | Quando |
|---|---|---|
| 401 | unauthenticated |
Il token non è valido, è scaduto, è stato revocato o non è vincolato a una chiave, la sua applicazione non è un'applicazione di prima parte attiva, oppure la sua sessione è terminata. |
| 422 | validation_failed |
flow non è organization_switch, client_id non è l'applicazione del token, organization non è un ID org_…, oppure l'utente non può passare a quell'organizzazione in questa applicazione (not_eligible). |
| 403 | authorization_failed |
L'organizzazione richiede una schermata che il cambio non può mostrare; error è l'errore OAuth (login_required, interaction_required, consent_required). Avvia un nuovo accesso con organization impostato. |
flow organization_switch senza il token restituisce 422 validation_failed (access_token_required).
Errori
| Stato | Codice | Quando |
|---|---|---|
| 400 | malformed_request |
Idp-Client manca oppure il corpo non è JSON valido. |
| 403 | origin_not_allowed |
Origin non è l'host di accesso. |
| 403 | headless_not_allowed |
Un'applicazione di terze parti ha provato ad avviare un flusso headless. |
| 404 | not_found |
L'host non è un host di accesso di alcun ambiente. |
| 422 | validation_failed |
client_id non è un'applicazione di questo ambiente, redirect_uri non è registrato per essa, oppure un campo non è valido. |
| 401 | invalid_dpop_proof |
La prova DPoP manca, non è valida o è stata riutilizzata, oppure l'host non gestisce transazioni vincolate a DPoP. |
| 401 | use_dpop_nonce |
Firma una nuova prova con il valore dell'intestazione di risposta DPoP-Nonce. |
| 503 | temporarily_unavailable |
Una dipendenza non è disponibile; riprova più tardi. |
Esempio
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"}'
Dati personali
Questo endpoint tratta dati personali: il profilo dell'utente finale. Dati personali nelle API di KeenAuth descrive cosa viene memorizzato, per quanto tempo viene conservato e come viene cancellato. Non inviare in alcun campo categorie particolari di dati personali (salute, dati biometrici, religione, opinioni politiche, orientamento sessuale).