API Reference
Complete REST API reference for Earna AI Console. The API provides endpoints for chat interactions, model management, avatar sessions, voice conversations, and file handling powered by GPT-4o and multiple AI providers.
Base URL
Development: http://localhost:3000/api
Production: Deployed on Vercel (custom domain)
Authentication
All API requests require authentication using Supabase Auth JWT tokens:
Authorization: Bearer your_jwt_token
Content-Type: application/json
X-API-Version: 2025-01
Chat APIs
Send Message
Send a message to GPT-4o or alternative models:
Request
POST /api/chat
Content-Type: application/json
{
"messages": [{"role": "user", "content": "Explain how this platform works"}],
"chatId": "chat_abc123",
"userId": "user_123",
"model": "gpt-4o",
"isAuthenticated": true,
"systemPrompt": "You are a helpful assistant",
"enableSearch": false
}
Parameters:
messages
(array): Array of message objects with role and contentchatId
(string): Chat session identifieruserId
(string): User identifiermodel
(string): AI model to use (default: “gpt-4o”)isAuthenticated
(boolean): User authentication statussystemPrompt
(string): System instructions for the AIenableSearch
(boolean): Enable web search capabilities
Create Chat
Create a new chat session:
Request
POST /api/create-chat
Content-Type: application/json
{
"title": "New Chat",
"model": "gpt-4o"
}
Parameters:
title
(string): Chat titlemodel
(string): Default model for the chat
Create Guest User
Create an anonymous guest user:
POST /api/create-guest
Content-Type: application/json
Response:
{
"chats": [
{
"id": "chat_abc123",
"title": "Quantum Computing Discussion",
"model": "gpt-4o",
"createdAt": "2025-01-15T10:00:00Z",
"updatedAt": "2025-01-15T10:30:00Z",
"messageCount": 15
}
]
}
Model Management
List Available Models
Get all available AI models:
GET /api/models
Authorization: Bearer your_jwt_token
Response:
{
"models": [
{
"id": "gpt-4o",
"name": "GPT-4o",
"provider": "openai",
"features": ["chat", "vision", "tools", "voice"],
"contextLength": 128000,
"primary": true
},
{
"id": "claude-3-opus-20240229",
"name": "Claude 3 Opus",
"provider": "anthropic",
"features": ["chat", "vision", "tools"],
"contextLength": 200000
},
{
"id": "gemini-1.5-pro",
"name": "Gemini 1.5 Pro",
"provider": "google",
"features": ["chat", "vision", "tools"],
"contextLength": 1000000
}
]
}
Update Chat Model
Change the model for a chat:
POST /api/update-chat-model
Content-Type: application/json
{
"chatId": "chat_abc123",
"model": "claude-3-opus-20240229"
}
Avatar APIs (HeyGen)
Create Avatar Session
Initialize a HeyGen avatar session:
Request
POST /api/heygen/create-session
Content-Type: application/json
{
"avatarId": "josh_lite3_20230714",
"voice": {
"voiceId": "en-US-BrianNeural",
"rate": 1.0,
"pitch": 0
}
}
Make Avatar Speak
Send text for the avatar to speak:
POST /api/heygen/speak
Content-Type: application/json
{
"sessionId": "session_xyz789",
"text": "Hello, I'm your AI assistant",
"taskType": "talk"
}
Get Avatar Session
Get avatar session details:
GET /api/heygen/session
Authorization: Bearer your_jwt_token
List Avatars
Get available avatars:
GET /api/heygen/list-avatars
Authorization: Bearer your_jwt_token
Voice APIs (GPT-4o Realtime)
Create Voice Session
Initialize a GPT-4o Realtime voice session:
Request
POST /api/realtime-session
Content-Type: application/json
{
"voice": "alloy",
"instructions": "You are a helpful assistant"
}
Text-to-Speech
Convert text to speech using OpenAI TTS:
POST /api/tts
Content-Type: application/json
{
"text": "Hello, this is a test",
"voice": "nova",
"speed": 1.0
}
Response: Audio file (audio/mpeg)
Speech-to-Text (Whisper)
Transcribe audio to text:
POST /api/whisper
Content-Type: multipart/form-data
audio: [audio file]
language: "en"
Response:
{
"text": "This is the transcribed text",
"language": "en",
"duration": 3.5
}
File Management
Get User Keys
Get user API keys configuration:
GET /api/user-keys
Authorization: Bearer your_jwt_token
User Key Status
Check user API key status:
GET /api/user-key-status
Authorization: Bearer your_jwt_token
Response:
{
"fileId": "file_xyz123",
"url": "https://storage.earna.sh/files/file_xyz123",
"name": "document.pdf",
"size": 1024000,
"mimeType": "application/pdf"
}
Analyze Image
Analyze an image with GPT-4o vision:
POST /api/vision/analyze
Content-Type: application/json
{
"imageUrl": "https://storage.earna.sh/files/image.jpg",
"prompt": "What's in this image?"
}
Response:
{
"analysis": "The image shows a beautiful sunset over mountains...",
"model": "gpt-4o",
"confidence": 0.95
}
Plaid Banking APIs
Create Link Token
Generate a Plaid Link token for bank connection:
Request
POST /api/plaid/create-link-token
Content-Type: application/json
Authorization: Bearer your_jwt_token
{
"userId": "user_123",
"products": ["transactions", "accounts"],
"countryCodes": ["US", "CA"],
"language": "en"
}
Parameters:
userId
(string): User identifierproducts
(array): Plaid products to enablecountryCodes
(array): Supported countrieslanguage
(string): UI language
Exchange Public Token
Exchange Plaid public token for access token:
Request
POST /api/plaid/exchange-token
Content-Type: application/json
Authorization: Bearer your_jwt_token
{
"public_token": "public-production-abc123",
"institution": {
"id": "ins_109508",
"name": "Chase"
},
"accounts": [
{
"id": "acc_123",
"name": "Checking",
"mask": "0000",
"type": "depository",
"subtype": "checking"
}
]
}
Get Accounts
Retrieve connected bank accounts:
GET /api/plaid/accounts
Authorization: Bearer your_jwt_token
Response:
{
"accounts": [
{
"account_id": "acc_123",
"name": "Chase Checking",
"official_name": "Chase Total Checking",
"type": "depository",
"subtype": "checking",
"mask": "0000",
"balances": {
"available": 5000.00,
"current": 5250.00,
"limit": null,
"iso_currency_code": "USD",
"last_updated": "2025-01-15T10:00:00Z"
}
},
{
"account_id": "acc_456",
"name": "Chase Savings",
"type": "depository",
"subtype": "savings",
"mask": "1111",
"balances": {
"available": 15000.00,
"current": 15000.00,
"limit": null,
"iso_currency_code": "USD",
"last_updated": "2025-01-15T10:00:00Z"
}
}
],
"total_balance": 20250.00,
"last_sync": "2025-01-15T10:00:00Z"
}
Get Transactions
Retrieve bank transactions with real-time updates:
Request
GET /api/plaid/transactions?startDate=2025-01-01&endDate=2025-01-15&accountId=acc_123
Authorization: Bearer your_jwt_token
Query Parameters:
startDate
(string): Start date (YYYY-MM-DD)endDate
(string): End date (YYYY-MM-DD)accountId
(string, optional): Filter by accountcategory
(string, optional): Filter by categorylimit
(number): Max results (default: 100)offset
(number): Pagination offset
Refresh Transactions
Trigger real-time transaction sync:
POST /api/plaid/refresh
Content-Type: application/json
Authorization: Bearer your_jwt_token
{
"connectionId": "conn_abc123",
"force": true
}
Response:
{
"status": "syncing",
"added": 12,
"modified": 3,
"removed": 0,
"next_cursor": "cursor_xyz789",
"has_more": false
}
Process Webhook
Handle Plaid webhook events for real-time updates:
POST /api/plaid/webhook
Content-Type: application/json
X-Plaid-Signature: webhook_signature_here
{
"webhook_type": "TRANSACTIONS",
"webhook_code": "SYNC_UPDATES_AVAILABLE",
"item_id": "item_xyz789",
"initial_update_complete": true,
"historical_update_complete": true
}
Webhook Types:
TRANSACTIONS.SYNC_UPDATES_AVAILABLE
- New transactions availableTRANSACTIONS.INITIAL_UPDATE
- Initial transaction sync completeTRANSACTIONS.DEFAULT_UPDATE
- Regular transaction updatesITEM.ERROR
- Connection error occurredITEM.PENDING_EXPIRATION
- Token expiring soon
Get Institutions
Get supported banks and credit unions (12,000+ institutions):
GET /api/plaid/institutions?countryCodes=US,CA
Authorization: Bearer your_jwt_token
Response:
{
"institutions": [
{
"institution_id": "ins_109508",
"name": "Chase",
"products": ["assets", "auth", "balance", "transactions", "identity"],
"country_codes": ["US"],
"logo": "https://plaid-logos.com/chase.png",
"primary_color": "#0066b2",
"oauth": true,
"routing_numbers": ["021000021", "022000020"]
},
{
"institution_id": "ins_109509",
"name": "Bank of America",
"products": ["assets", "auth", "balance", "transactions"],
"country_codes": ["US"],
"logo": "https://plaid-logos.com/bofa.png",
"primary_color": "#e31837",
"oauth": true
}
],
"total": 12000,
"coverage": {
"US": 11500,
"CA": 500
}
}
Disconnect Bank
Remove a bank connection:
DELETE /api/plaid/disconnect
Content-Type: application/json
Authorization: Bearer your_jwt_token
{
"connectionId": "conn_abc123"
}
Response:
{
"success": true,
"message": "Bank connection removed successfully",
"connectionId": "conn_abc123"
}
User Management
Get User Preferences
Retrieve user preferences:
GET /api/user-preferences
Authorization: Bearer your_jwt_token
Update User Preferences
Update user preferences:
POST /api/user-preferences
Content-Type: application/json
{
"theme": "dark",
"defaultModel": "gpt-4o"
}
Response:
{
"id": "user_123",
"email": "user@example.com",
"username": "johndoe",
"subscription": {
"tier": "pro",
"dailyMessageLimit": 100,
"messagesUsedToday": 23
},
"settings": {
"defaultModel": "gpt-4o",
"theme": "dark",
"language": "en"
}
}
Update Settings
Update user settings:
PATCH /api/user/settings
Content-Type: application/json
{
"defaultModel": "claude-3-opus-20240229",
"theme": "light",
"notifications": true
}
Subscription Management
Get Rate Limits
Check rate limit status:
GET /api/rate-limits
Authorization: Bearer your_jwt_token
Response:
{
"tier": "pro",
"status": "active",
"dailyMessageLimit": 100,
"messagesUsedToday": 23,
"resetAt": "2025-01-16T00:00:00Z",
"features": {
"gpt4Access": true,
"alternativeModels": true,
"avatarMinutes": "unlimited",
"voiceMinutes": "unlimited"
}
}
WebSocket Events
Real-time Message Updates
Connect to WebSocket for live updates:
const ws = new WebSocket('wss://api.earna.sh/realtime');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch(data.type) {
case 'message.new':
// New message in chat
break;
case 'message.update':
// Message updated
break;
case 'typing.start':
// User started typing
break;
case 'typing.stop':
// User stopped typing
break;
}
};
Error Handling
All API errors follow a consistent format:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Daily message limit reached",
"details": {
"limit": 10,
"used": 10,
"resetAt": "2025-01-16T00:00:00Z"
}
}
}
Common Error Codes
Code | HTTP Status | Description |
---|---|---|
unauthorized | 401 | Invalid or missing authentication |
forbidden | 403 | Insufficient permissions |
not_found | 404 | Resource not found |
rate_limit_exceeded | 429 | Too many requests |
invalid_request | 400 | Invalid request parameters |
model_unavailable | 503 | AI model temporarily unavailable |
insufficient_credits | 402 | Payment required |
Rate Limiting
API rate limits by tier:
Tier | Requests/Min | Daily Messages | Concurrent Sessions |
---|---|---|---|
Free | 20 | 10 | 1 |
Pro | 60 | 100 | 3 |
Enterprise | Custom | Unlimited | Unlimited |
Rate limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1705315200
Code Examples
Node.js/TypeScript
import { createClient } from '@earna/sdk';
const client = createClient({
apiKey: process.env.EARNA_API_KEY,
baseUrl: 'https://api.earna.sh/v1'
});
// Send a message
const response = await client.chat.send({
message: 'Hello, GPT-4o!',
model: 'gpt-4o',
stream: true
});
// Handle streaming response
for await (const chunk of response) {
console.log(chunk.content);
}
Python
import earna
client = earna.Client(
api_key=os.environ["EARNA_API_KEY"],
base_url="https://api.earna.sh/v1"
)
# Send a message
response = client.chat.send(
message="Hello, GPT-4o!",
model="gpt-4o",
stream=True
)
# Handle streaming response
for chunk in response:
print(chunk.content, end="")
cURL
# Send a chat message
curl -X POST https://api.earna.sh/v1/api/chat \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Hello, GPT-4o!",
"model": "gpt-4o"
}'
# Get chat history
curl -X GET "https://api.earna.sh/v1/api/chat/history?chatId=chat_abc123" \
-H "Authorization: Bearer $API_KEY"
SDK Libraries
Official SDKs available:
- JavaScript/TypeScript:
pnpm add @earna/sdk
- Python:
pip install earna
- Go:
go get github.com/earna/go-sdk
- Ruby:
gem install earna
For detailed SDK documentation, visit sdk.earna.shÂ
Webhooks
Configure webhooks to receive real-time events:
Webhook Events
chat.message.created
- New message createdchat.message.updated
- Message updatedchat.created
- New chat session startedchat.ended
- Chat session endeduser.subscription.updated
- Subscription changeduser.limit.reached
- Daily limit reached
Webhook Payload
{
"event": "chat.message.created",
"timestamp": "2025-01-15T10:30:00Z",
"data": {
"chatId": "chat_abc123",
"messageId": "msg_xyz789",
"role": "assistant",
"model": "gpt-4o",
"content": "Hello! How can I help you?"
}
}
Webhook Security
Verify webhook signatures:
import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string) {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const expectedSignature = hmac.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
API Versioning
The API uses date-based versioning:
X-API-Version: 2025-01
Version History
2025-01
- Current version with GPT-4o support2024-12
- Added avatar and voice features2024-11
- Initial release
Support
For API support:
- Documentation: docs.earna.shÂ
- Status: status.earna.shÂ
- Support: support@earna.sh