Access leave data, create requests, and sync your HR systems with the OrOut REST API.
Navigate to Settings → Integrations in your OrOut dashboard and generate an API key. Keep it secure!
Include your API key in the X-Api-Key header:
# List all users in your organization
curl -X GET "https://api.orout.co/public/v1/users" \
-H "X-Api-Key: orro_live_your_api_key_here"
Use our interactive API reference to explore endpoints, test requests, and generate code samples.
Open API ReferenceList and retrieve user profiles in your organization.
Retrieve available leave types configured for your organization.
Query user leave allowances and balances.
Full CRUD operations for managing leave requests.
Access documents attached to leave requests (read-only).
Full CRUD operations for overtime submissions and TOIL balance queries.
Check team coverage rules before submitting leave requests.
Submit worked hours from external rostering systems. Automatically accrues leave for shift workers.
Subscribe to real-time events for leave requests, allowance changes, and more.
const response = await fetch('https://api.orout.co/public/v1/leave-requests', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'orro_live_your_api_key_here'
},
body: JSON.stringify({
userId: '550e8400-e29b-41d4-a716-446655440000',
leaveTypeId: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
startDate: '2025-01-15',
endDate: '2025-01-17',
notes: 'Family holiday'
})
});
const leaveRequest = await response.json();
console.log(leaveRequest.id); // New leave request ID
const params = new URLSearchParams({
status: 'Approved',
startDateFrom: '2025-01-01',
startDateTo: '2025-12-31',
pageSize: '50'
});
const response = await fetch(
`https://api.orout.co/public/v1/leave-requests?${params}`,
{
headers: {
'X-Api-Key': 'orro_live_your_api_key_here'
}
}
);
const { items, totalCount, hasNextPage } = await response.json();
const response = await fetch('https://api.orout.co/public/v1/coverage/check', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'orro_live_your_api_key_here'
},
body: JSON.stringify({
userId: '550e8400-e29b-41d4-a716-446655440000',
startDate: '2026-02-10',
endDate: '2026-02-14',
includeDailyBreakdown: true
})
});
const result = await response.json();
if (result.hasViolation) {
console.warn(result.message); // "Team coverage would drop below 60%"
}
const response = await fetch('https://api.orout.co/public/v1/overtime', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'orro_live_your_api_key_here'
},
body: JSON.stringify({
userId: '550e8400-e29b-41d4-a716-446655440000',
date: '2026-01-18',
hoursWorked: 4.5,
description: 'Weekend deployment support'
})
});
const submission = await response.json();
console.log(submission.id); // New overtime submission ID
console.log(`TOIL accrued: ${submission.toilHoursAccrued} hours`);
const userId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(
`https://api.orout.co/public/v1/overtime/balance?userId=${userId}`,
{
headers: {
'X-Api-Key': 'orro_live_your_api_key_here'
}
}
);
const balance = await response.json();
console.log(`Available: ${balance.totalHoursAvailable} hours`);
console.log(`Expiring soon: ${balance.hoursExpiringSoon} hours`);
const leaveRequestId = 'f47ac10b-58cc-4372-a567-0e02b2c3d479';
// List documents
const response = await fetch(
`https://api.orout.co/public/v1/leave-requests/${leaveRequestId}/documents`,
{
headers: { 'X-Api-Key': 'orro_live_your_api_key_here' }
}
);
const documents = await response.json();
// Get download URL for a specific document
const docId = documents[0].id;
const urlResponse = await fetch(
`https://api.orout.co/public/v1/leave-requests/${leaveRequestId}/documents/${docId}/download-url`,
{
headers: { 'X-Api-Key': 'orro_live_your_api_key_here' }
}
);
const { url } = await urlResponse.json();
// Use url to download - valid for 15 minutes
// Single submission
const response = await fetch('https://api.orout.co/public/v1/hours-worked', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'orro_live_your_api_key_here'
},
body: JSON.stringify({
externalUserId: 'EMP-12345', // Your system's employee ID
date: '2026-01-15',
hoursWorked: 8.5,
leaveTypeId: 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
})
});
const result = await response.json();
console.log(`Accrued: ${result.hoursAccrued} hours`);
console.log(`New balance: ${result.newBalance} hours`);
const response = await fetch('https://api.orout.co/public/v1/hours-worked/bulk', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'orro_live_your_api_key_here'
},
body: JSON.stringify({
submissions: [
{ externalUserId: 'EMP-001', date: '2026-01-15', hoursWorked: 10 },
{ externalUserId: 'EMP-001', date: '2026-01-16', hoursWorked: 8 },
{ externalUserId: 'EMP-002', date: '2026-01-15', hoursWorked: 12 }
]
})
});
const result = await response.json();
console.log(`Processed: ${result.processedCount}/${result.totalCount}`);
const response = await fetch('https://api.orout.co/public/v1/webhooks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'orro_live_your_api_key_here'
},
body: JSON.stringify({
url: 'https://your-app.com/webhooks/orout',
eventTypes: [
'leave_request.approved',
'leave_request.rejected',
'leave_request.cancelled'
],
description: 'Sync leave to rostering system'
})
});
const webhook = await response.json();
console.log(`Webhook ID: ${webhook.id}`);
console.log(`Secret: ${webhook.signingSecret}`); // Store securely!
import crypto from 'crypto';
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// In your webhook handler:
app.post('/webhooks/orout', (req, res) => {
const signature = req.headers['x-orout-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, process.env.OROUT_WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook event
const { eventType, data } = req.body;
console.log(`Received: ${eventType}`, data);
res.status(200).send('OK');
});
API requests are limited to 1,000 requests per hour per organization.
Exceeding this limit will result in a 429 Too Many Requests response.
Each response includes headers to help you track your usage:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed per hour |
X-RateLimit-Remaining |
Requests remaining in current window |
Retry-After |
Seconds to wait before retrying (only on 429) |
API keys follow the format:
orro_live_xxxxxxxxxxxxxxxxxxxxxxxx