Skip to content

Error Codes Reference

This document describes all error responses returned by the BoardAPI, including HTTP status codes, error formats, and troubleshooting guidance.

Error Response Format

All API errors follow a consistent JSON structure:

json
{
  "statusCode": 400,
  "message": "Validation failed",
  "error": "Bad Request",
  "details": [
    {
      "field": "title",
      "message": "title must be longer than or equal to 1 characters"
    }
  ],
  "timestamp": "2025-11-19T10:30:45.123Z",
  "path": "/api/v1/boards"
}

Response Fields

FieldTypeDescription
statusCodenumberHTTP status code (400, 401, 404, etc.)
messagestringHuman-readable error description
errorstringError type name (e.g., "Bad Request", "Unauthorized")
detailsarrayOptional array of validation errors or additional context
timestampstringISO 8601 timestamp of when error occurred
pathstringAPI endpoint path where error occurred

HTTP Status Codes

2xx Success

CodeNameDescription
200OKRequest succeeded
201CreatedResource created successfully
204No ContentRequest succeeded with no response body

4xx Client Errors

400 Bad Request

Cause: Invalid request parameters, malformed JSON, or validation errors.

Example:

json
{
  "statusCode": 400,
  "message": ["title must be longer than or equal to 1 characters"],
  "error": "Bad Request"
}

Common Scenarios:

  • Missing required fields
  • Invalid data types (string instead of number)
  • Validation constraints not met
  • Malformed JSON syntax

How to Fix:

  • Check all required fields are present
  • Verify data types match API specification
  • Review validation rules in API documentation
  • Validate JSON syntax using a linter

401 Unauthorized

Cause: Missing, invalid, or expired authentication credentials.

Example:

json
{
  "statusCode": 401,
  "message": "Unauthorized",
  "error": "Unauthorized"
}

Common Scenarios:

  • Missing X-API-Key header
  • Invalid API key
  • Expired JWT token
  • Invalid board access token
  • Token signature verification failed

How to Fix:

  • Ensure X-API-Key header is present and correct
  • Check token expiration time
  • Regenerate API key if compromised
  • Verify JWT token format and signature

Code Example:

javascript
// ❌ Wrong - Missing authentication
fetch('https://api.boardapi.io/api/v1/boards', {
  method: 'POST',
  body: JSON.stringify({ title: 'Test' })
});

// ✅ Correct - Include API key
fetch('https://api.boardapi.io/api/v1/boards', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your-api-key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ title: 'Test' })
});

403 Forbidden

Cause: Authenticated but lacking permissions for the requested action.

Example:

json
{
  "statusCode": 403,
  "message": "Insufficient permissions",
  "error": "Forbidden"
}

Common Scenarios:

  • Guest trying to delete a board (requires host role)
  • Accessing organization resources from different organization
  • Attempting admin actions without admin permissions

How to Fix:

  • Check user role and permissions
  • Use host token for admin operations
  • Verify organization ID matches requested resource

404 Not Found

Cause: Requested resource does not exist.

Example:

json
{
  "statusCode": 404,
  "message": "Board not found",
  "error": "Not Found"
}

Common Scenarios:

  • Invalid board UUID
  • Board has been deleted
  • Resource ID typo or incorrect format
  • Accessing resource from different organization

How to Fix:

  • Verify resource ID is correct
  • Check if resource was deleted
  • Confirm organization scope
  • List all resources to find correct ID

409 Conflict

Cause: Request conflicts with current state of the server.

Example:

json
{
  "statusCode": 409,
  "message": "Email already exists",
  "error": "Conflict"
}

Common Scenarios:

  • Duplicate email during user registration
  • Concurrent updates to same resource
  • Attempting to create resource that already exists

How to Fix:

  • Check for existing resources before creation
  • Implement optimistic locking for concurrent updates
  • Use unique identifiers

410 Gone

Cause: Resource existed but has been permanently removed or expired.

Example:

json
{
  "statusCode": 410,
  "message": "Board has expired",
  "error": "Gone"
}

