Skip to Content

Integration

Complete guide for integrating the Credit Engine with your applications and services.

Integration with Earna Console

The Credit Engine is designed to work seamlessly with the main Earna Console application.

Console Integration Setup

// console/lib/credit-engine/client.ts import { CreditEngineClient } from './types'; export class CreditEngine implements CreditEngineClient { private baseUrl: string; private apiKey: string; constructor() { this.baseUrl = process.env.NEXT_PUBLIC_CREDIT_ENGINE_URL || 'http://localhost:3004'; this.apiKey = process.env.CREDIT_ENGINE_API_KEY!; } async chat(messages: Message[], context?: CreditContext) { const response = await fetch(`${this.baseUrl}/api/chat`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}` }, body: JSON.stringify({ messages, context }) }); if (!response.ok) { throw new Error(`Credit Engine error: ${response.statusText}`); } return response.json(); } }

Using in Console Components

// console/components/credit-coach.tsx import { useCreditEngine } from '@/hooks/use-credit-engine'; export function CreditCoach() { const { chat, isLoading } = useCreditEngine(); const [messages, setMessages] = useState<Message[]>([]); const handleSubmit = async (content: string) { const newMessage = { role: 'user', content }; const updatedMessages = [...messages, newMessage]; const response = await chat(updatedMessages, { creditScore: user.creditScore, creditGoal: user.creditGoal }); setMessages([...updatedMessages, response]); }; return ( <div className="credit-coach"> <ChatInterface messages={messages} onSubmit={handleSubmit} isLoading={isLoading} /> </div> ); }

Third-Party Integrations

REST API Integration

Basic integration using any HTTP client:

// JavaScript/Node.js const axios = require('axios'); class CreditEngineAPI { constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = 'https://credit-api.earna.sh'; } async makeRequest(endpoint, method = 'GET', data = null) { const config = { method, url: `${this.baseUrl}${endpoint}`, headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' } }; if (data) { config.data = data; } try { const response = await axios(config); return response.data; } catch (error) { console.error('API Error:', error.response?.data || error.message); throw error; } } // Example methods async getCreditAnalysis(userId) { return this.makeRequest(`/api/analyze/user/${userId}`); } async generateDispute(disputeData) { return this.makeRequest('/api/generate/dispute', 'POST', disputeData); } }

Python Integration

# Python integration example import requests import json from typing import Dict, List, Optional class CreditEngineClient: def __init__(self, api_key: str, base_url: str = "https://credit-api.earna.sh"): self.api_key = api_key self.base_url = base_url self.session = requests.Session() self.session.headers.update({ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" }) def chat(self, messages: List[Dict], context: Optional[Dict] = None): """Send chat messages to credit coach""" payload = { "messages": messages, "context": context or {} } response = self.session.post( f"{self.base_url}/api/chat", json=payload ) response.raise_for_status() return response.json() def analyze_impact(self, current_score: int, actions: List[Dict]): """Analyze impact of actions on credit score""" payload = { "currentScore": current_score, "actions": actions, "timeframe": 6 } response = self.session.post( f"{self.base_url}/api/analyze/impact", json=payload ) response.raise_for_status() return response.json() # Usage client = CreditEngineClient(api_key="your_api_key") response = client.chat([ {"role": "user", "content": "How can I improve my credit score?"} ]) print(response["response"]["content"])

Webhook Integration

Setting Up Webhooks

Configure webhooks to receive real-time notifications:

// Setup webhook endpoint const webhookConfig = { url: 'https://your-app.com/webhooks/credit-engine', events: [ 'score.changed', 'alert.created', 'goal.achieved' ], secret: 'your_webhook_secret' }; // Register webhook await creditEngine.webhooks.create(webhookConfig);

Handling Webhook Events

