Skip to Content
ConsoleDevelopmentAPI Reference

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:

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 content
  • chatId (string): Chat session identifier
  • userId (string): User identifier
  • model (string): AI model to use (default: “gpt-4o”)
  • isAuthenticated (boolean): User authentication status
  • systemPrompt (string): System instructions for the AI
  • enableSearch (boolean): Enable web search capabilities

Create Chat

Create a new chat session:

POST /api/create-chat Content-Type: application/json { "title": "New Chat", "model": "gpt-4o" }

Parameters:

  • title (string): Chat title
  • model (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:

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:

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

Generate a Plaid Link token for bank connection:

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 identifier
  • products (array): Plaid products to enable
  • countryCodes (array): Supported countries
  • language (string): UI language

Exchange Public Token

Exchange Plaid public token for access token:

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:

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 account
  • category (string, optional): Filter by category
  • limit (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 available
  • TRANSACTIONS.INITIAL_UPDATE - Initial transaction sync complete
  • TRANSACTIONS.DEFAULT_UPDATE - Regular transaction updates
  • ITEM.ERROR - Connection error occurred
  • ITEM.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

CodeHTTP StatusDescription
unauthorized401Invalid or missing authentication
forbidden403Insufficient permissions
not_found404Resource not found
rate_limit_exceeded429Too many requests
invalid_request400Invalid request parameters
model_unavailable503AI model temporarily unavailable
insufficient_credits402Payment required

Rate Limiting

API rate limits by tier:

TierRequests/MinDaily MessagesConcurrent Sessions
Free20101
Pro601003
EnterpriseCustomUnlimitedUnlimited

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 created
  • chat.message.updated - Message updated
  • chat.created - New chat session started
  • chat.ended - Chat session ended
  • user.subscription.updated - Subscription changed
  • user.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 support
  • 2024-12 - Added avatar and voice features
  • 2024-11 - Initial release

Support

For API support:

Last updated on