API Reference
Complete API documentation for the Earna AI Credit Engine, including all endpoints, request/response formats, and authentication requirements.
Base URL
Development: http://localhost:3004
Production: https://credit-api.earna.sh (planned)
Authentication
All API endpoints require authentication using Bearer tokens.
Authorization: Bearer <token>
Obtaining a Token
// Using NextAuth
const session = await getSession();
const token = session?.accessToken;
// Using API Key (service accounts)
const token = process.env.CREDIT_ENGINE_API_KEY;
Core Endpoints
Health Check
Check the service health and availability.
GET /api/health
Response
{
"status": "ok",
"timestamp": "2025-01-15T10:30:00.000Z",
"version": "1.0.0",
"services": {
"database": "connected",
"ai": "ready",
"cache": "connected"
}
}
Credit Chat
AI-powered credit coaching conversation.
POST /api/chat
Content-Type: application/json
Request Body
interface ChatRequest {
messages: Message[];
context?: {
creditScore?: number;
creditGoal?: number;
timeframe?: string;
financialSituation?: {
income: number;
debt: number;
assets: number;
};
};
options?: {
streamResponse?: boolean;
includeAnalysis?: boolean;
language?: 'en' | 'fr';
};
}
interface Message {
role: 'user' | 'assistant' | 'system';
content: string;
metadata?: Record<string, any>;
}
Response
{
"response": {
"content": "Based on your credit score of 650...",
"recommendations": [
{
"action": "Pay down credit card balances",
"impact": "+40 points",
"priority": "high",
"timeline": "3 months"
}
],
"analysis": {
"currentSituation": "...",
"opportunities": ["..."],
"risks": ["..."]
}
},
"usage": {
"promptTokens": 1500,
"completionTokens": 800,
"totalCost": 0.023
}
}
Streaming Response
When streamResponse: true
, the API returns a stream of Server-Sent Events:
const response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ messages, options: { streamResponse: true } })
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
console.log('Received:', chunk);
}
Credit Analysis Endpoints
Analyze Credit Report
Parse and analyze a credit report.
POST /api/analyze/report
Content-Type: application/json
Request
interface AnalyzeReportRequest {
reportData: string; // Base64 encoded PDF or text
bureau: 'experian' | 'equifax' | 'transunion';
options?: {
extractScore?: boolean;
identifyIssues?: boolean;
generateRecommendations?: boolean;
};
}
Response
{
"analysis": {
"score": 720,
"scoreFactors": [
{
"factor": "Payment History",
"impact": "positive",
"weight": 35,
"details": "100% on-time payments"
}
],
"accounts": [
{
"name": "Credit Card XYZ",
"type": "revolving",
"status": "open",
"balance": 500,
"limit": 5000,
"utilization": 10
}
],
"issues": [
{
"severity": "medium",
"description": "High utilization on Card ABC",
"recommendation": "Pay down to below 30%"
}
]
}
}
Calculate Score Impact
Predict the impact of specific actions on credit score.
POST /api/analyze/impact
Content-Type: application/json
Request
interface ImpactRequest {
currentScore: number;
actions: Action[];
timeframe: number; // months
}
interface Action {
type: 'pay_down' | 'new_account' | 'close_account' | 'dispute';
details: Record<string, any>;
}
Response
{
"predictions": [
{
"action": "Pay down credit cards to 30% utilization",
"estimatedImpact": {
"points": 40,
"newScore": 690,
"confidence": 85
},
"timeline": {
"immediate": 10,
"threeMonths": 25,
"sixMonths": 40
}
}
],
"totalImpact": {
"bestCase": 755,
"likelyCase": 720,
"worstCase": 680
}
}
Document Generation Endpoints
Generate Dispute Letter
Create a dispute letter for credit bureau errors.
POST /api/generate/dispute
Content-Type: application/json
Request
interface DisputeRequest {
bureau: 'experian' | 'equifax' | 'transunion';
disputeType: 'error' | 'fraud' | 'outdated' | 'unverified';
accountInfo: {
creditor: string;
accountNumber: string;
disputeReason: string;
};
supportingEvidence?: string[];
userInfo: {
name: string;
address: string;
ssn?: string; // Last 4 digits only
};
}
Response
{
"document": {
"content": "Dear Experian...",
"format": "text",
"metadata": {
"bureauAddress": "...",
"mailingInstructions": "...",
"trackingNumber": "DIS-2025-001234"
}
},
"instructions": [
"Print and sign the letter",
"Include copies of supporting documents",
"Send via certified mail",
"Keep tracking information"
],
"followUp": {
"expectedResponse": "30-45 days",
"nextSteps": ["..."]
}
}
Generate Goodwill Letter
Create a goodwill letter for late payment removal.
POST /api/generate/goodwill
Content-Type: application/json
Request
interface GoodwillRequest {
creditor: string;
accountNumber: string;
latePaymentDates: string[];
explanation: string;
customerHistory: {
accountAge: number; // months
previousLatePayments: number;
};
}
Monitoring Endpoints
Set Up Monitoring
Configure credit score monitoring.
POST /api/monitor/setup
Content-Type: application/json
Request
interface MonitoringSetup {
bureaus: ('experian' | 'equifax' | 'transunion')[];
frequency: 'daily' | 'weekly' | 'monthly';
alerts: {
scoreChange: number; // Point threshold
newAccount: boolean;
hardInquiry: boolean;
latePayment: boolean;
};
notifications: {
email?: string;
sms?: string;
webhook?: string;
};
}
Get Monitoring Status
Check current monitoring configuration and recent alerts.
GET /api/monitor/status
Response
{
"monitoring": {
"active": true,
"since": "2025-01-01T00:00:00Z",
"lastCheck": "2025-01-15T10:00:00Z",
"nextCheck": "2025-01-16T10:00:00Z"
},
"recentAlerts": [
{
"type": "score_increase",
"date": "2025-01-10T15:30:00Z",
"details": {
"previousScore": 680,
"newScore": 695,
"change": 15
}
}
],
"configuration": {
"bureaus": ["experian", "equifax"],
"frequency": "daily",
"alerts": {
"scoreChange": 5,
"newAccount": true
}
}
}
Webhook Events
Event Types
interface WebhookEvent {
id: string;
type: EventType;
timestamp: string;
data: Record<string, any>;
}
type EventType =
| 'score.changed'
| 'alert.created'
| 'goal.achieved'
| 'report.available'
| 'dispute.updated'
| 'monitoring.error';
Webhook Payload Example
{
"id": "evt_2025_abc123",
"type": "score.changed",
"timestamp": "2025-01-15T10:30:00Z",
"data": {
"userId": "user_123",
"previousScore": 680,
"newScore": 695,
"change": 15,
"bureau": "experian",
"factors": [
"Credit utilization decreased",
"Payment history improved"
]
}
}
Webhook Security
Verify webhook signatures to ensure authenticity:
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Error Responses
Error Format
{
"error": {
"code": "INVALID_REQUEST",
"message": "The request body is invalid",
"details": {
"field": "creditScore",
"issue": "Must be between 300 and 900"
}
},
"requestId": "req_abc123",
"timestamp": "2025-01-15T10:30:00Z"
}
Error Codes
Code | HTTP Status | Description |
---|---|---|
UNAUTHORIZED | 401 | Missing or invalid authentication |
FORBIDDEN | 403 | Insufficient permissions |
NOT_FOUND | 404 | Resource not found |
INVALID_REQUEST | 400 | Request validation failed |
RATE_LIMITED | 429 | Too many requests |
INTERNAL_ERROR | 500 | Server error |
SERVICE_UNAVAILABLE | 503 | Service temporarily unavailable |
Rate Limiting
API rate limits per authentication type:
Auth Type | Requests/Minute | Requests/Hour | Requests/Day |
---|---|---|---|
User Token | 60 | 1,000 | 10,000 |
API Key | 120 | 2,000 | 20,000 |
Public | 10 | 100 | 500 |
Rate limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1642255200
SDK Examples
JavaScript/TypeScript
import { CreditEngineClient } from '@earna/credit-engine-sdk';
const client = new CreditEngineClient({
apiKey: process.env.CREDIT_ENGINE_API_KEY,
baseUrl: 'https://credit-api.earna.sh'
});
// Chat with AI coach
const response = await client.chat({
messages: [
{ role: 'user', content: 'How can I improve my credit score?' }
],
context: {
creditScore: 650,
creditGoal: 750
}
});
// Analyze credit impact
const impact = await client.analyzeImpact({
currentScore: 650,
actions: [
{ type: 'pay_down', details: { amount: 5000 } }
],
timeframe: 6
});
Python
from earna_credit import CreditEngineClient
client = CreditEngineClient(
api_key="your_api_key",
base_url="https://credit-api.earna.sh"
)
# Chat with AI coach
response = client.chat(
messages=[
{"role": "user", "content": "How can I improve my credit score?"}
],
context={
"credit_score": 650,
"credit_goal": 750
}
)
# Generate dispute letter
letter = client.generate_dispute(
bureau="experian",
dispute_type="error",
account_info={
"creditor": "ABC Bank",
"account_number": "****1234",
"dispute_reason": "Account not mine"
}
)
Last updated on