Common Scenarios:

  • Accessing expired board (past expires_at timestamp)
  • Resource explicitly marked as deleted/gone

How to Fix:

  • Create a new board
  • Check expiration dates before access
  • Archive boards instead of deleting

413 Payload Too Large

Cause: Request body exceeds size limit.

Example:

json
{
  "statusCode": 413,
  "message": "Request entity too large",
  "error": "Payload Too Large"
}

Limits:

  • Request body: 10MB
  • File uploads: 50MB

How to Fix:

  • Reduce request payload size
  • Split large requests into smaller chunks
  • Compress file uploads

422 Unprocessable Entity

Cause: Request is well-formed but contains semantic errors.

Example:

json
{
  "statusCode": 422,
  "message": "Invalid object type schema",
  "error": "Unprocessable Entity",
  "details": [
    {
      "field": "data.word",
      "message": "required property missing"
    }
  ]
}

Common Scenarios:

  • JSON schema validation failures
  • Business logic constraints violated
  • Invalid enum values

How to Fix:

  • Review object type schemas
  • Check business logic rules
  • Validate against API specification

429 Too Many Requests

Cause: Rate limit exceeded.

Example:

json
{
  "statusCode": 429,
  "message": "Rate limit exceeded. Try again in 3600 seconds.",
  "error": "Too Many Requests"
}

Rate Limits:

  • Standard Plan: 1,000 requests/hour
  • Premium Plan: 10,000 requests/hour

Response Headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1732012345

How to Fix:

  • Implement exponential backoff
  • Respect X-RateLimit-Remaining header
  • Upgrade to higher plan
  • Cache responses to reduce API calls

Code Example:

javascript
async function makeRequest(url, options, retries = 3) {
  try {
    const response = await fetch(url, options);

    if (response.status === 429 && retries > 0) {
      const resetTime = response.headers.get('X-RateLimit-Reset');
      const waitTime = (resetTime * 1000) - Date.now();

      console.log(`Rate limited. Waiting ${waitTime}ms...`);
      await new Promise(resolve => setTimeout(resolve, waitTime));

      return makeRequest(url, options, retries - 1);
    }

    return response;
  } catch (error) {
    throw error;
  }
}

5xx Server Errors

500 Internal Server Error

Cause: Unexpected server error.

Example:

json
{
  "statusCode": 500,
  "message": "Internal server error",
  "error": "Internal Server Error"
}

Common Scenarios:

  • Database connection failure
  • Unhandled exception in server code
  • Third-party service unavailable

How to Fix:

  • Retry request after brief delay
  • Check API status page
  • Contact support if persistent
  • Report error with request ID

502 Bad Gateway

Cause: Invalid response from upstream server.

Example:

json
{
  "statusCode": 502,
  "message": "Bad Gateway",
  "error": "Bad Gateway"
}

How to Fix:

  • Retry request (likely temporary)
  • Check API status page
  • Wait for service recovery

503 Service Unavailable

Cause: Service temporarily unavailable (maintenance, overload).

Example:

json
{
  "statusCode": 503,
  "message": "Service temporarily unavailable",
  "error": "Service Unavailable"
}

How to Fix:

  • Retry with exponential backoff
  • Check status page for maintenance schedule
  • Wait for service to recover

504 Gateway Timeout

Cause: Request timeout while waiting for upstream server.

Example:

json
{
  "statusCode": 504,
  "message": "Gateway timeout",
  "error": "Gateway Timeout"
}

How to Fix:

  • Retry request
  • Reduce request complexity
  • Contact support if persistent

Error Handling Best Practices

1. Always Check Status Codes

javascript
async function makeApiRequest(url, options) {
  const response = await fetch(url, options);

  if (!response.ok) {
    const error = await response.json();
    throw new ApiError(error.statusCode, error.message, error);
  }

  return response.json();
}

class ApiError extends Error {
  constructor(statusCode, message, details) {
    super(message);
    this.statusCode = statusCode;
    this.details = details;
    this.name = 'ApiError';
  }
}

