Overview
The Quarma360 API provides read-only access to your organization's performance assessment data, employee information, and bonus/malus calculations. This RESTful API uses JSON for all requests and responses.
Base URL: https://app.quarma360.com/api/v1
Current Version: v1
Protocol: HTTPS only
Authentication
All API requests require authentication using an API key.
API Key Format
API keys follow this format: qa360_live_XXXXXXXXXXXXXXXXXXXX
- Prefix:
qa360_live_ - Key: 32-character random string
How to Authenticate
Include your API key in the request header:
X-API-Key: qa360_live_****************************xxLF
Security Notes
- API keys are organization-specific and grant read-only access
- Keys are only shown once upon creation (only the last 8 characters are visible afterwards)
- Store your API key securely - treat it like a password
- Keys can be revoked at any time through the admin panel
- All requests are logged for security and monitoring
Error Response - Missing Key
{
"error": {
"code": "MISSING_API_KEY",
"message": "API key is required"
}
}
Error Response - Invalid Key
{
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid or expired API key"
}
}
Rate Limiting
API requests are rate-limited to prevent abuse and ensure fair usage.
Default Limit: 60 requests per minute per API key
Rate Limit Headers
Each response includes rate limit information:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1635724800
Rate Limit Exceeded Response
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please try again later.",
"retry_after": 60
}
}
Status Code: 429 Too Many Requests
Response Format
All successful responses follow this structure:
{
"success": true,
"message": "Optional message",
"data": { ... }
}
Paginated Responses
Endpoints that return lists include pagination metadata:
{
"success": true,
"data": [ ... ],
"pagination": {
"total": 150,
"per_page": 50,
"current_page": 1,
"last_page": 3
}
}
Note: The maximum value for per_page is 100. Values exceeding 100 will be automatically capped at 100.
Error Responses
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message"
}
}
API Endpoints
Health Check
GET /health
Check API health and availability.
Authentication: Required
Response:
{
"status": "healthy",
"timestamp": "2025-11-01T10:30:00Z",
"version": "v1"
}
Status (Public)
GET /status
Public endpoint to check API availability.
Authentication: Not required
Response:
{
"api": "Quarma360 API",
"version": "v1",
"status": "online",
"documentation": "https://your-domain.com/api/documentation"
}
Organization Endpoints
Get Organization Details
GET /organization
Retrieve your organization's basic information, statistics, and configuration.
Authentication: Required
Response:
{
"success": true,
"data": {
"organization": {
"id": 30,
"name": "Acme Corporation",
"slug": "acme-corp",
"created_at": "2024-01-15T10:00:00Z",
"tax_number": "12345678-1-23",
"eu_vat_number": "HU12345678",
"country_code": "HU",
"postal_code": "1011",
"region": "Budapest",
"city": "Budapest",
"street": "Main Street",
"house_number": "42",
"phone": "+36301234567",
"employee_limit": 100,
"subscription_type": "premium"
},
"statistics": {
"total_employees": 85,
"active_employees": 82,
"pending_assessments": 1,
"completed_assessments": 12,
"total_assessments": 13,
"active_competencies": 25,
"total_departments": 8,
"total_managers": 12
},
"configuration": {
"api_enabled": "1",
"api_rate_limit_per_minute": "60",
"assessment_frequency": "quarterly",
"bonus_malus_enabled": "1",
"ai_features_enabled": "1",
"trust_algorithm_enabled": "1",
"language": "hu",
"threshold_method": "hybrid"
}
}
}
Note: Sensitive data like org_snapshot or AI summaries are never exposed through the API.
Get Organization Statistics
GET /organization/statistics
Retrieve only the statistics portion of organization data.
Authentication: Required
Response:
{
"success": true,
"data": {
"total_employees": 85,
"active_employees": 82,
"pending_assessments": 1,
"completed_assessments": 12,
"total_assessments": 13,
"active_competencies": 25,
"total_departments": 8,
"total_managers": 12
}
}
Fields:
total_employees: All employees in the organization (including inactive)active_employees: Currently active employees onlypending_assessments: Open assessments not yet closedcompleted_assessments: Closed assessmentstotal_assessments: All assessments (open + closed)active_competencies: Active competencies (global + custom)total_departments: Number of departmentstotal_managers: Number of managers and CEOs
Get Organization Configuration
GET /organization/configuration
Retrieve organization configuration settings.
Authentication: Required
Response:
{
"success": true,
"data": {
"api_enabled": "1",
"api_rate_limit_per_minute": "60",
"assessment_frequency": "quarterly",
"bonus_malus_enabled": "1",
"ai_features_enabled": "1",
"trust_algorithm_enabled": "1",
"language": "hu",
"threshold_method": "hybrid"
}
}
Get Competencies
GET /competencies
List all active competencies for your organization.
Authentication: Required
Query Parameters:
type(optional): Filter by type -global,custom, orall(default:all)locale(optional): Language for competency names and descriptions -hu,en,de, etc. (default:hu)
Response:
{
"success": true,
"data": {
"organization_id": 30,
"competencies": [
{
"id": 1,
"name": "Leadership",
"description": "Ability to lead and inspire teams",
"organization_id": null,
"type": "global",
"questions_count": 5
},
{
"id": 45,
"name": "Technical Skills",
"description": "Domain-specific technical expertise",
"organization_id": 30,
"type": "custom",
"questions_count": 8
}
],
"statistics": {
"total": 25,
"global": 15,
"custom": 10
}
}
}
Notes:
- Competency names and descriptions are returned in the requested language (via
localeparameter) - If translation is not available for the requested language, falls back to Hungarian, then English
- Global competencies (
organization_id: null) are available to all organizations - Custom competencies belong to your specific organization
User Endpoints
List Users
GET /users
Get a paginated list of all users in your organization.
Authentication: Required
Query Parameters:
per_page(optional): Number of results per page (default: 50, max: 100)page(optional): Page number (default: 1)department_id(optional): Filter by departmentrole(optional): Filter by role -employee,manager,ceo,adminsearch(optional): Search by name or emailsort_by(optional):name,email,position(default:name)sort_order(optional):ascordesc(default:asc)
Example Request:
GET /api/v1/users?department_id=5&role=manager&per_page=20&page=1
Response:
{
"success": true,
"data": [
{
"id": 123,
"name": "John Doe",
"email": "[email protected]",
"position": "Senior Developer",
"department_id": 5,
"department_name": "Engineering",
"role": "manager"
}
],
"pagination": {
"total": 85,
"per_page": 20,
"current_page": 1,
"last_page": 5
}
}
Get User Details
GET /users/{id}
Get detailed information about a specific user.
Authentication: Required
Path Parameters:
id: User ID
Response:
{
"success": true,
"data": {
"user": {
"id": 123,
"name": "John Doe",
"email": "[email protected]",
"position": "Senior Developer",
"department_id": 5,
"department_name": "Engineering",
"role": "manager",
"created_at": "2024-01-15T10:00:00Z"
},
"recent_assessments": [
{
"assessment_id": 42,
"started_at": "2024-10-01T00:00:00Z",
"closed_at": "2024-10-15T23:59:59Z",
"overall_score": 4.2,
"bonus_malus_level": 8
}
]
}
}
Get User Competencies
GET /users/{id}/competencies
Get all competencies assigned to a specific user.
Authentication: Required
Path Parameters:
id: User ID
Query Parameters:
locale(optional): Language for competency names and descriptions -hu,en,de, etc. (default:hu)
Response:
{
"success": true,
"data": {
"user_id": 123,
"competencies": [
{
"id": 1,
"name": "Leadership",
"description": "Ability to lead and inspire teams",
"organization_id": null,
"type": "global"
},
{
"id": 45,
"name": "Technical Skills",
"description": "Domain-specific technical expertise",
"organization_id": 30,
"type": "custom"
}
]
}
}
Note: Competency names and descriptions are translated to the requested language when available.
Get User Hierarchy
GET /users/{id}/hierarchy
Get a user's organizational hierarchy (manager, colleagues, subordinates).
Authentication: Required
Path Parameters:
id: User ID
Response:
{
"success": true,
"data": {
"user_id": 123,
"manager": {
"id": 98,
"name": "Jane Smith",
"email": "[email protected]"
},
"colleagues": [
{
"id": 124,
"name": "Alice Johnson",
"email": "[email protected]"
}
],
"subordinates": [
{
"id": 150,
"name": "Bob Wilson",
"email": "[email protected]"
}
]
}
}
Assessment Endpoints
List Assessments
GET /assessments
Get a paginated list of all assessments.
Authentication: Required
Query Parameters:
per_page(optional): Number of results per page (default: 50, max: 100)page(optional): Page number (default: 1)status(optional): Filter by status -openorclosedyear(optional): Filter by year (e.g.,2024)from_date(optional): Filter assessments starting from date (ISO 8601:2024-01-01)to_date(optional): Filter assessments up to date (ISO 8601:2024-12-31)sort_by(optional):started_at,due_at,closed_at,id(default:started_at)sort_order(optional):ascordesc(default:desc)
Example Request:
GET /api/v1/assessments?status=closed&year=2024&per_page=10
Response:
{
"success": true,
"data": [
{
"id": 42,
"organization_id": 30,
"started_at": "2024-10-01T00:00:00Z",
"due_at": "2024-10-14T23:59:59Z",
"closed_at": "2024-10-15T10:30:00Z",
"threshold_method": "hybrid",
"normal_level_up": 4.0,
"normal_level_down": 3.0,
"monthly_level_down": 3.5
}
],
"pagination": {
"total": 12,
"per_page": 10,
"current_page": 1,
"last_page": 2
}
}
Note: Sensitive fields like org_snapshot and suggested_decision are never exposed.
Get Assessment Details
GET /assessments/{id}
Get detailed information about a specific assessment.
Authentication: Required
Path Parameters:
id: Assessment ID
Response:
{
"success": true,
"data": {
"assessment": {
"id": 42,
"organization_id": 30,
"started_at": "2024-10-01T00:00:00Z",
"due_at": "2024-10-14T23:59:59Z",
"closed_at": "2024-10-15T10:30:00Z",
"threshold_method": "hybrid",
"normal_level_up": 4.0,
"normal_level_down": 3.0,
"monthly_level_down": 3.5
},
"participants": 82,
"statistics": {
"total_submissions": 1640,
"completed_evaluations": 82,
"pending_evaluations": 0,
"self_evaluations": 82,
"colleague_evaluations": 750,
"manager_evaluations": 82,
"ceo_evaluations": 82,
"participation_rate": 100.0
}
}
}
Get Assessment Participants
GET /assessments/{id}/participants
Get list of all participants in a closed assessment.
Authentication: Required
Availability: Only for closed assessments
Path Parameters:
id: Assessment ID
Query Parameters:
per_page(optional): Number of results per page (default: 50, max: 100)page(optional): Page number (default: 1)department_id(optional): Filter by departmentrole(optional): Filter by role
Response:
{
"success": true,
"data": {
"assessment_id": 42,
"participants": [
{
"user_id": 123,
"name": "John Doe",
"email": "[email protected]",
"position": "Senior Developer",
"department_name": "Engineering",
"role": "manager",
"completed_self": true,
"completed_others": true,
"total_submissions": 20
}
],
"pagination": {
"total": 82,
"per_page": 50,
"current_page": 1,
"last_page": 2
}
}
}
Get Assessment Results
GET /assessments/{id}/results
Get complete results for a closed assessment with detailed scores and component breakdown.
Authentication: Required
Availability: Only for closed assessments
Path Parameters:
id: Assessment ID
Query Parameters:
per_page(optional): Number of results per page (default: 50, max: 100)page(optional): Page number (default: 1)department_id(optional): Filter by departmentmin_score(optional): Filter by minimum score (e.g.,3.5)
Response:
{
"success": true,
"data": {
"assessment_id": 42,
"results": [
{
"user_id": 123,
"name": "John Doe",
"email": "[email protected]",
"position": "Senior Developer",
"department_name": "Engineering",
"overall_score": 4.2,
"components": {
"self": 4.5,
"colleague": 4.1,
"direct_reports": 4.3,
"manager": 4.0,
"ceo": 4.2
},
"bonus_malus_level": 8,
"trend": 0.3
}
],
"pagination": {
"total": 82,
"per_page": 50,
"current_page": 1,
"last_page": 2
}
}
}
Score Components:
self: Self-evaluation scorecolleague: Average score from colleaguesdirect_reports: Average score from subordinates (if applicable)manager: Score from direct managerceo: Score from CEO
Trend: Change in overall score compared to previous assessment (+/- value)
Results Endpoints
Get User Results History
GET /results/user/{userId}
Get complete assessment history for a specific user across all closed assessments.
Authentication: Required
Path Parameters:
userId: User ID
Response:
{
"success": true,
"data": {
"user": {
"id": 123,
"name": "John Doe",
"email": "[email protected]",
"position": "Senior Developer"
},
"assessment_history": [
{
"assessment_id": 42,
"started_at": "2024-10-01T00:00:00Z",
"closed_at": "2024-10-15T10:30:00Z",
"overall_score": 4.2,
"components": {
"self": 4.5,
"colleague": 4.1,
"direct_reports": 4.3,
"manager": 4.0,
"ceo": 4.2
},
"bonus_malus_level": 8,
"trend": 0.3
},
{
"assessment_id": 38,
"started_at": "2024-07-01T00:00:00Z",
"closed_at": "2024-07-15T10:30:00Z",
"overall_score": 3.9,
"components": {
"self": 4.2,
"colleague": 3.8,
"direct_reports": 4.0,
"manager": 3.7,
"ceo": 3.9
},
"bonus_malus_level": 7,
"trend": -0.2
}
],
"statistics": {
"total_assessments": 12,
"average_score": 4.1,
"highest_score": 4.5,
"lowest_score": 3.5,
"current_level": 8,
"current_trend": "improving"
}
}
}
Bonus/Malus Endpoints
List Current Bonus/Malus Status
GET /bonus-malus
Get current bonus/malus status for all employees.
Authentication: Required
Query Parameters:
per_page(optional): Number of results per page (default: 50, max: 100)page(optional): Page number (default: 1)department_id(optional): Filter by departmentmonth(optional): Filter by month (format:YYYY-MM, default: current month)level(optional): Filter by specific level (1-15)search(optional): Search by name or emailsort_by(optional):user.name,user.email,user_bonus_malus.level,user_bonus_malus.monthsort_order(optional):ascordesc(default:asc)
Example Request:
GET /api/v1/bonus-malus?month=2024-10&level=8&department_id=5
Response:
{
"success": true,
"data": [
{
"user_id": 123,
"name": "John Doe",
"email": "[email protected]",
"position": "Senior Developer",
"department_name": "Engineering",
"level": 8,
"month": "2024-10",
"created_at": "2024-10-15T10:30:00Z"
}
],
"pagination": {
"total": 82,
"per_page": 50,
"current_page": 1,
"last_page": 2
}
}
Get Bonus/Malus Configuration
GET /bonus-malus/configuration
Get the organization's bonus/malus multiplier configuration.
Authentication: Required
Response:
{
"success": true,
"data": {
"organization_id": 30,
"levels": [
{
"level": 1,
"multiplier": 0.5
},
{
"level": 2,
"multiplier": 0.6
},
{
"level": 8,
"multiplier": 1.0
},
{
"level": 15,
"multiplier": 2.0
}
]
}
}
Get Bonus/Malus Categories
GET /bonus-malus/categories
Get all possible bonus/malus categories (levels 1-15) with their codes and multipliers.
Authentication: Required
Response:
{
"success": true,
"data": {
"organization_id": 30,
"categories": [
{
"level": 1,
"code": "B01",
"multiplier": 0.5,
"configured": true
},
{
"level": 2,
"code": "B02",
"multiplier": 0.6,
"configured": true
},
{
"level": 8,
"code": "B08",
"multiplier": 1.0,
"configured": true
},
{
"level": 9,
"code": "B09",
"multiplier": 0.0,
"configured": false
},
{
"level": 15,
"code": "B15",
"multiplier": 2.0,
"configured": true
}
],
"total_levels": 15
}
}
Notes:
configured: Indicates if a multiplier has been set for this level- Unconfigured levels return
multiplier: 0.0 - Levels are standardized from 1-15
Get Assessment Bonuses
GET /bonus-malus/{id}
Get bonus payment details for a specific assessment.
Authentication: Required
Availability: Only for closed assessments
Path Parameters:
id: Assessment ID
Response:
{
"success": true,
"data": {
"assessment_id": 42,
"statistics": {
"total_employees": 82,
"total_bonus_amount": 2850000.00,
"average_bonus": 34756.10,
"paid_count": 82,
"paid_amount": 2850000.00
},
"distribution": [
{
"bonus_malus_level": 5,
"employee_count": 8,
"total_amount": 180000.00,
"average_amount": 22500.00
},
{
"bonus_malus_level": 8,
"employee_count": 45,
"total_amount": 1575000.00,
"average_amount": 35000.00
},
{
"bonus_malus_level": 12,
"employee_count": 15,
"total_amount": 675000.00,
"average_amount": 45000.00
}
]
}
}
Get Assessment Bonus Results
GET /bonus-malus/{id}/results
Get detailed bonus payment information for each employee in an assessment.
Authentication: Required
Availability: Only for closed assessments
Path Parameters:
id: Assessment ID
Query Parameters:
per_page(optional): Number of results per page (default: 50, max: 100)department_id(optional): Filter by departmentis_paid(optional): Filter by payment status (0or1)level(optional): Filter by bonus/malus levelsort_by(optional):user.name,assessment_bonuses.bonus_amount,assessment_bonuses.bonus_malus_levelsort_order(optional):ascordesc
Response:
{
"success": true,
"data": [
{
"user_id": 123,
"name": "John Doe",
"email": "[email protected]",
"position": "Senior Developer",
"department_name": "Engineering",
"bonus_malus_level": 8,
"net_wage": 500000.00,
"currency": "HUF",
"multiplier": 1.0,
"bonus_amount": 35000.00,
"is_paid": true,
"paid_at": "2024-10-20T14:30:00Z"
}
],
"pagination": {
"total": 82,
"per_page": 50,
"current_page": 1,
"last_page": 2
}
}
Get User Bonus/Malus History
GET /bonus-malus/user/{userId}
Get complete bonus/malus history for a specific user.
Authentication: Required
Path Parameters:
userId: User ID
Query Parameters:
from_date(optional): Start date (format:YYYY-MM-DD)to_date(optional): End date (format:YYYY-MM-DD)per_page(optional): Number of results per page (default: 50, max: 100)
Response:
{
"success": true,
"data": {
"user": {
"id": 123,
"name": "John Doe",
"email": "[email protected]",
"position": "Senior Developer"
},
"history": [
{
"month": "2024-10",
"level": 8,
"created_at": "2024-10-15T10:30:00Z"
},
{
"month": "2024-07",
"level": 7,
"created_at": "2024-07-15T10:30:00Z"
},
{
"month": "2024-04",
"level": 7,
"created_at": "2024-04-15T10:30:00Z"
}
],
"statistics": {
"current_level": 8,
"average_level": 7.5,
"highest_level": 9,
"lowest_level": 6,
"total_months": 12
}
},
"pagination": {
"total": 12,
"per_page": 50,
"current_page": 1,
"last_page": 1
}
}
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
MISSING_API_KEY | 401 | API key not provided in request header |
INVALID_API_KEY_FORMAT | 401 | API key doesn't match expected format |
INVALID_API_KEY | 401 | API key is invalid, revoked, or expired |
API_DISABLED | 403 | API access is disabled for the organization |
RATE_LIMIT_EXCEEDED | 429 | Too many requests, rate limit exceeded |
NOT_FOUND | 404 | Requested resource not found |
INVALID_PARAMETERS | 400 | Invalid query parameters or request data |
ASSESSMENT_NOT_CLOSED | 400 | Attempted to access results of an open assessment |
USER_NOT_IN_ORGANIZATION | 404 | User ID doesn't belong to your organization |
Best Practices
1. API Key Management
- Store securely: Never commit API keys to version control
- Use environment variables: Store keys in
.envfiles or secure key management systems - Rotate regularly: Generate new keys periodically and revoke old ones
- Monitor usage: Check API logs regularly for unusual activity
2. Rate Limiting
- Implement backoff: Use exponential backoff when receiving 429 responses
- Cache responses: Store frequently accessed data locally
- Batch requests: Group multiple queries when possible
- Monitor limits: Track your remaining rate limit quota
3. Error Handling
async function makeApiRequest(endpoint) {
try {
const response = await fetch(`https://api.example.com/v1${endpoint}`, {
headers: {
'X-API-Key': process.env.QUARMA360_API_KEY
}
});
// Check rate limits
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limited. Retry after ${retryAfter} seconds`);
// Implement exponential backoff here
return;
}
// Check authentication
if (response.status === 401) {
console.error('Authentication failed. Check your API key.');
return;
}
// Parse response
const data = await response.json();
if (!data.success) {
console.error('API Error:', data.error);
return;
}
return data.data;
} catch (error) {
console.error('Request failed:', error);
}
}
4. Pagination
Always handle pagination for list endpoints:
async function getAllUsers() {
let allUsers = [];
let currentPage = 1;
let lastPage = 1;
do {
const response = await makeApiRequest(`/users?page=${currentPage}&per_page=100`);
allUsers = allUsers.concat(response.data);
lastPage = response.pagination.last_page;
currentPage++;
} while (currentPage <= lastPage);
return allUsers;
}
Note: Maximum per_page is 100. Values exceeding this will be automatically capped.
5. Data Freshness
- Assessment results are only available after assessments are closed
- Real-time data access is not available during ongoing assessments
- Bonus/malus data is updated monthly after assessment closures
- Cache data appropriately based on your use case
Code Examples
cURL
# Get organization details
curl -X GET "https://your-domain.com/api/v1/organization" \
-H "X-API-Key: qa360_live_YOUR_API_KEY_HERE"
# Get users with filters
curl -X GET "https://your-domain.com/api/v1/users?department_id=5&role=manager&per_page=20" \
-H "X-API-Key: qa360_live_YOUR_API_KEY_HERE"
# Get assessment results
curl -X GET "https://your-domain.com/api/v1/assessments/42/results" \
-H "X-API-Key: qa360_live_YOUR_API_KEY_HERE"
# Get competencies in English
curl -X GET "https://your-domain.com/api/v1/competencies?locale=en" \
-H "X-API-Key: qa360_live_YOUR_API_KEY_HERE"
JavaScript (Node.js)
const axios = require('axios');
const api = axios.create({
baseURL: 'https://your-domain.com/api/v1',
headers: {
'X-API-Key': process.env.QUARMA360_API_KEY
}
});
// Get organization details
async function getOrganization() {
try {
const response = await api.get('/organization');
return response.data.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
// Get assessment results
async function getAssessmentResults(assessmentId) {
try {
const response = await api.get(`/assessments/${assessmentId}/results`);
return response.data.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
// Get user history
async function getUserResults(userId) {
try {
const response = await api.get(`/results/user/${userId}`);
return response.data.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
// Get competencies in specific language
async function getCompetencies(locale = 'hu') {
try {
const response = await api.get(`/competencies?locale=${locale}`);
return response.data.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
Python
import requests
import os
class Quarma360API:
def __init__(self, api_key):
self.base_url = "https://your-domain.com/api/v1"
self.headers = {
"X-API-Key": api_key
}
def get_organization(self):
response = requests.get(
f"{self.base_url}/organization",
headers=self.headers
)
response.raise_for_status()
return response.json()['data']
def get_users(self, department_id=None, role=None, page=1, per_page=50):
params = {
'page': page,
'per_page': min(per_page, 100) # Cap at 100
}
if department_id:
params['department_id'] = department_id
if role:
params['role'] = role
response = requests.get(
f"{self.base_url}/users",
headers=self.headers,
params=params
)
response.raise_for_status()
return response.json()
def get_assessment_results(self, assessment_id):
response = requests.get(
f"{self.base_url}/assessments/{assessment_id}/results",
headers=self.headers
)
response.raise_for_status()
return response.json()['data']
def get_competencies(self, locale='hu', type='all'):
params = {
'locale': locale,
'type': type
}
response = requests.get(
f"{self.base_url}/competencies",
headers=self.headers,
params=params
)
response.raise_for_status()
return response.json()['data']
# Usage
api = Quarma360API(os.getenv('QUARMA360_API_KEY'))
# Get organization
org = api.get_organization()
print(f"Organization: {org['organization']['name']}")
# Get users
users = api.get_users(role='manager')
print(f"Total managers: {users['pagination']['total']}")
# Get competencies in Hungarian
competencies = api.get_competencies(locale='hu')
print(f"Total competencies: {competencies['statistics']['total']}")
PHP
<?php
class Quarma360API {
private $baseUrl;
private $apiKey;
public function __construct($apiKey) {
$this->baseUrl = 'https://your-domain.com/api/v1';
$this->apiKey = $apiKey;
}
private function request($endpoint, $params = []) {
$url = $this->baseUrl . $endpoint;
if (!empty($params)) {
// Cap per_page at 100
if (isset($params['per_page'])) {
$params['per_page'] = min($params['per_page'], 100);
}
$url .= '?' . http_build_query($params);
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . $this->apiKey
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API request failed with status $httpCode");
}
return json_decode($response, true);
}
public function getOrganization() {
return $this->request('/organization')['data'];
}
public function getUsers($departmentId = null, $role = null) {
$params = [];
if ($departmentId) $params['department_id'] = $departmentId;
if ($role) $params['role'] = $role;
return $this->request('/users', $params);
}
public function getAssessmentResults($assessmentId) {
return $this->request("/assessments/$assessmentId/results")['data'];
}
public function getCompetencies($locale = 'hu', $type = 'all') {
return $this->request('/competencies', [
'locale' => $locale,
'type' => $type
])['data'];
}
}
// Usage
$api = new Quarma360API(getenv('QUARMA360_API_KEY'));
// Get organization
$org = $api->getOrganization();
echo "Organization: " . $org['organization']['name'] . "\n";
// Get users
$users = $api->getUsers(null, 'manager');
echo "Total managers: " . $users['pagination']['total'] . "\n";
// Get competencies in Hungarian
$competencies = $api->getCompetencies('hu');
echo "Total competencies: " . $competencies['statistics']['total'] . "\n";
Support
API Management
Manage your API keys through the admin panel:
- Location: Admin → Settings → API Connection
- Actions: Generate new keys, revoke existing keys, view usage statistics
Rate Limit Adjustments
If you need higher rate limits for your use case:
- Contact your account manager
- Provide details about your integration requirements
- Rate limits can be adjusted on a per-organization basis
Technical Support
For technical support or questions:
- Documentation: Check this document first
- Help Center: Available in the application
- Support Tickets: Submit through the platform
Change Log
v1.0.0
- Initial API release
- Read-only access to organization, user, assessment, and bonus/malus data
- API key authentication
- Rate limiting (60 req/min)
- Comprehensive error handling
- Multi-language support for competencies
- Response time tracking
Security Considerations
- HTTPS Only: All API requests must use HTTPS
- API Key Security: Keys are hashed and only the last 8 characters are stored
- Read-Only Access: API provides read-only access to prevent data modification
- IP Logging: All requests are logged with IP addresses for security monitoring
- Rate Limiting: Prevents abuse and ensures fair usage
- Data Filtering: Sensitive data (org_snapshot, AI summaries) is never exposed
- Organization Scoping: Users can only access data from their own organization
- Response Tracking: All requests logged with response time and status code
Frequently Asked Questions
Can I modify data through the API?
No, the API is currently read-only. All data modifications must be done through the web interface.
How often is the data updated?
- User data: Real-time
- Assessment data: Real-time during assessments, finalized after closure
- Bonus/malus data: Updated monthly after assessment closures
- Statistics: Recalculated on-demand when requested
Can I have multiple API keys?
Currently, each organization can have one active API key at a time. You must revoke the existing key before generating a new one.
What happens if my assessment is still open?
Assessment results and bonus/malus calculations are only available after the assessment is closed. Attempting to access them will return a 404 error.
How do I increase my rate limit?
Contact your account manager to discuss higher rate limits based on your integration needs.
Is there a sandbox environment?
Please contact support to inquire about sandbox/testing environments for development purposes.
What does per_page=100 maximum mean?
To prevent server overload, pagination is capped at 100 items per page. If you request per_page=500, the API will automatically limit it to 100 items.
How do I get competencies in different languages?
Use the locale parameter: /competencies?locale=en for English, locale=hu for Hungarian, etc. If a translation is not available, the API falls back to Hungarian, then English.
What's the difference between total_employees and active_employees?
total_employees: All employees in the organization (including inactive ones)active_employees: Only currently active employees
Document Version: 1.0.1
Last Updated: January 25, 2026
API Version: v1