// Express.js webhook handler app.post('/webhooks/credit-engine', (req, res) => { const signature = req.headers['x-credit-engine-signature']; const payload = JSON.stringify(req.body); // Verify signature if (!verifySignature(payload, signature, WEBHOOK_SECRET)) { return res.status(401).send('Invalid signature'); } // Process event const event = req.body; switch (event.type) { case 'score.changed': handleScoreChange(event.data); break; case 'alert.created': sendAlertNotification(event.data); break; case 'goal.achieved': celebrateGoalAchievement(event.data); break; } res.status(200).send('OK'); }); function verifySignature(payload, signature, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(payload) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) ); }

Mobile App Integration

React Native

// React Native integration import AsyncStorage from '@react-native-async-storage/async-storage'; class CreditEngineService { private apiKey: string; private baseUrl = 'https://credit-api.earna.sh'; async initialize() { this.apiKey = await AsyncStorage.getItem('credit_engine_api_key'); } async chat(messages: Message[]): Promise<ChatResponse> { const response = await fetch(`${this.baseUrl}/api/chat`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}` }, body: JSON.stringify({ messages }) }); if (!response.ok) { throw new Error('Credit Engine request failed'); } return response.json(); } // Stream responses for better UX async *streamChat(messages: Message[]) { const response = await fetch(`${this.baseUrl}/api/chat`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}` }, 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); yield chunk; } } }

Flutter Integration

// Flutter integration import 'package:http/http.dart' as http; import 'dart:convert'; class CreditEngineClient { final String apiKey; final String baseUrl = 'https://credit-api.earna.sh'; CreditEngineClient({required this.apiKey}); Future<Map<String, dynamic>> chat(List<Map<String, String>> messages) async { final response = await http.post( Uri.parse('$baseUrl/api/chat'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $apiKey', }, body: jsonEncode({ 'messages': messages, }), ); if (response.statusCode == 200) { return jsonDecode(response.body); } else { throw Exception('Failed to load credit advice'); } } Future<Map<String, dynamic>> analyzeImpact({ required int currentScore, required List<Map<String, dynamic>> actions, }) async { final response = await http.post( Uri.parse('$baseUrl/api/analyze/impact'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $apiKey', }, body: jsonEncode({ 'currentScore': currentScore, 'actions': actions, 'timeframe': 6, }), ); if (response.statusCode == 200) { return jsonDecode(response.body); } else { throw Exception('Failed to analyze impact'); } } }

Banking API Integration

Plaid Integration (Planned)

// Planned Plaid integration for bank data import { PlaidClient } from 'plaid'; class BankingIntegration { private plaid: PlaidClient; private creditEngine: CreditEngineClient; constructor() { this.plaid = new PlaidClient({ clientId: process.env.PLAID_CLIENT_ID, secret: process.env.PLAID_SECRET, env: process.env.PLAID_ENV }); } async analyzeBankStatements(accessToken: string) { // Get transactions from Plaid const transactions = await this.plaid.transactions.get({ access_token: accessToken, start_date: '2024-01-01', end_date: '2024-12-31' }); // Send to Credit Engine for analysis const analysis = await this.creditEngine.analyzeBankData({ transactions: transactions.transactions, accounts: transactions.accounts }); return { spending_patterns: analysis.patterns, credit_impact: analysis.creditImpact, recommendations: analysis.recommendations }; } }

Credit Bureau Integration

Bureau API Integration (Planned)

// Planned credit bureau integration interface BureauIntegration { fetchReport(userId: string, bureau: string): Promise<CreditReport>; subscribeToUpdates(userId: string): Promise<Subscription>; disputeItem(itemId: string, reason: string): Promise<DisputeStatus>; } class ExperianIntegration implements BureauIntegration { async fetchReport(userId: string) { // Fetch from Experian API const report = await experianAPI.getCreditReport(userId); // Send to Credit Engine for processing const processed = await creditEngine.processReport({ bureau: 'experian', rawReport: report }); return processed; } }

GraphQL Integration

GraphQL Schema

