Skip to content

Getting Started with Custom Login Screen

Overview

Use this guide if you want to build your own custom login screen instead of redirecting users to the Engagifii default authentication page. This approach gives you full control over the user experience while maintaining secure authentication.

Sandbox Environment Base URLs

Authentication Services

ServiceURL
Identity Servicehttps://engagifii-sandbox-identityservice.azurewebsites.net
Auth Servicehttps://engagifii-sandbox-auth.azurewebsites.net

API Endpoints

API ModuleBase URL
Relationship APIhttps://engagifii-sandbox-crm.azurewebsites.net
Event Management APIhttps://engagifii-sandbox-event.azurewebsites.net
Revenue Management APIhttps://engagifii-sandbox-revenue.azurewebsites.net
Legislative Tracking APIhttps://engagifii-sandbox-billtracking.azurewebsites.net
Training & Accreditation APIhttps://engagifii-sandbox-tna.azurewebsites.net

Frontend URL Pattern

https://[tenant-code].engagifii-sandbox.com/

Example: https://COMPANYA.engagifii-sandbox.com/


Authentication Flow Overview

The Engagifii authentication system uses a two-step process to ensure secure, workspace-scoped access:

mermaid
graph LR
    A[Step 1: Login] --> B[Get Workspaces]
    B --> C[Step 2: Choose Workspace]
    C --> D[Get Access Token]
    D --> E[Step 3: Make API Calls]
    E --> F[Use Token + Tenant Code]

Flow Summary

  1. Login - User authenticates with email/password and receives available workspaces
  2. Choose Workspace - User selects a workspace and gets workspace-specific access token
  3. Make API Calls - Use access token and tenant code for all subsequent requests

Step 1: User Login - Get Available Workspaces

In this step, the user logs in with their credentials and receives a list of all workspaces they have access to.

Important Note

The endpoint is spelled Authrize (not "Authorize") - this is intentional and must be used exactly as shown.

Request

Endpoint: POST /api/v1/Services/Authrize

bash
curl -X POST https://engagifii-sandbox-identityservices.azurewebsites.net/api/v1/Services/Authrize \
  -H "Content-Type: application/json" \
  -d '{
    "userName": "your-email@example.com",
    "password": "your-password"
  }'

Request Body:

FieldTypeRequiredDescription
userNamestringYesUser's email address
passwordstringYesUser's password

Response

json
{
  "identityId": "abc123-def456-ghi789",
  "workSpaceList": [
    {
      "tenantId": "tenant-uuid-1",
      "tenantName": "Company A",
      "tenantCode": "COMPANYA",
      "logoUrl": "https://...",
      "timezone": "UTC",
      "lastLogin": "2025-01-15T10:30:00Z",
      "isActive": true,
      "isDeleted": false,
      "personName": "John Doe"
    },
    {
      "tenantId": "tenant-uuid-2",
      "tenantName": "Company B",
      "tenantCode": "COMPANYB",
      "logoUrl": "https://...",
      "timezone": "UTC",
      "lastLogin": "2025-01-10T08:15:00Z",
      "isActive": true,
      "isDeleted": false,
      "personName": "John Doe"
    }
  ],
  "refreshToken": null,
  "accessToken": null
}

Response Fields

FieldTypeDescription
identityIdstringUnique identifier for the authenticated user
workSpaceListarrayList of all workspaces the user has access to
workSpaceList[].tenantIdstringUnique workspace identifier
workSpaceList[].tenantNamestringDisplay name of the workspace
workSpaceList[].tenantCodestringShort code for the workspace (used in subsequent requests)
workSpaceList[].personNamestringUser's name in this workspace
workSpaceList[].lastLoginstringISO 8601 timestamp of last login
workSpaceList[].isActivebooleanWhether the workspace is active
accessTokenstringNULL at this stage
refreshTokenstringNULL at this stage

What Happens Next

At this stage, you receive:

  • identityId - User's identity
  • workSpaceList - All workspaces the user has access to
  • ⚠️ accessToken and refreshToken are NULL (you'll get these in Step 2)

Next Steps:

  1. Store identityId, userName, and password temporarily (in memory only)
  2. Display the workSpaceList to the user as selectable options
  3. Allow the user to select their desired workspace

Step 2: Workspace Authorization - Get Access Token

After the user selects a workspace from the list, you'll exchange their credentials + tenant code for workspace-specific access tokens.

Example Scenario

User selects "Company A" which has tenantCode: "COMPANYA"

Request

Endpoint: POST /api/v1/Services/AuthorizeUserForWorkSpace

bash
curl -X POST https://engagifii-sandbox-identityservices.azurewebsites.net/api/v1/Services/AuthorizeUserForWorkSpace \
  -H "Content-Type: application/json" \
  -d '{
    "tenantCode": "COMPANYA",
    "userName": "your-email@example.com",
    "password": "your-password"
  }'

