Appearance
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
| Service | URL |
|---|---|
| Identity Service | https://engagifii-sandbox-identityservice.azurewebsites.net |
| Auth Service | https://engagifii-sandbox-auth.azurewebsites.net |
API Endpoints
| API Module | Base URL |
|---|---|
| Relationship API | https://engagifii-sandbox-crm.azurewebsites.net |
| Event Management API | https://engagifii-sandbox-event.azurewebsites.net |
| Revenue Management API | https://engagifii-sandbox-revenue.azurewebsites.net |
| Legislative Tracking API | https://engagifii-sandbox-billtracking.azurewebsites.net |
| Training & Accreditation API | https://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
- Login - User authenticates with email/password and receives available workspaces
- Choose Workspace - User selects a workspace and gets workspace-specific access token
- 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:
| Field | Type | Required | Description |
|---|---|---|---|
userName | string | Yes | User's email address |
password | string | Yes | User'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
| Field | Type | Description |
|---|---|---|
identityId | string | Unique identifier for the authenticated user |
workSpaceList | array | List of all workspaces the user has access to |
workSpaceList[].tenantId | string | Unique workspace identifier |
workSpaceList[].tenantName | string | Display name of the workspace |
workSpaceList[].tenantCode | string | Short code for the workspace (used in subsequent requests) |
workSpaceList[].personName | string | User's name in this workspace |
workSpaceList[].lastLogin | string | ISO 8601 timestamp of last login |
workSpaceList[].isActive | boolean | Whether the workspace is active |
accessToken | string | NULL at this stage |
refreshToken | string | NULL at this stage |
What Happens Next
At this stage, you receive:
- ✅
identityId- User's identity - ✅
workSpaceList- All workspaces the user has access to - ⚠️
accessTokenandrefreshTokenare NULL (you'll get these in Step 2)
Next Steps:
- Store
identityId,userName, andpasswordtemporarily (in memory only) - Display the
workSpaceListto the user as selectable options - 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:
| Field | Type | Required | Description |
|---|---|---|---|
tenantCode | string | Yes | The tenant code from the selected workspace |
userName | string | Yes | User's email address (same as Step 1) |
password | string | Yes | User's password (same as Step 1) |
Response
json
{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Response Fields
| Field | Type | Description |
|---|---|---|
accessToken | string | JWT token for authenticating API requests |
refreshToken | string | JWT 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:
- Store
accessToken,refreshToken, and selected workspace details securely - Clear the temporary
userNameandpasswordfrom memory - 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:
Authorization: Bearer {accessToken}tenant-code: {tenantCode}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:
| Header | Value | Description |
|---|---|---|
accept | application/json | Response content type |
tenant-code | COMPANYA | The tenant code from the selected workspace |
Authorization | Bearer {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/Authrizeendpoint on form submission - [ ] Store credentials temporarily in memory only (NOT localStorage)
- [ ] Display workspace selection UI from
workSpaceListresponse
Token Management
- [ ] Call
/Services/AuthorizeUserForWorkSpacewhen user selects workspace - [ ] Store
accessTokenandrefreshTokensecurely (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
| Practice | Description |
|---|---|
| Use HTTPS | Always use HTTPS in production environments |
| Secure Token Storage | Store tokens in memory, sessionStorage, or localStorage (web apps) |
| Clear Credentials | Clear email/password from memory immediately after getting tokens |
| Token Refresh | Implement token refresh logic before expiration |
| Proper Logout | Clear all tokens and workspace data on logout |
| Error Handling | Handle 401 Unauthorized responses and re-authenticate |
❌ DON'T Do These Things
| Practice | Reason |
|---|---|
| Store passwords permanently | Security risk - only store temporarily in memory |
| Expose tokens in URLs | Tokens can leak through browser history and logs |
| Share tokens between users | Each user needs their own authentication |
| Forget required headers | Both tenant-code and Authorization headers are mandatory |
| Log tokens | Never log tokens in console or server logs |
| Use HTTP in production | Always use HTTPS to encrypt data in transit |
API Environments
Choose the appropriate environment for your integration needs:
| Environment | Identity API | CRM API | Access |
|---|---|---|---|
| Support (Testing) | https://engagifii-sandbox-identityservices.azurewebsites.net/api/v1 | https://engagifii-sandbox-crm.azurewebsites.net/api/v1 | Internal team only |
| Development (Sandbox) | https://engagifii-sandbox-identityservices.azurewebsites.net/api/v1 | https://engagifii-dev-sandbox.azurewebsites.net/api/v1 | Development & testing |
| Production (Live) | https://engagifii-identityservices.azurewebsites.net/api/v1 | https://engagifii-crm.azurewebsites.net/api/v1 | Production 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
tenantCodeexactly 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
Authorizationheader format:Bearer {token}(with space) - ✅ Verify
tenant-codeheader is included in the request - ✅ Ensure the token hasn't expired - implement token refresh
- ✅ Confirm both
userNameandtenantCodematch 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:
| Step | Endpoint | Method | Required Headers | Request Body |
|---|---|---|---|---|
| 1. Login | /Services/Authrize | POST | Content-Type: application/json | userName, password |
| 2. Get Token | /Services/AuthorizeUserForWorkSpace | POST | Content-Type: application/json | tenantCode, userName, password |
| 3. API Call | Any API endpoint (e.g., /Organization/OrganizationListLite) | GET/POST | accept: application/jsontenant-code: {code}Authorization: Bearer {token} | Varies by endpoint |
Key Takeaways
- Step 1 gives you
workSpaceList(no tokens yet) - Step 2 gives you
accessTokenandrefreshToken - Step 3 uses tokens + tenant code for all API calls
Support & Documentation
API Documentation (Swagger)
- Identity Service: Sandbox Swagger
- CRM API: Sandbox 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)