type Query { creditScore(userId: ID!): CreditScore creditAnalysis(userId: ID!): CreditAnalysis creditHistory(userId: ID!, limit: Int): [CreditHistoryItem] } type Mutation { sendCreditChat(input: ChatInput!): ChatResponse generateDispute(input: DisputeInput!): Document analyzeImpact(input: ImpactInput!): ImpactAnalysis } type Subscription { scoreUpdates(userId: ID!): ScoreUpdate creditAlerts(userId: ID!): Alert } type CreditScore { score: Int! bureau: String! date: String! factors: [ScoreFactor] } type ChatResponse { content: String! recommendations: [Recommendation] analysis: Analysis } input ChatInput { messages: [MessageInput!]! context: ContextInput } input MessageInput { role: String! content: String! }

GraphQL Client

// Apollo Client integration import { ApolloClient, InMemoryCache, gql } from '@apollo/client'; const client = new ApolloClient({ uri: 'https://credit-api.earna.sh/graphql', cache: new InMemoryCache(), headers: { authorization: `Bearer ${apiKey}` } }); // Query example const CREDIT_CHAT = gql` mutation SendCreditChat($input: ChatInput!) { sendCreditChat(input: $input) { content recommendations { action impact priority } } } `; const result = await client.mutate({ mutation: CREDIT_CHAT, variables: { input: { messages: [ { role: 'user', content: 'How to improve my score?' } ] } } });

SDK Development

TypeScript SDK Structure

// @earna/credit-engine-sdk export class CreditEngineSDK { private client: HttpClient; public chat: ChatAPI; public analysis: AnalysisAPI; public documents: DocumentsAPI; public monitoring: MonitoringAPI; public webhooks: WebhooksAPI; constructor(config: SDKConfig) { this.client = new HttpClient(config); this.chat = new ChatAPI(this.client); this.analysis = new AnalysisAPI(this.client); this.documents = new DocumentsAPI(this.client); this.monitoring = new MonitoringAPI(this.client); this.webhooks = new WebhooksAPI(this.client); } } // Usage import { CreditEngineSDK } from '@earna/credit-engine-sdk'; const sdk = new CreditEngineSDK({ apiKey: 'your_api_key', environment: 'production' }); const response = await sdk.chat.send({ messages: [{ role: 'user', content: 'Help me improve my credit' }] });

Testing Integration

Integration Testing

// Integration test example import { CreditEngineClient } from '@/lib/credit-engine'; describe('Credit Engine Integration', () => { let client: CreditEngineClient; beforeAll(() => { client = new CreditEngineClient({ apiKey: process.env.TEST_API_KEY, baseUrl: process.env.TEST_BASE_URL }); }); test('should return credit advice', async () => { const response = await client.chat([ { role: 'user', content: 'Test message' } ]); expect(response).toHaveProperty('response'); expect(response.response).toHaveProperty('content'); }); test('should handle errors gracefully', async () => { const invalidClient = new CreditEngineClient({ apiKey: 'invalid_key', baseUrl: process.env.TEST_BASE_URL }); await expect(invalidClient.chat([])).rejects.toThrow('Unauthorized'); }); });

Monitoring Integration

Application Performance Monitoring

// Sentry integration for error tracking import * as Sentry from '@sentry/node'; Sentry.init({ dsn: process.env.SENTRY_DSN, integrations: [ new Sentry.Integrations.Http({ tracing: true }), ], tracesSampleRate: 1.0, }); // Wrap Credit Engine calls async function chatWithMonitoring(messages: Message[]) { const transaction = Sentry.startTransaction({ op: 'credit-engine.chat', name: 'Credit Engine Chat' }); try { const result = await creditEngine.chat(messages); transaction.setStatus('ok'); return result; } catch (error) { Sentry.captureException(error); transaction.setStatus('internal_error'); throw error; } finally { transaction.finish(); } }
Last updated on