User Auth API
POST /api/auth/custom-token
Returns a Firebase custom token and user profile. The endpoint supports two mutually exclusive authentication grants:
- External-user grant (recommended): allow an approved partner backend to authenticate one of its existing users with a server API key and a stable
externalUserId. - Password grant (compatibility): authenticate an existing GOFA Firebase user with
clientId,email, andpassword.
The custom token is for immediate Firebase sign-in. It is not a GOFA API bearer token.
External-User Grant (Recommended)
Use this grant when your application already authenticated the user in your own identity system and needs to open an approved GOFA experience as that user.
Prefer this grant when your application already has user accounts. Your backend can retrieve a Firebase custom token without collecting, sharing, or managing a separate GOFA password for the user.
Call this grant only from your trusted backend. Never embed a GOFA API key in a browser, mobile app, desktop app, source code, or distributed application package.
Before integration, GOFA must enable external-user SSO for your client and environment. GOFA can configure the client for either existing users only or approved just-in-time (JIT) provisioning. Complete UAT acceptance before requesting production activation.
Headers:
Authorization: Bearer <server-api-key>Content-Type: application/json
Body:
{
"grantType": "external_user",
"externalUserId": "member_839201"
}
externalUserId must be a stable, case-sensitive, opaque identifier from your identity system. Send only that identifier; do not send a GOFA user ID, email address, password, clientId, roles, or access claims. GOFA derives the authoritative client from the API key and deterministically namespaces the external ID to that client.
Use the same externalUserId for the same person on every request. Changing it creates a different identity and is not an account-migration mechanism.
curl --request POST \
--url https://www.uat.gofa.app/api/auth/custom-token \
--header "Authorization: Bearer <server-api-key>" \
--header "Content-Type: application/json" \
--data '{
"grantType": "external_user",
"externalUserId": "member_839201"
}'
If JIT provisioning is enabled, GOFA can create the minimum active player identity when it does not exist. If JIT is disabled, both the GOFA authentication identity and client user must already exist. Sign-in never reactivates a disabled or inactive user and never accepts caller-supplied roles.
Password Grant
Use this compatibility grant only when the user intentionally signs in with a GOFA-managed email and password. For partner applications that already authenticate their own users, prefer the external-user grant instead.
Email alone is never sufficient authentication; the password is required to prove control of the account.
For backward compatibility, grantType may be omitted:
{
"clientId": "your-client-id",
"email": "user@example.com",
"password": "user-password"
}
When identifying the password grant explicitly:
{
"grantType": "password",
"clientId": "your-client-id",
"email": "user@example.com",
"password": "user-password"
}
Do not include externalUserId in a password-grant request.
Success Response
-
200 OK:Success Response{
"customToken": "string", // Firebase custom token
"user": {
"uid": "string",
"email": "string|null",
"displayName": "string|null",
"photoURL": "string|null",
"emailVerified": false,
"disabled": false
}
}
The email field is normally null for an external user created without an email address. Password users retain their Firebase profile values.
User Profile Fields
| Field | Type | Description |
|---|---|---|
| uid | string | Firebase user ID |
| string | null | User's email address, when available | |
| displayName | string | null | User's display name |
| photoURL | string | null | User's profile photo URL |
| emailVerified | boolean | Whether the user's email is verified |
| disabled | boolean | Whether the user account is disabled |
For Google or other OAuth sign-in, use the Firebase JS SDK directly on the frontend.
Error Responses
Errors use a stable code and a safe error message:
{
"code": "invalid_credentials",
"error": "Invalid credentials"
}
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | The body does not match exactly one supported grant |
401 | invalid_credentials | The password credentials or server API key are invalid |
403 | external_sso_disabled | External-user SSO is not enabled for this client or environment |
403 | jit_provisioning_disabled | The user is missing and the client is configured for existing users only |
403 | user_disabled | The GOFA authentication identity or client access is disabled/inactive |
404 | user_not_found | The required existing user identity cannot be resolved |
429 | rate_limit_exceeded | The request or provisioning rate limit was exceeded |
500 | internal_error | Authentication could not be completed because of an unexpected error |
503 | provisioning_incomplete | Provisioning did not reach a confirmed consistent state; retry safely |
For a 429 response, honor the Retry-After response header before retrying. Do not use authentication errors to probe whether an external ID exists.
Security and Token Handling
- Store server API keys in a backend secret manager and use a separate key for each environment.
- Rotate keys by overlapping the new and old keys, moving traffic, and then revoking the old key. See Client API Keys.
- Transmit the returned custom token only over HTTPS and use it immediately with Firebase
signInWithCustomTokenor a GOFA-approved hosted-module handoff flow. - Never log or persist passwords, API keys, custom tokens, or authorization headers.
- Keep user authorization in your own backend before requesting a token; possession of a valid server API key allows the backend to request tokens for external IDs in its client namespace.
POST /api/auth/exchange-token
Exchanges a valid Firebase ID token for a Firebase custom token with full custom claims. Used by external apps (e.g. kiosk apps) that already have a Firebase session and need a custom token to pass into GOFA web module URLs.
Exchange Token Request
Headers:
Authorization: Bearer <firebase_id_token>(required)
No request body is needed. The client ID is derived from the request hostname.
Exchange Token Response
-
200 OK:Success Response{
"customToken": "string"
} -
401 Unauthorized:{ "error": "Missing or invalid Authorization header" | "Invalid or expired token" } -
404 Not Found:{ "error": "Client user not found" } -
500 Internal Server Error:{ "error": "Internal server error" }
The returned customToken can be appended as a query parameter to GOFA web module URLs. The web app will automatically sign the user in and establish a session.
POST /api/auth/guest-custom-token
Creates a guest sign-in token for public trial flows (for example, fall-risk trial entry pages). The token is intended for immediate Firebase client sign-in as a temporary guest session.
Guest Custom Token Request
Headers:
- No request body is required.
- Client context is inferred from the incoming hostname.
Guest Custom Token Response
-
200 OK:Success Response{
"customToken": "string"
} -
403 Forbidden:{ "error": "Public guest sign-in is not allowed for this client" } -
429 Too Many Requests:{ "error": "Too many guest sign-in attempts. Please try again later.", "retryAfterSeconds": number } -
500 Internal Server Error:{ "error": "Internal Server Error" | "Client ID not found" }
This endpoint is intended for public trial onboarding where guests start quickly and optionally upgrade to a full sign-in method later.
Set Custom Claims API
POST /api/auth/set-claims
Sets custom Firebase Auth claims for a user, based on their client user document. Returns the updated claims and user profile.
Set Claims Request
Headers:
Content-Type: application/json
Body:
{
"clientId": "string", // Required. The client (tenant) ID
"idToken": "string" // Required. Firebase ID token for the user
}
Set Claims Response
-
200 OK:Success Response{
"success": true,
"claims": {
/* Custom claims object */
},
"user": {
"uid": "string",
"email": "string",
"displayName": "string|null",
"photoURL": "string|null",
"emailVerified": true,
"disabled": false
}
} -
400 Bad Request:{ "error": "Missing clientId" | "Missing idToken" } -
401 Unauthorized:{ "error": "Invalid idToken" } -
404 Not Found:{ "error": "Client user not found" | "Client user data missing" } -
500 Internal Server Error:{ "error": "Internal server error" }
Example Error Responses
{ "error": "Missing clientId" }
{ "error": "Invalid idToken" }
{ "error": "Client user not found" }
Notes
- The endpoint verifies the provided Firebase ID token and resolves the matching client user.
- If the user is found, the required access claims are generated from the user's current GOFA client data.
- Only fields defined in the schema are accepted; unknown fields will result in a 400 error.
- This endpoint is typically used after user registration or when updating user roles/status.
- For invitation-based 1Care onboarding, the sign-in flow can activate access for the invited email after the user successfully signs in with that same email.
Related
- See
/api/auth/custom-tokenfor obtaining a Firebase custom token.