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

# Request Validation

> Validate user requests via the REST API

Validate user requests against rate limits and usage policies using the Limitly REST API.

## Validate Request

Validate a user's request using their API key:

```bash theme={null}
curl -X POST \
  -H "Authorization: Bearer lk_1234567890abcdef1234567890abcdef" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "lk_user_abcdef1234567890abcdef1234567890",
    "endpoint": "/api/users",
    "method": "GET"
  }' \
  https://api.limitly.dev/functions/v1/validate
```

### Request Parameters

<ParamField body="api_key" type="string" required>
  The user's API key to validate
</ParamField>

<ParamField body="endpoint" type="string" required>
  The endpoint being accessed
</ParamField>

<ParamField body="method" type="string" required>
  The HTTP method being used (GET, POST, PUT, DELETE, etc.)
</ParamField>

### Response

```json theme={null}
{
  "success": true,
  "details": {
    "current_usage": 45,
    "limit": 1000,
    "remaining": 955,
    "reset_time": "2024-02-01T00:00:00Z",
    "plan_name": "Basic Plan"
  }
}
```

## Error Response

When a request is denied due to rate limiting:

```json theme={null}
{
  "success": false,
  "error": "Rate limit exceeded",
  "details": {
    "current_usage": 1000,
    "limit": 1000,
    "remaining": 0,
    "reset_time": "2024-02-01T00:00:00Z",
    "plan_name": "Basic Plan"
  }
}
```

## Validation Errors

### Invalid API Key

```json theme={null}
{
  "success": false,
  "error": "Invalid API key",
  "code": "INVALID_API_KEY"
}
```

### API Key Not Found

```json theme={null}
{
  "success": false,
  "error": "API key not found",
  "code": "API_KEY_NOT_FOUND"
}
```

### Disabled API Key

```json theme={null}
{
  "success": false,
  "error": "API key is disabled",
  "code": "API_KEY_DISABLED"
}
```

### Invalid Request

```json theme={null}
{
  "success": false,
  "error": "Invalid request",
  "code": "INVALID_REQUEST",
  "details": {
    "field": "endpoint",
    "message": "Endpoint is required"
  }
}
```

## JavaScript Example

```javascript theme={null}
const response = await fetch('https://api.limitly.dev/functions/v1/validate', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer lk_1234567890abcdef1234567890abcdef',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    api_key: 'lk_user_abcdef1234567890abcdef1234567890',
    endpoint: '/api/users',
    method: 'GET'
  })
});

const result = await response.json();

if (result.success) {
  console.log('Request allowed');
  console.log('Remaining requests:', result.details.remaining);
} else {
  console.log('Request denied:', result.error);
}
```

## cURL Example

```bash theme={null}
curl -X POST \
  -H "Authorization: Bearer lk_1234567890abcdef1234567890abcdef" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "lk_user_abcdef1234567890abcdef1234567890",
    "endpoint": "/api/users",
    "method": "GET"
  }' \
  https://api.limitly.dev/functions/v1/validate
```

## Response Headers

When validation is successful, the response includes useful headers:

```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 955
X-RateLimit-Reset: 1706745600
X-RateLimit-Plan: Basic Plan
```

## Rate Limit Headers

The API includes rate limit information in response headers:

* **X-RateLimit-Limit**: Total requests allowed per period
* **X-RateLimit-Remaining**: Remaining requests for the current period
* **X-RateLimit-Reset**: Unix timestamp when the limit resets
* **X-RateLimit-Plan**: Name of the plan associated with the API key

## Validation Flow

1. **Extract API Key**: Get the API key from the request (header, query param, etc.)
2. **Validate Request**: Send validation request to Limitly API
3. **Check Response**: If `success: true`, allow the request; if `success: false`, deny
4. **Handle Errors**: Provide appropriate error responses for different scenarios

## Integration Examples

### Express.js Middleware

```javascript theme={null}
const express = require('express');
const app = express();

app.use(async (req, res, next) => {
  const apiKey = req.headers['x-api-key'];
  
  if (!apiKey) {
    return res.status(401).json({ error: 'API Key required' });
  }

  try {
    const response = await fetch('https://api.limitly.dev/functions/v1/validate', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.LIMITLY_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        api_key: apiKey,
        endpoint: req.path,
        method: req.method
      })
    });

    const result = await response.json();

    if (!result.success) {
      return res.status(429).json({
        error: 'Rate limit exceeded',
        details: result.details
      });
    }

    // Add rate limit headers
    res.set('X-RateLimit-Limit', result.details.limit);
    res.set('X-RateLimit-Remaining', result.details.remaining);
    res.set('X-RateLimit-Reset', result.details.reset_time);

    next();
  } catch (error) {
    console.error('Validation error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});
```

### Next.js API Route

```javascript theme={null}
// pages/api/users.js
export default async function handler(req, res) {
  const apiKey = req.headers['authorization']?.replace('Bearer ', '');
  
  if (!apiKey) {
    return res.status(401).json({ error: 'API Key required' });
  }

  try {
    const response = await fetch('https://api.limitly.dev/functions/v1/validate', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.LIMITLY_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        api_key: apiKey,
        endpoint: req.url,
        method: req.method
      })
    });

    const result = await response.json();

    if (!result.success) {
      return res.status(429).json({
        error: 'Rate limit exceeded',
        details: result.details
      });
    }

    // Your API logic here
    res.json({ message: 'Success' });
  } catch (error) {
    console.error('Validation error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
}
```

## Best Practices

<CardGroup cols={1}>
  <Card title="Cache Validation Results">
    For high-traffic applications, consider caching validation results for a short period to reduce API calls.
  </Card>
</CardGroup>

<CardGroup cols={1}>
  <Card title="Handle Errors Gracefully">
    Always handle validation errors gracefully and provide meaningful error messages to your users.
  </Card>
</CardGroup>

<CardGroup cols={1}>
  <Card title="Monitor Usage">
    Regularly monitor usage patterns to optimize rate limits and plan assignments.
  </Card>
</CardGroup>

## Next Steps

* [API Key Management](/rest-api/api-keys) - Manage API keys for your users
* [Plans](/rest-api/plans) - Configure usage plans
* [Users](/rest-api/users) - Manage user accounts
