API Authentication
Developer Resource: This guide covers authentication setup for the Profitelligence API. Choose the method that fits your use case.
Authentication Methods
The API supports two authentication methods:
| Method | Use Case | Best For |
|---|---|---|
| Firebase JWT | User-authenticated requests | Web/mobile apps where users log in |
| API Key | Server-to-server requests | Backend services, scripts, automation |
Both methods provide the same data access. Your subscription tier (Free, Pro, Elite) determines which symbols and features you can access.
Method 1: Firebase JWT
Use Firebase Authentication when building applications where end users log in with their Profitelligence accounts.
How It Works
- User logs in via Firebase Auth (email/password, Google, etc.)
- Firebase returns a JWT token
- Include the token in API requests
- API validates the token and applies user's subscription tier
Setup
1. Initialize Firebase in your app:
import { initializeApp } from 'firebase/app';
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
const firebaseConfig = {
apiKey: "YOUR_FIREBASE_API_KEY",
authDomain: "profitelligence.firebaseapp.com",
projectId: "profitelligence"
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
2. Authenticate the user:
const userCredential = await signInWithEmailAndPassword(
auth,
email,
password
);
3. Get the JWT token:
const token = await userCredential.user.getIdToken();
4. Include in API requests:
const response = await fetch(
'https://apollo.profitelligence.com/v1/company-profile?symbol=AAPL',
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
Token Refresh
Firebase tokens expire after 1 hour. The Firebase SDK handles automatic refresh, but you should:
// Always get a fresh token before API calls
const token = await auth.currentUser.getIdToken(/* forceRefresh */ false);
The SDK returns a cached token if valid, or refreshes automatically if expired.
Python Example
import firebase_admin
from firebase_admin import credentials, auth
import requests
# Initialize Firebase Admin SDK
cred = credentials.Certificate('path/to/serviceAccount.json')
firebase_admin.initialize_app(cred)
# For server-side token verification (if you're validating tokens):
# decoded_token = auth.verify_id_token(id_token)
# For making API calls with a user's token:
def fetch_company_profile(jwt_token: str, symbol: str):
response = requests.get(
f"https://apollo.profitelligence.com/v1/company-profile",
params={"symbol": symbol},
headers={"Authorization": f"Bearer {jwt_token}"}
)
return response.text # CSV data
Method 2: API Key
Use API keys for backend services, scripts, and automated systems that don't involve user login.
How It Works
- Request an API key from your account settings
- Include the key in a custom header
- API validates the key and applies your account's subscription tier
Setup
1. Obtain your API key:
Contact support or visit your account settings to generate an API key. Keys are tied to your account and inherit your subscription tier.
2. Include in requests:
curl -H "X-API-Key: YOUR_API_KEY" \
"https://apollo.profitelligence.com/v1/company-profile?symbol=AAPL"
JavaScript Example
const API_KEY = process.env.PROFITELLIGENCE_API_KEY;
async function getCompanyProfile(symbol) {
const response = await fetch(
`https://apollo.profitelligence.com/v1/company-profile?symbol=${symbol}`,
{
headers: {
'X-API-Key': API_KEY
}
}
);
return response.text();
}
Python Example
import os
import requests
API_KEY = os.environ.get('PROFITELLIGENCE_API_KEY')
def get_company_profile(symbol: str) -> str:
response = requests.get(
"https://apollo.profitelligence.com/v1/company-profile",
params={"symbol": symbol},
headers={"X-API-Key": API_KEY}
)
response.raise_for_status()
return response.text
Security Best Practices
Never expose API keys in:
- Client-side JavaScript
- Public repositories
- Browser network requests
Do:
- Store keys in environment variables
- Use keys only in backend/server code
- Rotate keys periodically
- Use separate keys for development and production
Rate Limits
Both authentication methods are subject to rate limits based on subscription tier:
| Tier | Daily Limit | Hourly Limit |
|---|---|---|
| Free | 10 requests | 2 requests |
| Pro | 100 requests | 25 requests |
| Elite | 1,000 requests | 100 requests |
Rate Limit Headers
Every response includes rate limit information:
X-RateLimit-Limit: 100 # Your daily limit
X-RateLimit-Remaining: 87 # Requests remaining today
X-RateLimit-Reset: 1705449600 # Unix timestamp when limit resets
Handling Rate Limits
When you exceed your limit, the API returns 429 Too Many Requests:
{
"error": "Rate limit exceeded",
"code": "RATE_LIMIT_EXCEEDED",
"details": "Daily limit of 100 requests exceeded. Resets at 2024-01-17T00:00:00Z"
}
Implement exponential backoff:
import time
import requests
def api_request_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
wait_time = 2 ** attempt # 1, 2, 4 seconds
time.sleep(wait_time)
continue
return response
raise Exception("Max retries exceeded")
Optimizing API Usage
1. Use page aggregation endpoints:
Instead of multiple calls:
GET /company-profile?symbol=AAPL
GET /ohlc?symbol=AAPL
GET /technical-signals?symbol=AAPL
Use one call:
GET /company-info-page?symbol=AAPL
2. Cache responses:
Company profiles and historical data don't change frequently. Cache for 5-15 minutes.
3. Batch your requests:
If checking multiple symbols, spread requests over time rather than bursting.
Symbol Access Tiers
Your subscription tier determines which symbols you can query:
| Tier | Symbols Available |
|---|---|
| Free | Top 500 by average daily volume |
| Pro | Top 6,000 by average daily volume |
| Elite | All symbols (unlimited) |
Requesting a symbol outside your tier returns 403 Forbidden:
{
"error": "Symbol access denied",
"code": "SYMBOL_TIER_RESTRICTED",
"details": "SMALLCAP is not available on the Free tier. Upgrade to Pro for access.",
"upgrade_url": "https://profitelligence.com/subscribe"
}
Error Responses
Authentication Errors
401 Unauthorized — Missing or invalid credentials:
{
"error": "Authentication required",
"code": "AUTH_REQUIRED",
"details": "Include Authorization header with Bearer token or X-API-Key header"
}
401 Unauthorized — Expired JWT:
{
"error": "Token expired",
"code": "TOKEN_EXPIRED",
"details": "Firebase token has expired. Please refresh and retry."
}
401 Unauthorized — Invalid API key:
{
"error": "Invalid API key",
"code": "INVALID_API_KEY",
"details": "The provided API key is not valid or has been revoked"
}
Authorization Errors
403 Forbidden — Feature not available on tier:
{
"error": "Feature access denied",
"code": "FEATURE_TIER_RESTRICTED",
"details": "Advanced analytics requires Pro subscription",
"upgrade_url": "https://profitelligence.com/subscribe"
}
Testing Authentication
Verify JWT Setup
# Replace with your actual JWT token
curl -i -H "Authorization: Bearer YOUR_JWT_TOKEN" \
"https://apollo.profitelligence.com/v1/user-status"
Successful response includes your user info and tier:
{
"user_id": "abc123",
"email": "user@example.com",
"subscription_tier": "pro",
"feature_version": "main",
"available_features": ["form4_light", "form4_medium", "analytics"]
}
Verify API Key Setup
curl -i -H "X-API-Key: YOUR_API_KEY" \
"https://apollo.profitelligence.com/v1/company-profile?symbol=AAPL"
A successful response returns company data. Check the X-RateLimit-* headers to confirm your tier limits.
Common Issues
"Token expired" errors
Firebase tokens last 1 hour. Always call getIdToken() before API requests—the SDK handles refresh automatically.
"Invalid API key" errors
- Verify the key is copied correctly (no extra spaces)
- Check the key hasn't been revoked
- Ensure you're using the correct header name (
X-API-Key)
Rate limit exceeded unexpectedly
- Check if you have multiple services using the same key
- Review your code for unnecessary duplicate requests
- Consider upgrading your tier for higher limits
Next Steps
With authentication configured, explore the available endpoints:
- Company Data — Profiles, prices, signals
- Form 4 Insider — Insider trading data
- FRED Economic — Macro indicators