API Reference

The Reasonable API allows you to programmatically send logs, events, and health reports to your projects.

Authentication

All API requests require authentication using an API key. Include your API key in the request headers:

Authorization: Bearer YOUR_API_KEY
X-Project-ID: YOUR_PROJECT_ID

Getting Your API Credentials

You can find your API credentials in the project settings:

  1. Navigate to your project dashboard
  2. Go to Settings → API & Integration
  3. Copy your Project ID and API Key

⚠️ Keep your API key secure and never expose it in client-side code or public repositories.

Base URL

All API requests should be made to:

https://reasonable.sh

Endpoints

📊 Logs

POST /api/v1/logs

Send log entries to Reasonable.

Request Body:

{
  "project_id": "your-project-id",
  "level": "INFO",
  "message": "User logged in successfully",
  "application": "my-app",
  "timestamp": "2024-01-15T10:30:00Z",
  "meta": {
    "userId": "user-123",
    "ip": "192.168.1.1",
    "custom": "any additional data"
  }
}

Response:

{
  "success": true,
  "id": "log-id-123"
}

Log Levels:

DEBUGINFOWARNINGERRORFATAL
curl -X POST https://reasonable.sh/api/v1/logs \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-Project-ID: YOUR_PROJECT_ID" \
  -d '{
    "project_id": "your-project-id",
    "level": "INFO",
    "message": "API request completed",
    "application": "api-service",
    "timestamp": "2024-01-15T10:30:00Z",
    "meta": {
      "endpoint": "/api/users",
      "method": "GET",
      "responseTime": 145
    }
  }'

📈 Events

POST /api/v1/events

Track custom events in your application.

Request Body:

{
  "project_id": "your-project-id",
  "name": "user_signup",
  "type": "user",
  "user_id": "user-123",
  "session_id": "session-abc",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "plan": "pro",
    "source": "organic",
    "referrer": "google.com"
  }
}

Event Types:

userbusinessperformancecustom
curl -X POST https://reasonable.sh/api/v1/events \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-Project-ID: YOUR_PROJECT_ID" \
  -d '{
    "project_id": "your-project-id",
    "name": "purchase_completed",
    "type": "business",
    "user_id": "user-123",
    "timestamp": "2024-01-15T10:30:00Z",
    "data": {
      "amount": 99.99,
      "currency": "USD",
      "plan": "pro"
    }
  }'

🏥 Health

POST /api/v1/health

Monitor the health status of your services.

Request Body:

{
  "project_id": "your-project-id",
  "service": "api-gateway",
  "status": "healthy",
  "timestamp": "2024-01-15T10:30:00Z",
  "checks": [
    {
      "name": "database",
      "status": "healthy",
      "response_time": 15,
      "message": "Connected successfully"
    },
    {
      "name": "redis",
      "status": "healthy",
      "response_time": 5,
      "message": "Cache operational"
    }
  ],
  "metadata": {
    "version": "2.1.0",
    "uptime": 864000,
    "memory_usage": 75.5,
    "cpu_usage": 45.2
  }
}

Status Values:

healthydegradedunhealthy

💡 Note: Health monitoring is not yet available in the JavaScript SDK. Use the API directly for now.

curl -X POST https://reasonable.sh/api/v1/health \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-Project-ID: YOUR_PROJECT_ID" \
  -d '{
    "project_id": "your-project-id",
    "service": "web-app",
    "status": "healthy",
    "timestamp": "2024-01-15T10:30:00Z",
    "checks": [
      {
        "name": "database",
        "status": "healthy",
        "response_time": 20
      }
    ],
    "metadata": {
      "version": "1.0.0",
      "region": "us-west-2"
    }
  }'

Error Responses

All endpoints return consistent error responses:

400 Bad Request

{
  "error": "Missing required field: project_id"
}

401 Unauthorized

{
  "error": "Invalid API key"
}

403 Forbidden

{
  "error": "Access denied to project"
}

Rate Limits

API endpoints have the following rate limits:

EndpointRate Limit
/api/v1/logs10,000 requests/minute
/api/v1/events5,000 requests/minute
/api/v1/health1,000 requests/minute

Rate limit information is included in response headers:

X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9950
X-RateLimit-Reset: 1705317600

Best Practices

🔒 Security

Never expose API keys in client-side code. Use environment variables and server-side requests.

🔄 Retry Logic

Implement exponential backoff for failed requests to handle temporary issues gracefully.

📦 Batching

For high-volume applications, consider batching multiple logs/events in a single request.

📊 Structured Data

Use the meta/data fields to include structured context that can be searched and analyzed.

Quick Start Examples

While we have an official SDK for JavaScript/TypeScript, you can easily integrate Reasonable with any language. Here are simple logging functions you can copy and use:

import requests
import json
from datetime import datetime

class ReasonableLogger:
    def __init__(self, project_id, api_key, base_url="https://reasonable.sh"):
        self.project_id = project_id
        self.api_key = api_key
        self.base_url = base_url
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {api_key}",
            "X-Project-ID": project_id
        }
    
    def log(self, level, message, meta=None):
        payload = {
            "project_id": self.project_id,
            "level": level,
            "message": message,
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "application": "python-app",
            "meta": meta or {}
        }
        
        try:
            response = requests.post(
                f"{self.base_url}/api/v1/logs",
                headers=self.headers,
                json=payload
            )
            return response.json()
        except Exception as e:
            print(f"Error logging to Reasonable: {e}")
            return None
    
    def info(self, message, meta=None):
        return self.log("INFO", message, meta)
    
    def error(self, message, meta=None):
        return self.log("ERROR", message, meta)
    
    def warn(self, message, meta=None):
        return self.log("WARNING", message, meta)
    
    def debug(self, message, meta=None):
        return self.log("DEBUG", message, meta)

# Usage
logger = ReasonableLogger("your-project-id", "your-api-key")
logger.info("User logged in", {"user_id": "123"})
logger.error("Payment failed", {"error": "card_declined", "amount": 99.99})

Next Steps

Ready to start using Reasonable?