Request Body:

FieldTypeRequiredDescription
tenantCodestringYesThe tenant code from the selected workspace
userNamestringYesUser's email address (same as Step 1)
passwordstringYesUser's password (same as Step 1)

Response

json
{
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response Fields

FieldTypeDescription
accessTokenstringJWT token for authenticating API requests
refreshTokenstringJWT token for refreshing expired access tokens

You're Ready!

At this stage, you receive:

  • accessToken - Use this for all API calls
  • refreshToken - Use this to refresh the access token when it expires

Next Steps:

  1. Store accessToken, refreshToken, and selected workspace details securely
  2. Clear the temporary userName and password from memory
  3. You're now ready to make authenticated API calls!

Step 3: Making API Calls with Authentication

Now you can call any Engagifii API using the access token and tenant code from Step 2.

Required Headers

Every API request MUST include these three headers:

  1. Authorization: Bearer {accessToken}
  2. tenant-code: {tenantCode}
  3. accept: application/json

Example: Get Organizations List

Endpoint: GET /api/v1/Organization/OrganizationListLite

bash
curl -X GET https://engagifii-sandbox-crm.azurewebsites.net/api/v1/Organization/OrganizationListLite \
  -H "accept: application/json" \
  -H "tenant-code: COMPANYA" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Required Headers:

HeaderValueDescription
acceptapplication/jsonResponse content type
tenant-codeCOMPANYAThe tenant code from the selected workspace
AuthorizationBearer {accessToken}JWT token from Step 2

Response

json
[
  {
    "organizationId": "org-uuid-1",
    "organizationName": "Acme Corp",
    "email": "contact@acme.com",
    "phone": "+1-555-0123",
    "isActive": true
  },
  {
    "organizationId": "org-uuid-2",
    "organizationName": "TechStart Inc",
    "email": "info@techstart.com",
    "phone": "+1-555-0456",
    "isActive": true
  }
]

Complete Workflow Example

Here's a complete bash script demonstrating the entire authentication flow from login to API calls:

shell
#!/bin/bash

# Variables
EMAIL="your-email@example.com"
PASSWORD="your-password"
IDENTITY_API="https://engagifii-sandbox-identityservices.azurewebsites.net/api/v1"
CRM_API="https://engagifii-sandbox-crm.azurewebsites.net/api/v1"

# Step 1: Login and get workspaces
echo "Step 1: Logging in..."
LOGIN_RESPONSE=$(curl -s -X POST "${IDENTITY_API}/Services/Authrize" \
  -H "Content-Type: application/json" \
  -d "{\"userName\":\"${EMAIL}\",\"password\":\"${PASSWORD}\"}")

echo "$LOGIN_RESPONSE" | jq '.'

# Extract first workspace tenant code
TENANT_CODE=$(echo "$LOGIN_RESPONSE" | jq -r '.workSpaceList[0].tenantCode')
echo "\nSelected workspace: $TENANT_CODE"

# Step 2: Get access token for workspace
echo "\nStep 2: Getting access token for workspace..."
TOKEN_RESPONSE=$(curl -s -X POST "${IDENTITY_API}/Services/AuthorizeUserForWorkSpace" \
  -H "Content-Type: application/json" \
  -d "{\"tenantCode\":\"${TENANT_CODE}\",\"userName\":\"${EMAIL}\",\"password\":\"${PASSWORD}\"}")

ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.accessToken')
echo "Access token obtained: ${ACCESS_TOKEN:0:50}..."

# Step 3: Make API call
echo "\nStep 3: Fetching organizations..."
curl -s -X GET "${CRM_API}/Organization/OrganizationListLite" \
  -H "accept: application/json" \
  -H "tenant-code: ${TENANT_CODE}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq '.'

Integration Checklist

Use this checklist when integrating custom login into your application:

Frontend Implementation

  • [ ] Create login form with email/password fields
  • [ ] Call /Services/Authrize endpoint on form submission
  • [ ] Store credentials temporarily in memory only (NOT localStorage)
  • [ ] Display workspace selection UI from workSpaceList response

Token Management

  • [ ] Call /Services/AuthorizeUserForWorkSpace when user selects workspace
  • [ ] Store accessToken and refreshToken securely (sessionStorage/localStorage)
  • [ ] Store selected workspace details (tenantCode, tenantName, etc.)
  • [ ] Clear temporary credentials (email/password) from memory immediately

API Integration

  • [ ] Add required headers to ALL API calls:
    • Authorization: Bearer {accessToken}
    • tenant-code: {tenantCode}
    • accept: application/json
  • [ ] Implement token refresh logic before expiration
  • [ ] Handle 401 Unauthorized responses gracefully

Security & Cleanup

  • [ ] Implement logout functionality to clear all stored tokens
  • [ ] Never store passwords permanently
  • [ ] Use HTTPS for all API requests in production

Security Best Practices

Security Warning

Proper security implementation is critical for protecting user data and preventing unauthorized access.

✅ DO These Things

PracticeDescription
Use HTTPSAlways use HTTPS in production environments
Secure Token StorageStore tokens in memory, sessionStorage, or localStorage (web apps)
Clear CredentialsClear email/password from memory immediately after getting tokens
Token RefreshImplement token refresh logic before expiration
Proper LogoutClear all tokens and workspace data on logout
Error HandlingHandle 401 Unauthorized responses and re-authenticate

❌ DON'T Do These Things

PracticeReason
Store passwords permanentlySecurity risk - only store temporarily in memory
Expose tokens in URLsTokens can leak through browser history and logs
Share tokens between usersEach user needs their own authentication
Forget required headersBoth tenant-code and Authorization headers are mandatory
Log tokensNever log tokens in console or server logs
Use HTTP in productionAlways use HTTPS to encrypt data in transit

API Environments

Choose the appropriate environment for your integration needs:

EnvironmentIdentity APICRM APIAccess
Support (Testing)https://engagifii-sandbox-identityservices.azurewebsites.net/api/v1https://engagifii-sandbox-crm.azurewebsites.net/api/v1Internal team only
Development (Sandbox)https://engagifii-sandbox-identityservices.azurewebsites.net/api/v1https://engagifii-dev-sandbox.azurewebsites.net/api/v1Development & testing
Production (Live)https://engagifii-identityservices.azurewebsites.net/api/v1https://engagifii-crm.azurewebsites.net/api/v1Production use

Environment Selection

  • Use Development (Sandbox) for integration testing and development
  • Use Production (Live) only when you're ready to go live
  • Support environment is restricted to internal team members only

Troubleshooting

Common issues and their solutions:

Authentication Failed (Step 1)

Symptoms
  • Error response when calling /Services/Authrize
  • "Invalid credentials" or "Authentication failed" message

Solutions:

  • ✅ Verify email and password are correct
  • ✅ Check that the API endpoint is accessible
  • ✅ Ensure JSON payload is properly formatted
  • ✅ Confirm you're using the correct environment (sandbox/production)

Workspace Authorization Failed (Step 2)

Symptoms
  • Error response when calling /Services/AuthorizeUserForWorkSpace
  • "Invalid tenant code" or "Authorization failed" message

Solutions:

  • ✅ Verify tenantCode exactly matches one from the workspace list
  • ✅ Check that you're using the same credentials from Step 1
  • ✅ Re-authenticate if too much time has passed after Step 1
  • ✅ Ensure the workspace is active (isActive: true)

401 Unauthorized on API Calls (Step 3)

Symptoms
  • 401 Unauthorized response when calling any API
  • "Invalid token" or "Unauthorized" message

Solutions:

  • ✅ Check Authorization header format: Bearer {token} (with space)
  • ✅ Verify tenant-code header is included in the request
  • ✅ Ensure the token hasn't expired - implement token refresh
  • ✅ Confirm both userName and tenantCode match the authentication
  • ✅ Re-authenticate if token is expired

CORS Issues

Symptoms
  • CORS policy errors in browser console
  • "Access-Control-Allow-Origin" errors
  • Requests blocked by browser

Solutions:

  • ✅ CORS should be enabled on Engagifii APIs by default
  • ✅ Contact Engagifii support if CORS errors persist
  • ✅ Use a development proxy if needed for local testing
  • ✅ Ensure you're making requests from an allowed origin

Quick Reference

One-page summary of the complete authentication flow:

StepEndpointMethodRequired HeadersRequest Body
1. Login/Services/AuthrizePOSTContent-Type: application/jsonuserName, password
2. Get Token/Services/AuthorizeUserForWorkSpacePOSTContent-Type: application/jsontenantCode, userName, password
3. API CallAny API endpoint (e.g., /Organization/OrganizationListLite)GET/POSTaccept: application/json
tenant-code: {code}
Authorization: Bearer {token}
Varies by endpoint

Key Takeaways

  1. Step 1 gives you workSpaceList (no tokens yet)
  2. Step 2 gives you accessToken and refreshToken
  3. Step 3 uses tokens + tenant code for all API calls

Support & Documentation

API Documentation (Swagger)

Additional Resources

  • Main Authentication Guide: See the Authentication Overview for OAuth/OIDC flow
  • API Reference: Check individual module documentation for specific endpoints
  • Integration Examples: Find code samples in each module's documentation

Need Help?

  • Review this guide and the troubleshooting section above
  • Check the Swagger documentation for endpoint details
  • Contact your system administrator for credentials and access

Last Updated: January 2025 Version: 1.0 Environment: Sandbox (Development)