Skip to main content

Overview

The health check endpoint allows you to monitor the API’s availability and status. It’s designed for uptime monitoring services like Instatus, UptimeRobot, Pingdom, etc. Endpoint: GET /api/health Authentication: None required (public endpoint) Rate Limit: 60 requests per minute per IP address

Response Codes

Status CodeMeaning
200API is healthy and operational
429Rate limit exceeded (too many requests)
503API is unhealthy (backend unavailable)

Response Format

Healthy (200 OK)

{
  "status": "ok",
  "timestamp": "2025-10-29T12:00:00.000Z"
}

Unhealthy (503 Service Unavailable)

{
  "status": "error",
  "timestamp": "2025-10-29T12:00:00.000Z",
  "message": "Convex backend unreachable"
}

Rate Limited (429 Too Many Requests)

{
  "status": "error",
  "message": "Rate limit exceeded",
  "limit": 60,
  "remaining": 0,
  "reset": "2025-10-29T12:01:00.000Z"
}

Usage

Basic Check

cURL
curl https://lupitor.acrely.ai/api/health
JavaScript
const response = await fetch('https://lupitor.acrely.ai/api/health');
const health = await response.json();

if (health.status === 'ok') {
  console.log('API is healthy');
} else {
  console.error('API is down:', health.message);
}
Python
import requests

response = requests.get('https://lupitor.acrely.ai/api/health')

if response.status_code == 200:
    print('API is healthy')
else:
    print(f'API is unhealthy: {response.status_code}')

With Rate Limit Headers

cURL
curl -i https://lupitor.acrely.ai/api/health

# Response includes:
# HTTP/1.1 200 OK
# X-RateLimit-Limit: 60
# X-RateLimit-Remaining: 59
# X-RateLimit-Reset: 1698765432000

Monitoring Setup

Instatus

  1. Go to your Instatus dashboard
  2. Add a new monitor
  3. URL: https://lupitor.acrely.ai/api/health
  4. Method: GET
  5. Check interval: 1-5 minutes
  6. Expected status: 200
  7. Alert on: Non-200 responses or timeout

UptimeRobot

  1. Add new monitor
  2. Monitor Type: HTTP(s)
  3. Friendly Name: AI CSR API
  4. URL: https://lupitor.acrely.ai/api/health
  5. Monitoring Interval: 5 minutes

Pingdom

  1. Add new uptime check
  2. Name: AI CSR API Health
  3. URL: https://lupitor.acrely.ai/api/health
  4. Check interval: 1 minute
  5. Alert when down

What It Checks

The health endpoint verifies: API Server - Next.js server is responding ✅ Backend Connection - Convex database is reachable ✅ Query Execution - Can execute simple queries Does NOT check:
  • ❌ LiveKit voice service status
  • ❌ External integrations (OpenAI, etc.)
  • ❌ Specific feature availability

Best Practices

For Monitoring Services

  1. Set check interval to 1-5 minutes - Frequent enough to catch issues, infrequent enough to stay under rate limit
  2. Alert on 3+ consecutive failures - Avoid false alarms from transient issues
  3. Monitor from multiple regions - Detect regional outages
  4. Set reasonable timeout - 30 seconds is plenty

For Internal Health Checks

JavaScript
class HealthMonitor {
  constructor(interval = 60000) { // Check every minute
    this.interval = interval;
    this.isHealthy = true;
    this.lastCheck = null;
  }

  async start() {
    setInterval(async () => {
      try {
        const response = await fetch('https://lupitor.acrely.ai/api/health');
        const data = await response.json();

        this.isHealthy = response.ok && data.status === 'ok';
        this.lastCheck = new Date();

        if (!this.isHealthy) {
          console.error('API unhealthy:', data);
          // Trigger alerts, circuit breakers, etc.
        }
      } catch (error) {
        this.isHealthy = false;
        console.error('Health check failed:', error);
      }
    }, this.interval);
  }

  getStatus() {
    return {
      healthy: this.isHealthy,
      lastCheck: this.lastCheck
    };
  }
}

// Usage
const monitor = new HealthMonitor();
monitor.start();

Rate Limiting

The health endpoint is rate limited to 60 requests per minute per IP address. This is intentionally generous to accommodate:
  • ✅ Multiple monitoring services
  • ✅ Internal health checks
  • ✅ Testing and development
If you exceed the limit, you’ll receive a 429 response. Simply wait until the reset time indicated in the response.

Status Page

Our public status page uses this endpoint: lupitor-x-acrely.instatus.com You can subscribe for:
  • Email notifications
  • Slack/Discord webhooks
  • SMS alerts (enterprise only)
  • RSS feed

Troubleshooting

Getting 429 (Rate Limited)

Cause: More than 60 requests per minute from your IP Solution:
  • Reduce check frequency
  • Wait for rate limit reset time
  • Use multiple IP addresses if necessary

Getting 503 (Service Unavailable)

Cause: Backend database (Convex) is unreachable Solution:

Timing Out

Cause: Network issues or server overload Solution:
  • Check your network connection
  • Verify DNS resolution
  • Try from different network/region
  • Check status page

Questions?