Appearance
Getting Started with Engagifii Training & Accreditation API
This guide will walk you through setting up and making your first successful API calls to the Engagifii Training & Accreditation system.
Table of Contents
- Prerequisites
- Authentication Setup
- First API Call
- Testing Guide
- Common Integration Patterns
- Troubleshooting
Prerequisites
Before you begin integration, ensure you have:
Required Tools & Accounts
- HTTP Client: Postman, curl, or programming language with HTTP support
- Tenant Code: Unique identifier for your organization (provided by administrator)
- API Credentials: Authentication tokens if required
- Development Environment: Any modern programming language (JavaScript, Python, C#, Java, etc.)
Technical Requirements
- HTTPS Support: All API calls must use HTTPS protocol
- JSON Parser: Ability to parse JSON responses
- Header Support: Ability to set custom HTTP headers
- Error Handling: Proper exception handling in your code
Knowledge Requirements
- Basic understanding of RESTful APIs
- Familiarity with HTTP methods (GET, POST, PUT, DELETE)
- Understanding of JSON data format
- Basic programming skills in your chosen language
Authentication Setup
The Engagifii API uses header-based authentication with tenant isolation.
Step 1: Obtain Your Tenant Code
Your tenant code is a unique identifier that isolates your organization's data. This will be provided by your system administrator.
javascript
const TENANT_CODE = 'your-tenant-code-here';Step 2: Configure Request Headers
Every API request must include the tenant code in the headers:
javascript
const headers = {
'tenant-code': TENANT_CODE,
'Content-Type': 'application/json',
'Accept': 'application/json'
};Step 3: Optional Authentication Token
If your organization uses additional authentication:
javascript
const headers = {
'tenant-code': TENANT_CODE,
'Authorization': 'Bearer YOUR_TOKEN_HERE', // If required
'Content-Type': 'application/json'
};First API Call
Let's make your first API call to verify everything is set up correctly.
Test Connection - Get Awards List
Using cURL
bash
curl -X GET "https://engagifii-trainingandaccreditation.azurewebsites.net/api/v1/Awards/List" \
-H "tenant-code: YOUR_TENANT_CODE" \
-H "Content-Type: application/json"Using JavaScript (Fetch API)
javascript
const BASE_URL = 'https://engagifii-trainingandaccreditation.azurewebsites.net';
async function getAwardsList() {
try {
const response = await fetch(`${BASE_URL}/api/v1/Awards/List`, {
method: 'GET',
headers: {
'tenant-code': 'YOUR_TENANT_CODE',
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('Awards List:', data);
return data;
} catch (error) {
console.error('Error fetching awards:', error);
}
}
// Call the function
getAwardsList();Using Python
python
import requests
import json
BASE_URL = 'https://engagifii-trainingandaccreditation.azurewebsites.net'
TENANT_CODE = 'YOUR_TENANT_CODE'
def get_awards_list():
url = f"{BASE_URL}/api/v1/Awards/List"
headers = {
'tenant-code': TENANT_CODE,
'Content-Type': 'application/json'
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
print('Awards List:', json.dumps(data, indent=2))
return data
except requests.exceptions.RequestException as e:
print(f'Error fetching awards: {e}')
return None
# Call the function
awards = get_awards_list()Using C# (.NET)
csharp
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class EngagifiiApiClient
{
private const string BASE_URL = "https://engagifii-trainingandaccreditation.azurewebsites.net";
private const string TENANT_CODE = "YOUR_TENANT_CODE";
private readonly HttpClient _httpClient;
public EngagifiiApiClient()
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Add("tenant-code", TENANT_CODE);
_httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
}
public async Task<dynamic> GetAwardsListAsync()
{
try
{
var response = await _httpClient.GetAsync($"{BASE_URL}/api/v1/Awards/List");
response.EnsureSuccessStatusCode();
var jsonString = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject(jsonString);
Console.WriteLine($"Awards List: {jsonString}");
return data;
}
catch (HttpRequestException e)
{
Console.WriteLine($"Error fetching awards: {e.Message}");
return null;
}
}
}Expected Response
A successful response will return HTTP status 200 with JSON data:
json
[
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Professional Certification",
"description": "Advanced professional certification program",
"levelType": "Advanced",
"isActive": true,
"createdDate": "2024-01-15T10:30:00Z"
}
]Testing Guide
Using Postman
Import Collection
- Download the Postman Collection
- Open Postman and click "Import"
- Select the downloaded collection file
Configure Environment
- Create a new environment in Postman
- Add variable:
tenant_codewith your tenant code - Add variable:
base_urlwithhttps://engagifii-trainingandaccreditation.azurewebsites.net
Test Endpoints
- Select any request from the collection
- Ensure the environment is selected
- Click "Send" to execute the request
Using Swagger UI
- Navigate to Swagger UI
- Click on any endpoint to expand it
- Click "Try it out"
- Enter your tenant code in the header field
- Fill in any required parameters
- Click "Execute"
Automated Testing
javascript
// Example test suite using Jest
describe('Engagifii API Tests', () => {
const BASE_URL = 'https://engagifii-trainingandaccreditation.azurewebsites.net';
const TENANT_CODE = process.env.TENANT_CODE;
test('Should retrieve awards list', async () => {
const response = await fetch(`${BASE_URL}/api/v1/Awards/List`, {
headers: {
'tenant-code': TENANT_CODE,
'Content-Type': 'application/json'
}
});
expect(response.status).toBe(200);
const data = await response.json();
expect(Array.isArray(data)).toBe(true);
});
test('Should handle missing tenant code', async () => {
const response = await fetch(`${BASE_URL}/api/v1/Awards/List`, {
headers: {
'Content-Type': 'application/json'
}
});
expect(response.status).toBe(400);
});
});Common Integration Patterns
Pattern 1: Pagination
Handle large datasets with pagination:
javascript
async function getAllAwardsPaginated() {
const pageSize = 50;
let currentPage = 1;
let allAwards = [];
let hasMore = true;
while (hasMore) {
const response = await fetch(`${BASE_URL}/api/v1/Awards/AwardListPaging`, {
method: 'POST',
headers: {
'tenant-code': TENANT_CODE,
'Content-Type': 'application/json'
},
body: JSON.stringify({
page: currentPage,
pageSize: pageSize,
sortBy: 'createdDate',
sortDirection: 'desc'
})
});
const data = await response.json();
allAwards = [...allAwards, ...data.items];
hasMore = data.hasNextPage;
currentPage++;
}
return allAwards;
}Pattern 2: Error Handling
Implement comprehensive error handling:
javascript
class ApiError extends Error {
constructor(message, status, response) {
super(message);
this.status = status;
this.response = response;
}
}
async function apiCall(endpoint, options = {}) {
try {
const response = await fetch(`${BASE_URL}${endpoint}`, {
...options,
headers: {
'tenant-code': TENANT_CODE,
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const errorData = await response.json().catch(() => null);
throw new ApiError(
errorData?.message || `API Error: ${response.statusText}`,
response.status,
errorData
);
}
return await response.json();
} catch (error) {
if (error instanceof ApiError) {
throw error;
}
throw new Error(`Network error: ${error.message}`);
}
}Pattern 3: Retry Logic
Implement retry logic for transient failures:
javascript
async function apiCallWithRetry(endpoint, options = {}, maxRetries = 3) {
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await apiCall(endpoint, options);
} catch (error) {
lastError = error;
// Don't retry on client errors (4xx)
if (error.status >= 400 && error.status < 500) {
throw error;
}
// Exponential backoff
if (attempt < maxRetries) {
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw lastError;
}Pattern 4: Bulk Operations
Handle bulk operations efficiently:
javascript
async function bulkCreateRegistrations(registrations) {
const batchSize = 10;
const results = [];
for (let i = 0; i < registrations.length; i += batchSize) {
const batch = registrations.slice(i, i + batchSize);
const batchPromises = batch.map(registration =>
apiCall('/api/v1/registration/ClassRegistration', {
method: 'POST',
body: JSON.stringify(registration)
}).catch(error => ({
error: true,
message: error.message,
data: registration
}))
);
const batchResults = await Promise.all(batchPromises);
results.push(...batchResults);
}
return {
successful: results.filter(r => !r.error),
failed: results.filter(r => r.error)
};
}Troubleshooting
Common Issues and Solutions
1. Missing Tenant Code Error (400 Bad Request)
Error Message: "tenant-code header is required"
Solution:
javascript
// Ensure tenant-code is included in headers
headers: {
'tenant-code': 'YOUR_TENANT_CODE', // This is required
'Content-Type': 'application/json'
}2. Invalid Tenant Code (404 Not Found)
Error Message: "Tenant not found"
Solution:
- Verify the tenant code with your administrator
- Check for typos or extra spaces
- Ensure you're using the correct environment
3. Rate Limiting (429 Too Many Requests)
Error Message: "Rate limit exceeded"
Solution:
javascript
// Implement rate limiting
const rateLimiter = {
queue: [],
processing: false,
async add(fn) {
return new Promise((resolve, reject) => {
this.queue.push({ fn, resolve, reject });
this.process();
});
},
async process() {
if (this.processing || this.queue.length === 0) return;
this.processing = true;
const { fn, resolve, reject } = this.queue.shift();
try {
const result = await fn();
resolve(result);
} catch (error) {
reject(error);
}
// Wait 100ms between requests
setTimeout(() => {
this.processing = false;
this.process();
}, 100);
}
};4. JSON Parsing Errors
Error Message: "Unexpected token in JSON"
Solution:
javascript
// Always validate JSON before parsing
try {
const text = await response.text();
const data = text ? JSON.parse(text) : null;
} catch (error) {
console.error('Invalid JSON response:', text);
}5. CORS Issues (Browser Only)
Error Message: "Access to fetch at '...' from origin '...' has been blocked by CORS policy"
Solution:
- Use a server-side proxy for development
- Contact administrator for CORS configuration
- Use the API from server-side code
Debug Checklist
When encountering issues, check:
- [ ] Tenant code is correct and included in headers
- [ ] API endpoint URL is correct (including version)
- [ ] Request method matches API specification (GET, POST, etc.)
- [ ] Request body is valid JSON (for POST/PUT requests)
- [ ] Required fields are included in request
- [ ] Date formats are ISO 8601 compliant
- [ ] GUIDs are properly formatted
- [ ] Response status code and error messages
Getting Help
If you continue to experience issues:
- Check API Status: Verify the API is operational
- Review Logs: Include request/response details
- Contact Support: Provide:
- Exact error message
- Request details (endpoint, headers, body)
- Response status and body
- Timestamp of request
- Your tenant code (never share credentials)
Next Steps
Now that you've successfully made your first API calls:
- Explore Endpoints: Review the API Reference for all available endpoints
- Understand Authentication: Read the Authentication Guide for advanced security setup
- Learn Data Models: Study the Data Models documentation
- Handle Errors: Review the Error Handling Guide
- Build Integration: See code examples in the API Reference
Need help? Contact your system administrator or review the troubleshooting section.
