@finault/sdk
v4.3.0
Published
The economic proof layer for AI — sealed receipts, Named Chains, per-customer margins
Downloads
243
Maintainers
Readme
Finault SDK for Node.js
Official Node.js SDK for Finault - The economic proof layer for AI
Features
- Zero dependencies — Uses native fetch API
- Full TypeScript support — Comprehensive type definitions
- Automatic retry logic — Exponential backoff for transient failures
- Streaming support — Real-time token delivery for chat completions
- Request cancellation — AbortController support
- Typed error handling — Distinguish between auth, rate limit, and API errors
- Production-ready — Battle-tested in production environments
Installation
npm install @finault/sdkRequires Node.js 18+.
Quick Start
Initialize the Client
import Finault from '@finault/sdk';
const finault = new Finault({ apiKey: 'fk_live_...' });Route AI Requests Through Finault
const response = await finault.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'What is machine learning?' }],
providerApiKey: 'sk-...', // Your OpenAI API key
});
console.log(`Response: ${response.content}`);
console.log(`Cost: $${response.cost}`);
console.log(`Tokens: ${response.tokens}`);
console.log(`Request ID: ${response.requestId}`);Named Chains
Organize seals into scoped, independently verifiable audit trails:
// Create a response with multiple chain memberships
const response = await finault.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Generate report' }],
providerApiKey: 'sk-...',
// Assign to multiple chains for organizational scoping
finaultChains: ['product:analytics', 'customer:acme-corp']
});
console.log(`Chains: ${response.chains.join(', ')}`);
// List all active chains
const chains = await finault.chains.list();
for (const chain of chains) {
console.log(`${chain.id}: ${chain.sealCount} seals`);
}
// Export a chain for offline verification
const export = await finault.chains.export('product:analytics', {
format: 'jsonl'
});
console.log(`Exported ${export.exportedCount} seals`);
// Verify a chain server-side
const verification = await finault.chains.verify('product:analytics');
console.log(`Chain valid: ${verification.valid}`);
console.log(`Total cost: $${verification.totalCostUsd}`);Middleware Example
Use Finault as middleware to intercept and seal all API calls:
import Finault from '@finault/sdk';
import express from 'express';
const finault = new Finault({ apiKey: 'fk_live_...' });
const app = express();
// Finault middleware
app.use(async (req, res, next) => {
req.finault = finault;
req.finaultStartTime = Date.now();
res.on('finish', async () => {
if (req.aiCall) {
// Auto-seal the AI call
await req.finault.chat.completions.create({
model: req.aiCall.model,
messages: req.aiCall.messages,
providerApiKey: process.env.OPENAI_API_KEY,
finaultChains: [
`product:${req.query.product}`,
`customer:${req.query.customer}`
]
});
}
});
next();
});
app.post('/api/ask', async (req, res) => {
const { question, product, customer } = req.body;
req.aiCall = {
model: 'gpt-4o',
messages: [{ role: 'user', content: question }]
};
// Your AI logic here
res.json({ answer: 'Answer from AI' });
});Stream Chat Completions
const stream = await finault.chat.completions.createStream({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Write a poem about AI' }],
providerApiKey: 'sk-...',
});
for await (const chunk of stream) {
process.stdout.write(chunk.delta.content || '');
}Budget Management
Create a Budget
const budget = await finault.budgets.create({
name: 'GPT-4 Monthly Budget',
limit: 1000.0,
period: 'monthly',
});
console.log(`Budget ID: ${budget.id}`);List Budgets
const budgets = await finault.budgets.list();
for (const budget of budgets) {
console.log(`${budget.name}: $${budget.spent}/${budget.limit}`);
console.log(`Utilization: ${budget.utilizationPercent.toFixed(1)}%`);
console.log(`Remaining: $${budget.remaining}`);
}Get Budget Details
const budget = await finault.budgets.get('budget_123');
console.log(`Status: ${budget.status}`);
console.log(`Alert count: ${budget.alerts.length}`);Update a Budget
const updated = await finault.budgets.update('budget_123', {
limit: 2000.0,
status: 'paused',
});Cost Anomaly Detection
List Detected Anomalies
const anomalies = await finault.anomalies.list();
for (const anomaly of anomalies) {
console.log(`[${anomaly.severity}] ${anomaly.description}`);
console.log(`Variance: ${anomaly.percentageVariance.toFixed(1)}%`);
}Filter by Severity
const criticalAnomalies = await finault.anomalies.list({
severity: 'critical',
});Filter by Acknowledgement
const unacknowledged = await finault.anomalies.list({
acknowledged: false,
});Acknowledge an Anomaly
const anomaly = await finault.anomalies.acknowledge('anomaly_123');
console.log(`Acknowledged at: ${anomaly.acknowledgedAt}`);Financial Close Pack
Generate a Close Pack
const pack = await finault.closePack.generate({ period: '2026-02' });
console.log(`Period: ${pack.period}`);
console.log(`Total Spend: $${pack.totalSpend}`);
console.log(`Summary: ${pack.summary}`);
console.log(`Journal Entries: ${pack.journalEntries.length}`);List Previous Close Packs
const packs = await finault.closePack.list({ limit: 10 });
for (const pack of packs) {
console.log(`${pack.period}: $${pack.totalSpend} (${pack.status})`);
}API Key Management
Create an API Key
const key = await finault.keys.create({ name: 'Production Gateway' });
console.log(`Key ID: ${key.id}`);
// Note: The full key is only shown once upon creationList API Keys
const keys = await finault.keys.list();
for (const key of keys) {
console.log(`${key.name} (Preview: ${key.keyPreview})`);
}Revoke an API Key
await finault.keys.revoke('key_123');
console.log('Key revoked successfully');Dashboard & Insights
Get Overview Metrics
const metrics = await finault.dashboard.overview();
console.log(`Total Spend: $${metrics.totalSpend}`);
console.log(`Trend: ${metrics.spendTrend > 0 ? '+' : ''}${metrics.spendTrend.toFixed(1)}%`);
console.log(`Requests: ${metrics.requestCount}`);
console.log(`Avg Cost/Request: $${metrics.averageCostPerRequest.toFixed(4)}`);
console.log('\nTop Models:');
for (const model of metrics.topModels) {
console.log(` ${model.name}: ${model.usage} calls, $${model.cost}`);
}Get Insights and Recommendations
const insights = await finault.dashboard.insights();
console.log('Key Findings:');
for (const finding of insights.keyFindings) {
console.log(` - ${finding}`);
}
console.log('\nRecommendations:');
for (const rec of insights.recommendations) {
console.log(` - ${rec}`);
}
console.log('\nOptimization Opportunities:');
for (const opp of insights.optimizationOpportunities) {
console.log(` - ${opp.title}: $${opp.potentialSavings} potential savings`);
}Error Handling
import {
FinaultError,
AuthenticationError,
RateLimitError,
ValidationError,
APIError,
} from '@finault/sdk';
try {
const response = await finault.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
providerApiKey: 'sk-...',
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error(`Authentication failed: ${error.message}`);
console.error(`Request ID: ${error.requestId}`);
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
} else if (error instanceof ValidationError) {
console.error(`Validation error: ${error.message}`);
console.error(`Field errors: ${JSON.stringify(error.fieldErrors)}`);
} else if (error instanceof APIError) {
console.error(`API error: ${error.message}`);
console.error(`Status: ${error.statusCode}`);
} else if (error instanceof Error) {
console.error(`Unexpected error: ${error.message}`);
}
}Request Cancellation
Use AbortController to cancel requests:
const controller = new AbortController();
// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);
try {
const response = await finault.chat.completions.create(
{
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
providerApiKey: 'sk-...',
},
{ signal: controller.signal }
);
} catch (error) {
if (error instanceof APIError && error.message.includes('timeout')) {
console.error('Request was cancelled or timed out');
}
}Configuration Options
const finault = new Finault({
apiKey: 'fk_live_...',
baseUrl: 'https://api.finault.ai', // Custom base URL
timeout: 30000, // Request timeout in milliseconds (default: 30000)
maxRetries: 3, // Automatic retry attempts for 429/5xx (default: 3)
});Retry Logic
The SDK automatically retries requests that fail with:
- 429 (Rate Limit)
- 500, 502, 503, 504 (Server Errors)
Retries use exponential backoff with a configurable base delay (default 1 second).
TypeScript Support
Full TypeScript support with comprehensive type definitions:
import Finault, {
ChatCompletionRequest,
ChatCompletionResponse,
Budget,
Anomaly,
DashboardOverview,
} from '@finault/sdk';
const finault = new Finault({ apiKey: 'fk_live_...' });
const request: ChatCompletionRequest = {
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
providerApiKey: 'sk-...',
};
const response: ChatCompletionResponse = await finault.chat.completions.create(request);
const budgets: Budget[] = await finault.budgets.list();
const anomalies: Anomaly[] = await finault.anomalies.list();
const overview: DashboardOverview = await finault.dashboard.overview();API Reference
Resources
finault.chat.completions.create()- Create a chat completionfinault.chat.completions.createStream()- Stream a chat completionfinault.closePack.generate()- Generate a financial close packfinault.closePack.list()- List previous close packsfinault.budgets.create()- Create a new budgetfinault.budgets.list()- List all budgetsfinault.budgets.get()- Get a specific budgetfinault.budgets.update()- Update a budgetfinault.anomalies.list()- List detected anomaliesfinault.anomalies.get()- Get specific anomalyfinault.anomalies.acknowledge()- Mark anomaly as acknowledgedfinault.keys.create()- Create an API keyfinault.keys.list()- List API keysfinault.keys.revoke()- Revoke an API keyfinault.dashboard.overview()- Get dashboard overviewfinault.dashboard.insights()- Get dashboard insights
API Reference
Complete API documentation is available at:
- Docs: https://docs.finault.ai
- SDK Reference: https://docs.finault.ai/sdk/node
- OpenAPI Spec: https://api.finault.ai/openapi.yaml
- TypeScript Types: Fully defined in the SDK (no separate @types package needed)
Support
For issues, questions, or feedback:
- Email: [email protected]
- GitHub Issues: https://github.com/finault/finault-node/issues
- Discussions: https://github.com/finault/finault-node/discussions
- Discord: https://discord.gg/finault
License
MIT License - see LICENSE file for details
