Skip to content

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):

bash
curl -H "Authorization: Bearer your-jwt-token" \
  https://api.boardapi.io/api/v1/quota

API Key:

bash
curl -H "X-API-Key: your-api-key" \
  https://api.boardapi.io/api/v1/quota

Get your API key from the Developer Dashboard.

Base URL

https://api.boardapi.io/api/v1

For development:

http://localhost:4000/api/v1

Endpoints Overview

MethodEndpointDescription
GET/quotaGet comprehensive usage report for all quotas
GET/quota/:typeGet 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

http
GET /quota
Authorization: Bearer your-jwt-token

Response

Status Code: 200 OK

json
{
  "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

FieldTypeDescription
planstringCurrent plan: starter, professional, business, enterprise
quotasarrayArray of quota usage details for each resource type
quotas[].typestringQuota type (see Quota Types)
quotas[].currentnumberCurrent usage value
quotas[].limitnumberMaximum allowed value (-1 = unlimited)
quotas[].remainingnumberRemaining capacity
quotas[].percentnumberUsage percentage (0-100)
quotas[].isUnlimitedbooleanWhether this quota is unlimited
quotas[].resetAtstringISO 8601 timestamp when quota resets (periodic quotas only)
quotas[].warningstringWarning message if approaching limit (80%+)
overallUsagePercentnumberAverage usage across all limited quotas
recommendationstringRecommended action: ok, monitor, upgrade

Recommendations

ValueUsageMeaning
ok< 70%Usage is healthy
monitor70-90%Monitor usage, plan for upgrade
upgrade90%+Upgrade recommended to avoid limits

Example Requests

JavaScript/TypeScript:

javascript
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:

bash
curl -H "Authorization: Bearer your-jwt-token" \
  'https://api.boardapi.io/api/v1/quota'

PHP:

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 CodeErrorDescription
401UnauthorizedInvalid 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

http
GET /quota/:type
Authorization: Bearer your-jwt-token

URL Parameters

ParameterTypeDescription
typestringQuota type to check (see Quota Types)

Response

Status Code: 200 OK

json
{
  "allowed": true,
  "current": 45,
  "limit": 100,
  "remaining": 55,
  "warning": null
}

When approaching limit (80%+):

json
{
  "allowed": true,
  "current": 82,
  "limit": 100,
  "remaining": 18,
  "warning": "Warning: You've used 82% of your boards quota"
}

When limit exceeded:

json
{
  "allowed": false,
  "current": 100,
  "limit": 100,
  "remaining": 0,
  "warning": "Board limit reached. Upgrade to Business plan for 500 boards."
}

Response Fields

FieldTypeDescription
allowedbooleanWhether operation is allowed
currentnumberCurrent usage value
limitnumberMaximum allowed value (-1 = unlimited)
remainingnumberRemaining capacity
warningstringWarning or error message (if applicable)

Example Requests

JavaScript/TypeScript:

javascript
// 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:

bash
# 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
<?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 CodeErrorDescription
400Bad RequestInvalid quota type
401UnauthorizedInvalid or missing authentication token

Error Response (Invalid Quota Type):

json
{
  "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:

TypeDescriptionReset PeriodLimit Type
boardsActive boards in organizationCounted
participantsMaximum participants per boardPer-board
object_typesCustom object types registeredCounted
storage_orgTotal organization storage (bytes)Storage
storage_boardStorage per board (bytes)Per-board
storage_componentStorage per component (bytes)Per-component
api_calls_dailyAPI requests allowedDaily (midnight UTC)Periodic
webhooks_dailyWebhook deliveries allowedDaily (midnight UTC)Periodic
websocket_messages_dailyWebSocket messages allowedDaily (midnight UTC)Periodic
file_uploads_dailyFile uploads allowedDaily (midnight UTC)Periodic
exports_monthlyExport operations allowedMonthly (1st day)Periodic
ai_requests_monthlyAI generation requestsMonthly (1st day)Periodic
cdn_bandwidth_monthlyCDN 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:

javascript
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

StarterProfessionalBusinessEnterprise
Price/month$0$24$79from $299
Active Boards10100500Unlimited
Participants/board25100250Unlimited
Storage (org)1 GB10 GB100 GBCustom
API Calls/day1,00010,000100,000Unlimited
AI Requests/month502001,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: false in response
  • User Experience: Show error message, display upgrade prompt
  • Example: "Board limit reached. Upgrade to Business plan for 500 boards."

Implementation Example

javascript
// 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
HeaderDescription
X-RateLimit-LimitTotal requests allowed in period
X-RateLimit-RemainingRequests remaining in current period
X-RateLimit-ResetUnix timestamp when limit resets

Rate Limit Exceeded Response:

Status Code: 429 Too Many Requests

json
{
  "statusCode": 429,
  "message": "Rate limit exceeded. Please upgrade your plan or try again later.",
  "error": "Too Many Requests",
  "retryAfter": 3600
}

Rate Limits by Plan

PlanAPI Calls/dayWebhooks/dayAI Requests/month
Starter1,000
Professional10,0001,00050
Business100,00010,000200
EnterpriseUnlimitedUnlimited1,000

Response Status Codes

CodeMeaningDescription
200OKRequest succeeded
400Bad RequestInvalid quota type or parameters
401UnauthorizedMissing or invalid authentication
402Payment RequiredQuota limit exceeded, upgrade required
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error occurred

402 Payment Required

When a quota is exceeded, the API may return 402 Payment Required status code:

json
{
  "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:

javascript
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:

javascript
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:

javascript
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:

javascript
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