2. Implement Retry Logic

javascript
async function retryRequest(fn, maxRetries = 3, delay = 1000) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (i === maxRetries - 1) throw error;

      // Retry on 5xx errors or network issues
      if (error.statusCode >= 500 || error.name === 'NetworkError') {
        const backoff = delay * Math.pow(2, i); // Exponential backoff
        await new Promise(resolve => setTimeout(resolve, backoff));
        continue;
      }

      throw error; // Don't retry 4xx errors
    }
  }
}

3. Log Errors for Debugging

javascript
function logError(error, context) {
  console.error('API Error:', {
    statusCode: error.statusCode,
    message: error.message,
    path: error.details?.path,
    timestamp: error.details?.timestamp,
    context: context
  });

  // Send to error tracking service
  if (window.Sentry) {
    Sentry.captureException(error, {
      extra: { context, errorDetails: error.details }
    });
  }
}

4. Display User-Friendly Messages

javascript
function getUserFriendlyMessage(error) {
  const messages = {
    400: 'Please check your input and try again.',
    401: 'Please log in to continue.',
    403: 'You don\'t have permission to perform this action.',
    404: 'The requested resource was not found.',
    429: 'Too many requests. Please try again later.',
    500: 'Something went wrong. Please try again.',
    503: 'Service is temporarily unavailable. Please try again later.'
  };

  return messages[error.statusCode] || 'An unexpected error occurred.';
}

Common Error Scenarios

Scenario 1: Board Not Found

Problem:

javascript
GET /api/v1/boards/invalid-uuid
404 Not Found: "Board not found"

Solution:

javascript
try {
  const board = await getBoard(uuid);
} catch (error) {
  if (error.statusCode === 404) {
    console.log('Board does not exist or was deleted');
    // Redirect to board list or show creation dialog
  }
}

Scenario 2: Token Expired

Problem:

javascript
POST /api/v1/boards
X-API-Key: expired-key
401 Unauthorized: "Invalid or expired token"

Solution:

javascript
// Regenerate API key
PATCH /api/v1/organizations/:id/regenerate-api-key

// Or refresh JWT token (for user authentication)
POST /auth/refresh
{
  "refresh_token": "..."
}

Scenario 3: Validation Error

Problem:

json
POST /api/v1/boards
{
  "title": ""
}
400 Bad Request: "title must be longer than or equal to 1 characters"

Solution:

javascript
// Validate input before sending
function validateBoardInput(data) {
  const errors = [];

  if (!data.title || data.title.length < 1) {
    errors.push('Title is required');
  }

  if (data.expires_in_hours && data.expires_in_hours < 1) {
    errors.push('Expiration must be at least 1 hour');
  }

  return errors;
}

const errors = validateBoardInput(formData);
if (errors.length > 0) {
  showValidationErrors(errors);
} else {
  await createBoard(formData);
}

Troubleshooting Guide

Quick Diagnostic Checklist

  • [ ] Is the API endpoint URL correct?
  • [ ] Is authentication header present and valid?
  • [ ] Is request body valid JSON?
  • [ ] Are all required fields included?
  • [ ] Are data types correct (string vs number)?
  • [ ] Is rate limit exceeded? (check headers)
  • [ ] Is the server healthy? (check status page)
  • [ ] Are CORS headers correct (for browser requests)?

Debugging Tools

cURL Test:

bash
# Test API endpoint with verbose output
curl -v \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  'https://api.boardapi.io/api/v1/boards'

Check Response Headers:

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

Validate JSON:

bash
# Use jq to validate JSON syntax
echo '{"title":"test"}' | jq .

Support

If you encounter persistent errors:

  1. Check API Status: https://status.boardapi.io
  2. Review Documentation: https://docs.boardapi.io
  3. Contact Support: support@boardapi.io
  4. Report Bugs: https://github.com/boardapi/issues

Include the following in support requests:

  • Error response (full JSON)
  • Request details (method, endpoint, headers)
  • Timestamp of error
  • Steps to reproduce