Authentication
Overview
The Public API uses a bearer token in the Authorization header:
Authorization: Bearer <your_api_key>
This key/token is partner-specific and controls which data you can access.
What to include in requests
Most requests should include:
Authorization: Bearer <your_api_key>Content-Type: application/json(for requests with a JSON body)
Access control
External partners can only access their own data. Attempts to access data for another partner will return 403 Forbidden.
OAuth2 Integration Guide
This guide explains how to integrate your external system with eFICA using OAuth2. eFICA uses the Authorization Code Flow with PKCE (Proof Key for Code Exchange) to ensure secure authentication and authorization.
Overview
The integration process involves the following steps:
- Register your application in eFICA to get a Client ID and Client Secret.
- Configure your external system with the Client ID and Client Secret (if required by your system).
- Direct the user to the eFICA authorization endpoint.
- Receive the authorization code at your redirect URI.
- Exchange the code for an access token and refresh token (using PKCE, no client secret needed).
- Use the access token to make API requests.
- Refresh the access token when it expires.
Flow Diagram
Prerequisites
Before you begin, you must register your application within the eFICA platform. When you create an OAuth2 client, you will receive:
- Client ID: A unique identifier for your application.
- Client Secret: A secret key for your application (shown only once during creation - save it securely).
- Redirect URI: The URL where eFICA will send the user after authorization. This must be an HTTPS URL (or localhost for development).
Understanding Client Secret vs PKCE
Client Secret:
- Generated and returned when you create an OAuth2 client in eFICA.
- Save it immediately - it's only shown once during creation.
- May be required by your external system for configuration/identification purposes.
- NOT used in the OAuth2 token exchange request (PKCE is used instead).
PKCE (Proof Key for Code Exchange):
- Provides security for the OAuth2 authorization flow.
- Uses a dynamically generated
code_verifierandcode_challengeinstead of a static client secret. - This is what you use when exchanging the authorization code for tokens.
- More secure for public clients (like mobile apps or SPAs).
Summary: You receive both a Client ID and Client Secret when registering, but for the actual OAuth2 flow, you only use the Client ID and PKCE. The Client Secret is for your records and may be needed for configuring your external system.
Step 1: Authorization Request
To initiate the flow, redirect the user to the eFICA authorization endpoint. You must generate a PKCE Code Verifier and Code Challenge.
Before you start: Make sure you have:
- Your Client ID (from registration)
- Your registered Redirect URI
- A way to generate and store the PKCE code verifier securely
PKCE Generation (Example in JavaScript)
PKCE (Proof Key for Code Exchange) is a security extension for OAuth2 that prevents authorization code interception attacks. You generate a random code verifier, then create a code challenge from it.
Step 1: Generate Code Verifier
function generateCodeVerifier() {
// Generate 32 random bytes (64 hex characters)
const array = new Uint32Array(56/2);
window.crypto.getRandomValues(array);
return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');
}
Step 2: Generate Code Challenge
async function generateCodeChallenge(codeVerifier) {
const encoder = new TextEncoder();
const data = encoder.encode(codeVerifier);
const digest = await window.crypto.subtle.digest('SHA-256', data);
// Base64URL encode (replace + with -, / with _, remove padding)
return btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
Usage:
// Store the verifier securely (you'll need it later)
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
// Use codeChallenge in the authorization URL
// Keep codeVerifier for the token exchange
Redirect URL
Construct the URL with the following parameters:
GET /oauth2/authorize
| Parameter | Required | Description |
|---|---|---|
client_id | Yes | Your application's Client ID. |
redirect_uri | Yes | The URL to redirect back to after login. Must match the registered URI. |
code_challenge | Yes | The SHA256 hash of your code verifier (Base64URL encoded). |
code_challenge_method | Yes | Must be S256. |
state | No | An opaque value used to maintain state between the request and callback (prevents CSRF). |
Example URL:
https://sandboxapi.efica.co.za/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=https://yourapp.com/callback&code_challenge=YOUR_CODE_CHALLENGE&code_challenge_method=S256&state=xyz123
Step 2: Handle the Callback
After the user logs in successfully, eFICA will redirect them back to your redirect_uri with an authorization code.
Example Callback:
https://yourapp.com/callback?code=AUTHORIZATION_CODE&state=xyz123
- code: The authorization code (valid for 10 minutes, one-time use).
- state: The state value you provided in the initial request. Verify this matches to prevent CSRF attacks.
Step 3: Exchange Code for Token
Make a POST request to the token endpoint to exchange the authorization code for an access token.
Endpoint: POST /oauth2/token
Headers:
Content-Type: application/json
Body:
{
"grant_type": "authorization_code",
"client_id": "YOUR_CLIENT_ID",
"code": "AUTHORIZATION_CODE_FROM_CALLBACK",
"code_verifier": "YOUR_ORIGINAL_CODE_VERIFIER",
"redirect_uri": "YOUR_REDIRECT_URI"
}
Important:
- You do NOT need to include
client_secretin this request. The PKCEcode_verifierprovides the security validation. - The
code_verifiermust be the same one you used to generate thecode_challengein Step 1. - The
redirect_urimust exactly match the one used in the authorization request.
Response (Success - 200 OK):
{
"access_token": "eyJhbGciOiJFZERT...",
"refresh_token": "eyJhbGciOiJFZERT...",
"token_type": "Bearer",
"expires_in": 3600,
"userID": "user-guid-123",
"partnerID": "partner-guid-456"
}
access_token: The JWT token used to authenticate API requests (valid for 1 hour).refresh_token: A long-lived token used to get new access tokens (valid for 7 days).
Step 4: Using the Access Token
Include the access token in the Authorization header of your API requests.
Header:
Authorization: Bearer YOUR_ACCESS_TOKEN
Step 5: Refreshing the Token
When the access token expires (401 Unauthorized), use the refresh token to obtain a new one.
Endpoint: POST /oauth2/token
Headers:
Content-Type: application/json
Body:
{
"grant_type": "refresh_token",
"client_id": "YOUR_CLIENT_ID",
"refresh_token": "YOUR_REFRESH_TOKEN"
}
Response:
Returns a new access_token and a new refresh_token.
Error Handling
If an error occurs, the API will return a 400 or 401 status code with a JSON body:
{
"error": "invalid_request",
"error_description": "Description of what went wrong"
}
Common errors:
invalid_request: Missing parameters.invalid_grant: Invalid code, expired token, or invalid credentials.unauthorized_client: Client is not authorized for this action.unsupported_grant_type: Grant type must beauthorization_codeorrefresh_token.
Quick Reference
What You Get When Registering
- ✅ Client ID - Use this in all OAuth2 requests
- ✅ Client Secret - Save this securely (shown only once). May be needed for external system configuration.
- ✅ Redirect URI - Must match exactly in authorization requests
What You Use in OAuth2 Flow
- ✅ Client ID - Required in authorization and token requests
- ✅ PKCE Code Verifier & Challenge - Required for security (replaces client secret in token exchange)
- ❌ Client Secret - NOT used in the OAuth2 token exchange (PKCE is used instead)
Key Points
- Client Secret is generated when you create a client - save it immediately.
- Client Secret is NOT sent in token exchange requests - PKCE
code_verifieris used instead. - Your external system may require Client ID and Secret for configuration, even though the secret isn't used in the OAuth2 flow.
- PKCE provides security - generate a new
code_verifierfor each authorization flow.
This documentation is maintained by the eFICA development team. For updates and corrections, please contact your account manager.
Last Updated: 27 January 2026