The Reasonable API allows you to programmatically send logs, events, and health reports to your projects.
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_IDYou can find your API credentials in the project settings:
⚠️ Keep your API key secure and never expose it in client-side code or public repositories.
All API requests should be made to:
https://reasonable.shSend 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:
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
}
}'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:
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"
}
}'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:
💡 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"
}
}'All endpoints return consistent error responses:
{
"error": "Missing required field: project_id"
}{
"error": "Invalid API key"
}{
"error": "Access denied to project"
}API endpoints have the following rate limits:
| Endpoint | Rate Limit |
|---|---|
| /api/v1/logs | 10,000 requests/minute |
| /api/v1/events | 5,000 requests/minute |
| /api/v1/health | 1,000 requests/minute |
Rate limit information is included in response headers:
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9950
X-RateLimit-Reset: 1705317600Never expose API keys in client-side code. Use environment variables and server-side requests.
Implement exponential backoff for failed requests to handle temporary issues gracefully.
For high-volume applications, consider batching multiple logs/events in a single request.
Use the meta/data fields to include structured context that can be searched and analyzed.
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})Ready to start using Reasonable?