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:
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/v1/validate

Request Parameters

api_key
string
required
The user’s API key to validate
endpoint
string
required
The endpoint being accessed
method
string
required
The HTTP method being used (GET, POST, PUT, DELETE, etc.)

Response

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

{
  "success": false,
  "error": "Invalid API key",
  "code": "INVALID_API_KEY"
}

API Key Not Found

{
  "success": false,
  "error": "API key not found",
  "code": "API_KEY_NOT_FOUND"
}

Disabled API Key

{
  "success": false,
  "error": "API key is disabled",
  "code": "API_KEY_DISABLED"
}

Invalid Request

{
  "success": false,
  "error": "Invalid request",
  "code": "INVALID_REQUEST",
  "details": {
    "field": "endpoint",
    "message": "Endpoint is required"
  }
}

JavaScript Example

const response = await fetch('https://api.limitly.dev/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

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

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

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

Cache Validation Results

For high-traffic applications, consider caching validation results for a short period to reduce API calls.

Handle Errors Gracefully

Always handle validation errors gracefully and provide meaningful error messages to your users.

Monitor Usage

Regularly monitor usage patterns to optimize rate limits and plan assignments.

Next Steps