> ## Documentation Index
> Fetch the complete documentation index at: https://lupitor-docs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Health Check

> Monitor API uptime with the health check endpoint

## 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 Code | Meaning                                 |
| ----------- | --------------------------------------- |
| `200`       | API is healthy and operational          |
| `429`       | Rate limit exceeded (too many requests) |
| `503`       | API is unhealthy (backend unavailable)  |

## Response Format

### Healthy (200 OK)

```json theme={null}
{
  "status": "ok",
  "timestamp": "2025-10-29T12:00:00.000Z"
}
```

### Unhealthy (503 Service Unavailable)

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

### Rate Limited (429 Too Many Requests)

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

## Usage

### Basic Check

```bash cURL theme={null}
curl https://YOUR_DEPLOYMENT.lupitor.com/api/health
```

```javascript JavaScript theme={null}
const response = await fetch('https://YOUR_DEPLOYMENT.lupitor.com/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 Python theme={null}
import requests

response = requests.get('https://YOUR_DEPLOYMENT.lupitor.com/api/health')

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

### With Rate Limit Headers

```bash cURL theme={null}
curl -i https://YOUR_DEPLOYMENT.lupitor.com/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](https://instatus.com)
2. Add a new monitor
3. **URL:** `https://YOUR_DEPLOYMENT.lupitor.com/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://YOUR_DEPLOYMENT.lupitor.com/api/health`
5. **Monitoring Interval:** 5 minutes

### Pingdom

1. Add new uptime check
2. **Name:** AI CSR API Health
3. **URL:** `https://YOUR_DEPLOYMENT.lupitor.com/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 JavaScript theme={null}
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://YOUR_DEPLOYMENT.lupitor.com/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: [status.lupitor.com](https://status.lupitor.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:**

* Check [status page](https://status.lupitor.com)
* Wait a few minutes and retry
* Contact support if persists: [support@lupitor.com](mailto:support@lupitor.com)

### Timing Out

**Cause:** Network issues or server overload

**Solution:**

* Check your network connection
* Verify DNS resolution
* Try from different network/region
* Check [status page](https://status.lupitor.com)

## Questions?

* **Status Page:** [status.lupitor.com](https://status.lupitor.com)
* **Support:** [support@lupitor.com](mailto:support@lupitor.com)
* **Documentation:** [API Reference](/api-reference/introduction)
