Skip to main content

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, and password.

The custom token is for immediate Firebase sign-in. It is not a GOFA API bearer token.

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.

Recommended for new partner integrations

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.

Server-to-server only

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:

External-User Grant
{
"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.

Server-side request
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"
}'
Provisioning behavior

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:

Legacy-Compatible Password Grant
{
"clientId": "your-client-id",
"email": "user@example.com",
"password": "user-password"
}

When identifying the password grant explicitly:

Explicit Password Grant
{
"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

FieldTypeDescription
uidstringFirebase user ID
emailstring | nullUser's email address, when available
displayNamestring | nullUser's display name
photoURLstring | nullUser's profile photo URL
emailVerifiedbooleanWhether the user's email is verified
disabledbooleanWhether the user account is disabled
note

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:

Example Error
{
"code": "invalid_credentials",
"error": "Invalid credentials"
}
StatusCodeMeaning
400invalid_requestThe body does not match exactly one supported grant
401invalid_credentialsThe password credentials or server API key are invalid
403external_sso_disabledExternal-user SSO is not enabled for this client or environment
403jit_provisioning_disabledThe user is missing and the client is configured for existing users only
403user_disabledThe GOFA authentication identity or client access is disabled/inactive
404user_not_foundThe required existing user identity cannot be resolved
429rate_limit_exceededThe request or provisioning rate limit was exceeded
500internal_errorAuthentication could not be completed because of an unexpected error
503provisioning_incompleteProvisioning 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 signInWithCustomToken or 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" }

note

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" }

note

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:

Request 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

Missing clientId
{ "error": "Missing clientId" }
Invalid idToken
{ "error": "Invalid idToken" }
Client user not found
{ "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.
  • See /api/auth/custom-token for obtaining a Firebase custom token.