Authentication
All LimesIndex API endpoints (except health checks) require authentication using an API key. This page explains how to authenticate your requests and manage your API keys securely.
API Key Authentication
LimesIndex uses API key authentication via the X-API-Key header. Every authenticated request must include this header.
Header Format
X-API-Key: your_api_key_here
Example Request
curl -X GET "https://api.limesindex.com/v1/ip/8.8.8.8" \
-H "X-API-Key: li_a1b2c3d4e5f6789012345678901234ab" \
-H "Accept: application/json"
Obtaining an API Key
Creating a New Key
- Log in to the LimesIndex Dashboard
- Navigate to Settings > API Keys
- Click Create New API Key
- Enter a descriptive name for the key
- Select the desired permissions and rate limit tier
- Click Create
- Copy your API key immediately - it won't be shown again
API Key Format
LimesIndex API keys are prefixed with li_ followed by a random alphanumeric string:
li_{random alphanumeric characters}
Example: li_a1b2c3d4e5f6789012345678901234ab
The exact length may vary, but all keys begin with the li_ prefix.
Managing API Keys
Viewing Keys
From the Dashboard, you can view:
- List of all active keys
- Key creation date
- Last usage timestamp
- Usage statistics
Rotating Keys
We recommend rotating your API keys periodically. To rotate a key:
- Create a new API key
- Update your applications to use the new key
- Verify the new key is working
- Revoke the old key
Revoking Keys
To revoke a compromised or unused key:
- Go to Settings > API Keys
- Find the key to revoke
- Click the Revoke button
- Confirm the revocation
Once revoked, a key cannot be restored. Any requests using the revoked key will immediately receive a 401 Unauthorized response.
Authentication Errors
401 Unauthorized
This error occurs when:
- The
X-API-Keyheader is missing - The API key is invalid or malformed
- The API key has been revoked
Response:
{
"data": {
"error": "unauthorized",
"code": "UNAUTHORIZED"
},
"meta": {
"processing_time_ms": 0
}
}
Solutions:
- Verify your API key is correct
- Check that the
X-API-Keyheader is properly set - Ensure the key hasn't been revoked in the dashboard
Common Authentication Issues
| Issue | Solution |
|---|---|
| Missing header | Add X-API-Key: YOUR_KEY to your request headers |
| Wrong header name | Use X-API-Key (case-sensitive), not Authorization or x-api-key |
| Revoked key | Create a new key in the dashboard |
Security Best Practices
Store Keys Securely
Never hardcode API keys in your source code. Instead:
# Set as environment variable
export LIMESINDEX_API_KEY="li_a1b2c3d4e5f6789012345678901234ab"
# Python - read from environment
import os
api_key = os.environ.get("LIMESINDEX_API_KEY")
// Node.js - read from environment
const apiKey = process.env.LIMESINDEX_API_KEY;
// Go - read from environment
apiKey := os.Getenv("LIMESINDEX_API_KEY")
Use Secrets Management
For production applications, use a secrets manager:
- AWS Secrets Manager
- Google Cloud Secret Manager
- HashiCorp Vault
- Azure Key Vault
Key Scoping
Create separate API keys for:
- Development - Test keys with lower rate limits
- Staging - Production-like keys for testing
- Production - High-limit keys for live traffic
- Different services - Separate keys per microservice
Monitor Key Usage
Regularly review:
- Usage patterns in the dashboard
- Unusual request volumes
- Requests from unexpected IP ranges
Rate Limits by Key
Each API key has an associated rate limit based on your subscription tier:
| Tier | Rate Limit | Batch Size |
|---|---|---|
| Free | 1,000 req/day | 10 IPs |
| Starter | 10,000 req/day | 100 IPs |
| Pro | 100,000 req/day | 500 IPs |
| Enterprise | Unlimited | 1,000 IPs |
See Rate Limiting for detailed information.
Unauthenticated Endpoints
The following endpoints do not require authentication:
| Endpoint | Description |
|---|---|
GET /healthz | Service health check |
GET /readyz | Service readiness check |
Code Examples
Python with requests
import os
import requests
class LimesIndexClient:
def __init__(self, api_key=None):
self.api_key = api_key or os.environ.get("LIMESINDEX_API_KEY")
self.base_url = "https://api.limesindex.com"
self.session = requests.Session()
self.session.headers.update({
"X-API-Key": self.api_key,
"Accept": "application/json"
})
def lookup_ip(self, ip):
response = self.session.get(f"{self.base_url}/v1/ip/{ip}")
response.raise_for_status()
return response.json()
# Usage
client = LimesIndexClient()
result = client.lookup_ip("8.8.8.8")
print(result)
JavaScript/TypeScript
class LimesIndexClient {
private apiKey: string;
private baseUrl = 'https://api.limesindex.com';
constructor(apiKey?: string) {
this.apiKey = apiKey || process.env.LIMESINDEX_API_KEY || '';
}
async lookupIP(ip: string): Promise<IPLookupResponse> {
const response = await fetch(`${this.baseUrl}/v1/ip/${ip}`, {
headers: {
'X-API-Key': this.apiKey,
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
return response.json();
}
}
// Usage
const client = new LimesIndexClient();
const result = await client.lookupIP('8.8.8.8');
console.log(result);
Go
package limesindex
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
type Client struct {
apiKey string
baseURL string
httpClient *http.Client
}
func NewClient(apiKey string) *Client {
if apiKey == "" {
apiKey = os.Getenv("LIMESINDEX_API_KEY")
}
return &Client{
apiKey: apiKey,
baseURL: "https://api.limesindex.com",
httpClient: &http.Client{},
}
}
func (c *Client) LookupIP(ip string) (*IPLookupResponse, error) {
req, err := http.NewRequest("GET",
fmt.Sprintf("%s/v1/ip/%s", c.baseURL, ip), nil)
if err != nil {
return nil, err
}
req.Header.Set("X-API-Key", c.apiKey)
req.Header.Set("Accept", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result IPLookupResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}
return &result, nil
}