Skip to main content

Getting Started with GOFA API Integration

Overview

GOFA provides secure APIs for both user-facing and backend system integration, using Firebase for authentication and authorization.

This guide shows how to obtain credentials and tokens, and how to call GOFA APIs securely from both frontend and backend systems.

info

Environment Domains:
- UAT (User Acceptance Testing): www.uat.gofa.app
- Production: www.gofa.app
All example endpoints below use the UAT domain. For production, replace www.uat.gofa.app with www.gofa.app.


Authentication Flow Diagram

This diagram shows the user-facing, partner SSO, and backend/admin authentication flows for GOFA API integration.


User-facing Website API Integration

Preparation (User-facing)

  • Get your clientId and Firebase config: Contact GOFA support to obtain your organization’s clientId and your Firebase config:

    const firebaseConfig = {
    apiKey: "GOFA_FIREBASE_API_KEY",
    authDomain: "GOFA_FIREBASE_AUTH_DOMAIN",
    projectId: "GOFA_FIREBASE_PROJECT_ID",
    // ...other config fields
    };
  • Install Firebase SDK (for end-user website integrations only):

    If you are building an end-user website or app that authenticates users and calls APIs requiring a Firebase JWT (User Token), install the Firebase SDK:

    bun add firebase

    or

    npm install firebase

    If you are only calling APIs that require a Client Token (Backend/Admin JWT) from your backend, you do NOT need to install or use Firebase in your project.


User Authentication Flow

Use this option when your application already authenticated the user in its own identity system. Your trusted backend requests a GOFA custom token using a server API key and your stable user identifier.

Preferred custom-token flow

Use the external-user grant for new partner integrations. It reuses your existing user identity and avoids asking the user to create or share a separate GOFA password.

Keep the API key on your server

The external-user grant is server-to-server only. Never call it directly from a browser, mobile app, desktop app, or other distributed client.

  1. Ask GOFA to enable external-user SSO for the intended client and environment, and obtain a server API key. UAT and production must use separate keys.

  2. After your backend authenticates and authorizes its user, call /api/auth/custom-token:

    Partner backend
    const gofaApiKey = await getGofaApiKeyFromYourSecretManager();

    const response = await fetch(
    "https://www.uat.gofa.app/api/auth/custom-token",
    {
    method: "POST",
    headers: {
    Authorization: `Bearer ${gofaApiKey}`,
    "Content-Type": "application/json",
    },
    body: JSON.stringify({
    grantType: "external_user",
    externalUserId: authenticatedUser.stableId,
    }),
    },
    );

    if (!response.ok) {
    throw new Error(`GOFA sign-in failed with status ${response.status}`);
    }

    const { customToken } = await response.json();
  3. Return the short-lived custom token to the authenticated application over HTTPS, then sign in with Firebase:

    Partner application
    import { getAuth, signInWithCustomToken } from "firebase/auth";

    const auth = getAuth(app);
    await signInWithCustomToken(auth, customTokenFromYourBackend);

    Use the custom token immediately and do not log or persist it. For a GOFA hosted-module handoff, use the integration pattern agreed with GOFA.

GOFA derives the client from the server API key. Do not send clientId, email, password, roles, or access claims in the external-user request. Depending on the client configuration, the user must either already exist or can be created with minimum player access through approved JIT provisioning.


Option B: Sign In with GOFA Email and Password

Use this compatibility option when the user has and intends to use GOFA-managed credentials. If your application already authenticates the user, prefer Option A instead.

  1. POST to /api/auth/custom-token:

    {
    "grantType": "password",
    "clientId": "your-client-id",
    "email": "user@example.com",
    "password": "user-password"
    }
  2. Sign in with Firebase using the returned custom token:

    import { initializeApp } from "firebase/app";
    import { getAuth, signInWithCustomToken } from "firebase/auth";
    const app = initializeApp(firebaseConfig);
    const auth = getAuth(app);
    await signInWithCustomToken(auth, "customToken-from-api");

    The custom token is for Firebase Auth sign-in only, not for direct GOFA API access.


Option C: Sign In Directly with Firebase, Then Set Claims

  1. Sign in with Firebase (email/password, Google, etc.):

    import { getAuth, signInWithEmailAndPassword } from "firebase/auth";
    const auth = getAuth(app);
    const userCredential = await signInWithEmailAndPassword(
    auth,
    "user@example.com",
    "user-password",
    );
    const idToken = await userCredential.user.getIdToken();
  2. POST to /api/auth/set-claims:

    { "idToken": "firebase-id-token" }

    This sets the required custom claims for GOFA API access.


Calling a GOFA API Endpoint that Requires User Token

See the Challenge Plays API for details on available endpoints and request/response formats for challenge play operations.

After sign-in and claims are set, call protected endpoints like this:

import { getAuth } from "firebase/auth";
const auth = getAuth();
const idToken = await auth.currentUser?.getIdToken();

const response = await fetch("https://www.uat.gofa.app/api/challenge-plays", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${idToken}`,
},
body: JSON.stringify({
challengeId: "abc123",
score: 42,
}),
});

const result = await response.json();
console.log(result);
  • Always include the Authorization: Bearer <idToken> header.

Backend/Admin API Integration

Preparation (Backend/Admin)

  • Get your clientId and clientSecret: Contact GOFA support to obtain your organization’s clientId and clientSecret (required for backend authentication).

Retrieve the ClientToken

// Example using Node.js (fetch or axios)
const response = await fetch("https://www.uat.gofa.app/api/client/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
clientId: "your-client-id",
clientSecret: "your-client-secret",
}),
});
const data = await response.json();
const clientToken = data.token; // Use this as the ClientToken

Call the protected endpoint with the ClientToken

const clientId = "your-client-id";
const response2 = await fetch(
`https://www.uat.gofa.app/api/client/${clientId}/users`,
{
method: "GET", // or POST, PATCH, DELETE as required
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${clientToken}`,
},
// body: JSON.stringify({ ... }) // for POST/PATCH requests
},
);
const result = await response2.json();
console.log(result);
  • Always include the Authorization: Bearer <ClientToken> header for backend-to-backend API calls.
  • Replace the method and body as needed for your use case.

Notes

  • For Google/social login, always use the Firebase JS SDK, then call /api/auth/set-claims.
  • For partner external-user SSO, authenticate the user in your own backend first and keep the GOFA server API key out of distributed applications.
  • Always use HTTPS and never log user credentials or tokens.
  • Authentication errors include a stable code and a safe error message. See User Auth API.
  • Contact GOFA support for your Firebase config and any integration questions.