Quota & Limits API Reference
The Quota & Limits API provides endpoints for monitoring resource usage and quota limits across your organization. Use these endpoints to track consumption, display usage dashboards, and implement proactive upgrade flows.
Overview
The quota system tracks usage across multiple resource types:
- Boards - Total active boards in organization
- Participants - Maximum participants per board
- Storage - Organization, board, and component storage
- API Calls - Daily API request limits
- Webhooks - Daily webhook delivery limits
- AI Requests - Monthly AI generation requests
- File Uploads - Daily file upload limits
- Exports - Monthly export operations
Each quota has configurable limits based on your pricing tier, with soft limit warnings at 80% usage and hard limits at 100%.
Authentication
All Quota API endpoints support both authentication methods:
JWT Token (User Authentication):
curl -H "Authorization: Bearer your-jwt-token" \
https://api.boardapi.io/api/v1/quotaAPI Key:
curl -H "X-API-Key: your-api-key" \
https://api.boardapi.io/api/v1/quotaGet your API key from the Developer Dashboard.
Base URL
https://api.boardapi.io/api/v1For development:
http://localhost:4000/api/v1Endpoints Overview
| Method | Endpoint | Description |
|---|---|---|
GET | /quota | Get comprehensive usage report for all quotas |
GET | /quota/:type | Get usage for a specific quota type |
Get Usage Report
Returns a comprehensive usage report for all quota types in your organization, including current usage, limits, remaining capacity, and upgrade recommendations.
Request
GET /quota
Authorization: Bearer your-jwt-tokenResponse
Status Code: 200 OK
{
"plan": "professional",
"quotas": [
{
"type": "boards",
"current": 45,
"limit": 100,
"remaining": 55,
"percent": 45,
"isUnlimited": false
},
{
"type": "participants",
"current": 75,
"limit": 100,
"remaining": 25,
"percent": 75,
"isUnlimited": false
},
{
"type": "storage_org",
"current": 8589934592,
"limit": 10737418240,
"remaining": 2147483648,
"percent": 80,
"isUnlimited": false,
"warning": "82% used"
},
{
"type": "api_calls_daily",
"current": 2450,
"limit": 10000,
"remaining": 7550,
"percent": 24.5,
"isUnlimited": false,
"resetAt": "2025-11-27T00:00:00Z"
},
{
"type": "webhooks_daily",
"current": 125,
"limit": 1000,
"remaining": 875,
"percent": 12.5,
"isUnlimited": false,
"resetAt": "2025-11-27T00:00:00Z"
},
{
"type": "ai_requests_monthly",
"current": 28,
"limit": 50,
"remaining": 22,
"percent": 56,
"isUnlimited": false,
"resetAt": "2025-12-01T00:00:00Z"
}
],
"overallUsagePercent": 52.3,
"recommendation": "ok"
}Response Fields
| Field | Type | Description |
|---|---|---|
plan | string | Current plan: starter, professional, business, enterprise |
quotas | array | Array of quota usage details for each resource type |
quotas[].type | string | Quota type (see Quota Types) |
quotas[].current | number | Current usage value |
quotas[].limit | number | Maximum allowed value (-1 = unlimited) |
quotas[].remaining | number | Remaining capacity |
quotas[].percent | number | Usage percentage (0-100) |
quotas[].isUnlimited | boolean | Whether this quota is unlimited |
quotas[].resetAt | string | ISO 8601 timestamp when quota resets (periodic quotas only) |
quotas[].warning | string | Warning message if approaching limit (80%+) |
overallUsagePercent | number | Average usage across all limited quotas |
recommendation | string | Recommended action: ok, monitor, upgrade |
Recommendations
| Value | Usage | Meaning |
|---|---|---|
ok | < 70% | Usage is healthy |
monitor | 70-90% | Monitor usage, plan for upgrade |
upgrade | 90%+ | Upgrade recommended to avoid limits |
Example Requests
JavaScript/TypeScript:
const response = await fetch('https://api.boardapi.io/api/v1/quota', {
headers: {
'Authorization': 'Bearer your-jwt-token'
}
});
const report = await response.json();
console.log(`Plan: ${report.plan}`);
console.log(`Overall usage: ${report.overallUsagePercent.toFixed(1)}%`);
// Display quota details
report.quotas.forEach(quota => {
if (quota.warning) {
console.warn(`⚠️ ${quota.type}: ${quota.warning}`);
}
console.log(`${quota.type}: ${quota.current}/${quota.limit} (${quota.percent}%)`);
});
// Show upgrade prompt
if (report.recommendation === 'upgrade') {
showUpgradePrompt();
}cURL:
curl -H "Authorization: Bearer your-jwt-token" \
'https://api.boardapi.io/api/v1/quota'PHP:
<?php
$headers = ['Authorization: Bearer your-jwt-token'];
$report = json_decode(
file_get_contents(
'https://api.boardapi.io/api/v1/quota',
false,
stream_context_create(['http' => ['header' => implode("\r\n", $headers)]])
),
true
);
echo "Plan: {$report['plan']}\n";
echo "Overall usage: {$report['overallUsagePercent']}%\n";
foreach ($report['quotas'] as $quota) {
if (isset($quota['warning'])) {
echo "⚠️ {$quota['type']}: {$quota['warning']}\n";
}
}Use Cases
- Display usage dashboard in your application
- Show progress bars for each quota type
- Implement proactive upgrade prompts
- Monitor resource consumption
- Trigger alerts when limits are approaching
Possible Errors
| Status Code | Error | Description |
|---|---|---|
401 | Unauthorized | Invalid or missing authentication token |
Get Specific Quota Usage
Returns usage information for a single quota type. Useful for checking before performing an operation or displaying specific resource usage.
Request
GET /quota/:type
Authorization: Bearer your-jwt-tokenURL Parameters
| Parameter | Type | Description |
|---|---|---|
type | string | Quota type to check (see Quota Types) |
Response
Status Code: 200 OK
{
"allowed": true,
"current": 45,
"limit": 100,
"remaining": 55,
"warning": null
}When approaching limit (80%+):
{
"allowed": true,
"current": 82,
"limit": 100,
"remaining": 18,
"warning": "Warning: You've used 82% of your boards quota"
}When limit exceeded:
{
"allowed": false,
"current": 100,
"limit": 100,
"remaining": 0,
"warning": "Board limit reached. Upgrade to Business plan for 500 boards."
}Response Fields
| Field | Type | Description |
|---|---|---|
allowed | boolean | Whether operation is allowed |
current | number | Current usage value |
limit | number | Maximum allowed value (-1 = unlimited) |
remaining | number | Remaining capacity |
warning | string | Warning or error message (if applicable) |
Example Requests
JavaScript/TypeScript:
// Check boards quota before creating a board
const checkQuota = async () => {
const response = await fetch('https://api.boardapi.io/api/v1/quota/boards', {
headers: {
'Authorization': 'Bearer your-jwt-token'
}
});
const quota = await response.json();
if (!quota.allowed) {
alert(`Cannot create board: ${quota.warning}`);
showUpgradeModal();
return false;
}
if (quota.warning) {
console.warn(quota.warning);
}
return true;
};
// Use before creating board
if (await checkQuota()) {
await createBoard({ title: 'New Board' });
}cURL:
# Check boards quota
curl -H "Authorization: Bearer your-jwt-token" \
'https://api.boardapi.io/api/v1/quota/boards'
# Check storage quota
curl -H "Authorization: Bearer your-jwt-token" \
'https://api.boardapi.io/api/v1/quota/storage_org'
# Check API calls quota
curl -H "Authorization: Bearer your-jwt-token" \
'https://api.boardapi.io/api/v1/quota/api_calls_daily'PHP:
<?php
function checkQuota($type, $token) {
$url = "https://api.boardapi.io/api/v1/quota/{$type}";
$quota = json_decode(
file_get_contents($url, false, stream_context_create([
'http' => ['header' => "Authorization: Bearer {$token}"]
])),
true
);
if (!$quota['allowed']) {
echo "Operation blocked: {$quota['warning']}\n";
return false;
}
if (isset($quota['warning'])) {
echo "Warning: {$quota['warning']}\n";
}
return true;
}
// Check before creating board
if (checkQuota('boards', $jwt_token)) {
createBoard($data);
}Use Cases
- Pre-operation quota checks in your application
- Display specific resource usage (e.g., "45/100 boards used")
- Show quota warnings before user actions
- Implement "pay-as-you-go" upgrade flows
- Validate operations in API middleware
Possible Errors
| Status Code | Error | Description |
|---|---|---|
400 | Bad Request | Invalid quota type |
401 | Unauthorized | Invalid or missing authentication token |
Error Response (Invalid Quota Type):
{
"error": "Invalid quota type: invalid_type",
"validTypes": [
"boards",
"participants",
"object_types",
"storage_org",
"storage_board",
"api_calls_daily",
"webhooks_daily",
"ai_requests_monthly",
"websocket_messages_daily",
"file_uploads_daily",
"exports_monthly",
"storage_component",
"cdn_bandwidth_monthly"
]
}Quota Types
The following quota types are tracked in the system:
| Type | Description | Reset Period | Limit Type |
|---|---|---|---|
boards | Active boards in organization | — | Counted |
participants | Maximum participants per board | — | Per-board |
object_types | Custom object types registered | — | Counted |
storage_org | Total organization storage (bytes) | — | Storage |
storage_board | Storage per board (bytes) | — | Per-board |
storage_component | Storage per component (bytes) | — | Per-component |
api_calls_daily | API requests allowed | Daily (midnight UTC) | Periodic |
webhooks_daily | Webhook deliveries allowed | Daily (midnight UTC) | Periodic |
websocket_messages_daily | WebSocket messages allowed | Daily (midnight UTC) | Periodic |
file_uploads_daily | File uploads allowed | Daily (midnight UTC) | Periodic |
exports_monthly | Export operations allowed | Monthly (1st day) | Periodic |
ai_requests_monthly | AI generation requests | Monthly (1st day) | Periodic |
cdn_bandwidth_monthly | CDN bandwidth (bytes) | Monthly (1st day) | Periodic |
Storage Units
All storage quotas are measured in bytes:
1 MB= 1,048,576 bytes (1024²)1 GB= 1,073,741,824 bytes (1024³)100 MB= 104,857,600 bytes
Example conversion:
const bytesToMB = (bytes) => (bytes / 1024 / 1024).toFixed(2);
const bytesToGB = (bytes) => (bytes / 1024 / 1024 / 1024).toFixed(2);
console.log(bytesToGB(8589934592)); // "8.00 GB"Pricing Tiers
Quota limits vary by pricing tier. See the complete breakdown in Platform Pricing & Quotas.
Quick Reference
| Starter | Professional | Business | Enterprise | |
|---|---|---|---|---|
| Price/month | $0 | $24 | $79 | from $299 |
| Active Boards | 10 | 100 | 500 | Unlimited |
| Participants/board | 25 | 100 | 250 | Unlimited |
| Storage (org) | 1 GB | 10 GB | 100 GB | Custom |
| API Calls/day | 1,000 | 10,000 | 100,000 | Unlimited |
| AI Requests/month | — | 50 | 200 | 1,000 |
For complete limits including webhooks, file uploads, CDN bandwidth, and all other quotas, refer to the full pricing documentation.
Soft & Hard Limits
The quota system implements two warning levels:
Soft Limit (80% usage)
- Trigger: When usage reaches 80% of limit
- Action: Warning message returned in API responses
- User Experience: Show yellow warning indicator in UI
- Example: "You've used 80 of 100 boards. Consider upgrading soon."
Hard Limit (100% usage)
- Trigger: When usage reaches 100% of limit
- Action: Operation blocked,
allowed: falsein response - User Experience: Show error message, display upgrade prompt
- Example: "Board limit reached. Upgrade to Business plan for 500 boards."
Implementation Example
// Display quota status with color coding
function getQuotaStatus(percent) {
if (percent >= 100) return { color: 'red', text: 'Limit reached' };
if (percent >= 80) return { color: 'yellow', text: 'Approaching limit' };
return { color: 'green', text: 'Healthy' };
}
// Fetch and display quota
const response = await fetch('/api/v1/quota/boards');
const quota = await response.json();
const status = getQuotaStatus(quota.percent);
showQuotaBadge(status.color, status.text);
if (!quota.allowed) {
showUpgradeModal('Upgrade to create more boards');
}Rate Limiting
All API endpoints are subject to rate limiting based on your plan. Rate limit headers are included in responses:
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9999
X-RateLimit-Reset: 1732666800| Header | Description |
|---|---|
X-RateLimit-Limit | Total requests allowed in period |
X-RateLimit-Remaining | Requests remaining in current period |
X-RateLimit-Reset | Unix timestamp when limit resets |
Rate Limit Exceeded Response:
Status Code: 429 Too Many Requests
{
"statusCode": 429,
"message": "Rate limit exceeded. Please upgrade your plan or try again later.",
"error": "Too Many Requests",
"retryAfter": 3600
}Rate Limits by Plan
| Plan | API Calls/day | Webhooks/day | AI Requests/month |
|---|---|---|---|
| Starter | 1,000 | — | — |
| Professional | 10,000 | 1,000 | 50 |
| Business | 100,000 | 10,000 | 200 |
| Enterprise | Unlimited | Unlimited | 1,000 |
Response Status Codes
| Code | Meaning | Description |
|---|---|---|
200 | OK | Request succeeded |
400 | Bad Request | Invalid quota type or parameters |
401 | Unauthorized | Missing or invalid authentication |
402 | Payment Required | Quota limit exceeded, upgrade required |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server error occurred |
402 Payment Required
When a quota is exceeded, the API may return 402 Payment Required status code:
{
"statusCode": 402,
"message": "Board limit reached. Upgrade to Professional plan for 100 boards.",
"error": "Payment Required",
"quotaType": "boards",
"current": 10,
"limit": 10,
"upgradeUrl": "https://app.boardapi.io/pricing"
}Common Use Cases
Usage Dashboard
Display organization-wide usage metrics:
async function loadUsageDashboard() {
const response = await fetch('/api/v1/quota', {
headers: { 'Authorization': `Bearer ${jwt}` }
});
const report = await response.json();
// Display plan info
document.getElementById('current-plan').textContent = report.plan;
document.getElementById('overall-usage').textContent =
`${report.overallUsagePercent.toFixed(1)}%`;
// Render quota bars
report.quotas.forEach(quota => {
renderProgressBar(quota.type, quota.percent, quota.warning);
});
// Show upgrade prompt if needed
if (report.recommendation === 'upgrade') {
showUpgradeBanner();
}
}Pre-Operation Check
Validate before performing an operation:
async function createBoard(data) {
// Check quota first
const quotaCheck = await fetch('/api/v1/quota/boards', {
headers: { 'Authorization': `Bearer ${jwt}` }
}).then(r => r.json());
if (!quotaCheck.allowed) {
throw new Error(quotaCheck.warning);
}
// Proceed with board creation
const board = await fetch('/api/v1/boards', {
method: 'POST',
headers: {
'Authorization': `Bearer ${jwt}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(r => r.json());
return board;
}Storage Monitoring
Track storage usage across organization:
async function checkStorageQuota() {
const response = await fetch('/api/v1/quota/storage_org', {
headers: { 'Authorization': `Bearer ${jwt}` }
});
const quota = await response.json();
// Convert bytes to GB for display
const usedGB = (quota.current / 1024 / 1024 / 1024).toFixed(2);
const limitGB = (quota.limit / 1024 / 1024 / 1024).toFixed(2);
console.log(`Storage: ${usedGB} GB / ${limitGB} GB`);
// Show warning if over 80%
if (quota.percent >= 80) {
showStorageWarning(`${usedGB} GB used of ${limitGB} GB`);
}
}Upgrade Flow
Implement proactive upgrade prompts:
async function checkAndPromptUpgrade() {
const report = await fetch('/api/v1/quota').then(r => r.json());
// Find quotas approaching limits
const warningQuotas = report.quotas.filter(q => q.percent >= 80);
if (warningQuotas.length > 0) {
const messages = warningQuotas.map(q =>
`${q.type}: ${q.percent}% used`
);
showUpgradeModal({
title: 'Approaching Quota Limits',
message: messages.join('\n'),
currentPlan: report.plan,
recommendation: report.recommendation
});
}
}Next Steps
- Boards API - Create and manage boards (subject to quotas)
- Pricing Plans - View all pricing tiers and limits
- Platform Pricing Documentation - Complete quota specifications
- Integration Guide - Integrate quota checks into your application