API Reference
Build integrations with the PraxisMS REST API.
API key generation requires Billing Administrator access.
Introduction
The PraxisMS API allows you to access your company's time tracking data programmatically. Use it to:
- Build integrations with your existing tools (payroll, accounting, project management)
- Generate custom reports beyond what's available in the web interface
- Automate workflows like exporting timesheets to other systems
Base URL
https://praxisms.ca/api/v1/
Quick Facts
| Protocol | HTTPS only (HTTP requests will be rejected) |
| Method | All endpoints use POST requests |
| Format | Responses are JSON |
| Authentication | API key required (see below) |
Quick Start
- Go to Company Admin > Billing & API
- Scroll to API Access
- Choose a scope (Read Only or Read & Write)
- Click Generate API Key
- Copy and securely store your key
Your API key is only shown once when generated. Copy it immediately and store it securely. If you lose it, you'll need to generate a new one (which invalidates the old key).
Authentication
Every API request must include your API key. Keys start with the prx_ prefix.
Recommended: Authorization Header
Include your key in the Authorization header using the Bearer scheme:
Authorization: Bearer prx_your_api_key_here
Alternative: POST Parameter
For backwards compatibility, you can also send the key as a POST parameter:
key=prx_your_api_key_here
The Authorization header is preferred because it keeps your key out of server access logs.
API Key Scopes
| Scope | Description |
|---|---|
| Read Only | Can access all GET endpoints to fetch data. Cannot modify anything. |
| Read & Write | Can access all endpoints, including future write operations. |
Security Best Practices
- Never commit your API key to version control (use environment variables)
- Use Read Only scope unless you specifically need write access
- Regenerate your key immediately if you suspect it's been compromised
- Don't share keys between applications; generate a new key for each integration
Response Format
All API responses are JSON objects containing a status field.
Successful Response
{
"status": "success",
"employees": { ... }
}
Error Response
{
"status": "API Key Not Valid"
}
Common Error Messages
| Status | Meaning |
|---|---|
API Key Not Valid |
The key is missing, malformed, or doesn't exist |
API Key does not have write access |
You're using a Read Only key on a write endpoint |
Start and End Dates are Required |
The jobtimers endpoint requires date range parameters |
Start and End Dates must be in format YYYY-MM-DD |
Date parameters must use ISO format (e.g., 2024-01-15) |
Endpoints
The following endpoints are available for retrieving your company's data.
Employees
Retrieve a list of employees in your company.
Parameters
| Parameter | Type | Description |
|---|---|---|
employeeid (optional) |
integer | Filter to a specific employee by their ID |
Response Fields
| Field | Type | Description |
|---|---|---|
id |
integer | Unique employee ID |
name |
string | Full name |
email |
string | Email address |
permission |
string | Permission level: Employee, Supervisor, Administrator, Billing Administrator, Report Only, or Disabled |
hrStatus |
string|null | HR status: Employed, On Leave, Laid Off, Former, or null |
hasAccess |
boolean | Whether the employee can currently log in |
Example Request
curl -X POST https://praxisms.ca/api/v1/get/employees.php \
-H "Authorization: Bearer prx_YOUR_API_KEY"
Example Response
{
"status": "success",
"employees": {
"Jane Smith": {
"id": 1,
"name": "Jane Smith",
"email": "jane@example.com",
"permission": "Administrator",
"hrStatus": "Employed",
"hasAccess": true
},
"Bob Johnson": {
"id": 2,
"name": "Bob Johnson",
"email": "bob@example.com",
"permission": "Employee",
"hrStatus": null,
"hasAccess": true
}
}
}
Jobs
Retrieve jobs (projects) for your company. Requires the Job Costing module.
Parameters
| Parameter | Type | Description |
|---|---|---|
jobid (optional) |
integer | Filter to a specific job by ID |
Response Fields
| Field | Type | Description |
|---|---|---|
id |
integer | Unique job ID |
name |
string | Job name |
archived |
integer | 0 = active, 1 = archived |
Example Request
curl -X POST https://praxisms.ca/api/v1/get/jobs.php \
-H "Authorization: Bearer prx_YOUR_API_KEY"
Example Response
{
"status": "success",
"jobs": {
"Website Redesign": {
"id": 101,
"name": "Website Redesign",
"archived": 0
},
"Q4 Marketing Campaign": {
"id": 102,
"name": "Q4 Marketing Campaign",
"archived": 1
}
}
}
Quick Tasks
Retrieve quick task categories (e.g., "Meeting", "Development", "Administrative").
Parameters
| Parameter | Type | Description |
|---|---|---|
quicktaskid (optional) |
integer | Filter to a specific quick task by ID |
Response Fields
| Field | Type | Description |
|---|---|---|
id |
integer | Unique quick task ID |
description |
string | Task description/name |
active |
integer | 1 = active, 0 = inactive |
Example Request
curl -X POST https://praxisms.ca/api/v1/get/quicktasks.php \
-H "Authorization: Bearer prx_YOUR_API_KEY"
Example Response
{
"status": "success",
"quicktasks": {
"Administrative": {
"id": 1,
"description": "Administrative",
"active": 1
},
"Development": {
"id": 2,
"description": "Development",
"active": 1
}
}
}
Job Timers (Time Entries)
Retrieve time entries within a date range. This is the main endpoint for payroll exports and time reports.
Parameters
| Parameter | Type | Description |
|---|---|---|
startdate (required) |
string | Start date in YYYY-MM-DD format |
enddate (required) |
string | End date in YYYY-MM-DD format |
employeeid (optional) |
integer | Filter to a specific employee |
jobid (optional) |
integer | Filter to a specific job |
quicktaskid (optional) |
integer | Filter to a specific quick task |
Response Fields
| Field | Type | Description |
|---|---|---|
id |
integer | Unique timer ID |
employeeid |
integer | Employee ID |
employeename |
string | Employee's full name |
in |
string | Clock-in time (YYYY-MM-DD HH:MM:SS) |
out |
string | Clock-out time (YYYY-MM-DD HH:MM:SS) |
elapsed |
integer | Duration in seconds. Divide by 3600 for hours. |
note |
string|null | Optional note attached to this entry |
billable |
integer | 1 = billable, 0 = non-billable |
jobid |
integer|null | Associated job ID (if any) |
quicktaskid |
integer|null | Associated quick task ID (if any) |
The elapsed field is in seconds. To get hours: hours = elapsed / 3600. For example, 7200 seconds = 2 hours.
Example Request
curl -X POST https://praxisms.ca/api/v1/get/jobtimers.php \
-H "Authorization: Bearer prx_YOUR_API_KEY" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "startdate=2024-01-01&enddate=2024-01-31"
Example Response
{
"status": "success",
"startdate": "2024-01-01",
"enddate": "2024-01-31",
"jobtimers": [
{
"id": 5001,
"employeeid": 1,
"employeename": "Jane Smith",
"in": "2024-01-15 09:00:00",
"out": "2024-01-15 12:30:00",
"elapsed": 12600,
"note": "Client meeting and follow-up",
"billable": 1,
"jobid": 101,
"quicktaskid": null
}
]
}
PHP Example
<?php
$apiKey = "prx_YOUR_API_KEY";
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://praxisms.ca/api/v1/get/jobtimers.php",
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $apiKey",
"Content-Type: application/x-www-form-urlencoded"
],
CURLOPT_POSTFIELDS => http_build_query([
'startdate' => '2024-01-01',
'enddate' => '2024-01-31'
])
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
// Calculate total hours
$totalHours = 0;
foreach ($data['jobtimers'] as $timer) {
$totalHours += $timer['elapsed'] / 3600;
}
echo "Total hours: " . round($totalHours, 2);
JavaScript Example
const apiKey = "prx_YOUR_API_KEY";
const params = new URLSearchParams({
startdate: "2024-01-01",
enddate: "2024-01-31"
});
fetch("https://praxisms.ca/api/v1/get/jobtimers.php", {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/x-www-form-urlencoded"
},
body: params
})
.then(res => res.json())
.then(data => {
// Calculate total hours
const totalHours = data.jobtimers.reduce((sum, t) => {
return sum + (t.elapsed / 3600);
}, 0);
console.log(`Total hours: ${totalHours.toFixed(2)}`);
});
Task Lists
Retrieve shared task lists and their incomplete items. Requires the Task Manager module.
Only shared task lists are accessible via the API. Private lists are not returned.
Parameters
| Parameter | Type | Description |
|---|---|---|
id (optional) |
integer | Filter to a specific task list by ID |
Response Fields
| Field | Type | Description |
|---|---|---|
id |
integer | Unique task list ID |
name |
string | Task list name |
items |
array | Array of incomplete task descriptions |
Example Request
curl -X POST https://praxisms.ca/api/v1/get/tasklists.php \
-H "Authorization: Bearer prx_YOUR_API_KEY"
Example Response
{
"status": "success",
"tasklists": [
{
"id": 1,
"name": "Daily Standup",
"items": [
"Review overnight tickets",
"Check deployment status",
"Update project board"
]
},
{
"id": 2,
"name": "Sprint Goals",
"items": [
"Complete API documentation",
"Fix login timeout bug"
]
}
]
}