Integration Benefits
Crane Ledger is designed from the ground up for seamless integration into any application. Unlike traditional accounting software with limited APIs and complex integration requirements, Crane Ledger offers unparalleled flexibility through its headless architecture, multi-protocol support, and robust background processing system.
Headless API Architecture
What is Headless?
A headless system separates the backend business logic from the frontend user interface. Crane Ledger has no frontend assumptions - it's pure API that can power any user experience you can imagine.
Integration Advantages
Complete API Coverage
Every feature in Crane Ledger is accessible via API:
- Chart of Accounts: Create, modify, and query account structures
- Transactions: Record and manage all financial activities
- Financial Reports: Generate balance sheets, income statements, trial balances
- Multi-Organization: Handle complex business hierarchies
- Multi-Currency: Process international transactions
- Audit Trails: Access complete financial history
No UI Dependencies
// Traditional accounting software
// ❌ Must use their web interface or limited API
const quickbooks = new QuickBooksClient();
await quickbooks.launchWebInterface(); // Opens browser window
// Crane Ledger
// ✅ Pure API - integrate anywhere
const crane = new CraneLedger({ apiKey: 'cl_live_key' });
const accounts = await crane.accounts.list(); // Returns JSON data
Custom User Experiences
Build accounting interfaces tailored to your users:
- Embedded Widgets: Accounting components in your existing UI
- Mobile Apps: Native mobile accounting experiences
- Voice Interfaces: Accounting via Amazon Alexa, Google Assistant
- AI Assistants: Accounting operations through chatbots
- IoT Devices: Accounting data on smart displays
Multi-Protocol Support
Crane Ledger supports multiple communication protocols, each optimized for different use cases.
REST API - Universal Standard
Overview
Industry-standard RESTful API with predictable URLs and HTTP methods.
Best For
- CRUD Operations: Standard create, read, update, delete workflows
- Simple Integrations: Straightforward API consumption
- Caching: HTTP caching headers for performance
- Debugging: Familiar request/response patterns
Example Usage
// Create account
const response = await fetch('/organizations/org_123/accounts', {
method: 'POST',
headers: {
'Authorization': 'Bearer cl_live_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
code: '1001',
name: 'Operating Cash',
type: 'asset'
})
});
// List transactions
const transactions = await fetch('/organizations/org_123/transactions', {
headers: { 'Authorization': 'Bearer cl_live_key' }
}).then(r => r.json());
GraphQL API - Flexible Querying
Overview
Query exactly the data you need with a single request.
Best For
- Complex Data Requirements: Related data in one request
- Mobile Apps: Minimize network requests and data transfer
- Dynamic UIs: Fetch different data based on user interactions
- API Exploration: Discover available data during development
Example Usage
const query = `
query GetOrganizationOverview($orgId: ID!) {
organization(id: $orgId) {
name
accounts {
code
name
balance {
amount
formatted
}
}
recentTransactions(limit: 5) {
description
amount
date
}
}
}
`;
const result = await graphql.request(query, {
orgId: 'org_123'
});
MCP Protocol - AI-Native Integration
Overview
Model Context Protocol for seamless AI assistant integration.
Best For
- AI Applications: Accounting operations via AI assistants
- Voice Interfaces: Natural language accounting commands
- Automated Workflows: AI-driven financial processes
- Intelligent Agents: Context-aware financial operations
Example Usage
{
"method": "tools/call",
"params": {
"name": "create_invoice",
"arguments": {
"organization_id": "org_123",
"contact_id": "con_456",
"items": [
{
"description": "Consulting Services",
"quantity": 10,
"price": 100.00
}
]
}
}
}
Worker Architecture Benefits
Asynchronous Processing
Crane Ledger uses a sophisticated worker system for reliable, scalable processing:
Immediate Response + Background Processing
// Complex operations return job IDs immediately
const result = await crane.invoices.create({
contact_id: 'con_123',
items: complexItemsArray
});
// Returns: { job_id: 'job_456', status: 'queued' }
// Check status asynchronously
const status = await crane.jobs.get('job_456');
// Returns: { status: 'completed', result: invoiceData }
Benefits
- No Timeouts: Complex operations don't block your application
- Reliability: Failed operations automatically retry
- Scalability: Handle peak loads with background processing
- User Experience: Immediate feedback with progress tracking
Worker Types
Entity Workers
- Account Worker: Chart of accounts operations
- Transaction Worker: Financial transaction processing
- Invoice Worker: Sales document creation and management
- Contact Worker: Customer/vendor data management
System Workers
- Report Worker: Financial statement generation
- Reconciliation Worker: Bank statement matching
- Recurring Worker: Scheduled transaction execution
- Currency Worker: Exchange rate updates
Queue Management
// Monitor worker queues
const queues = await crane.system.queues();
// Returns queue depths, processing rates, error rates
// Prioritize urgent operations
await crane.jobs.prioritize('job_urgent_id', 'high');
// Cancel queued operations
await crane.jobs.cancel('job_unwanted_id');
Integration Patterns
Direct API Integration
Simple Synchronous Operations
class AccountingService {
constructor(apiKey, orgId) {
this.apiKey = apiKey;
this.orgId = orgId;
this.baseUrl = 'https://api.craneledger.ai';
}
async getAccountBalance(accountId) {
const response = await fetch(
`${this.baseUrl}/organizations/${this.orgId}/accounts/${accountId}`,
{
headers: { 'Authorization': `Bearer ${this.apiKey}` }
}
);
return response.json();
}
}
Batch Operations
async createBulkContacts(contacts) {
const jobs = [];
for (const contact of contacts) {
const job = await fetch('/organizations/org_123/contacts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(contact)
}).then(r => r.json());
jobs.push(job);
}
// Wait for all jobs to complete
return Promise.all(jobs.map(job => this.pollJobStatus(job.id)));
}
Webhook Integration
Real-Time Event Streaming
// Register webhook endpoint
await crane.webhooks.create({
url: 'https://your-app.com/webhooks/accounting',
events: ['transaction.posted', 'invoice.paid'],
secret: 'webhook_secret'
});
// Handle webhook in your application
app.post('/webhooks/accounting', (req, res) => {
const event = req.body;
switch (event.type) {
case 'transaction.posted':
updateLocalTransaction(event.data.transaction);
break;
case 'invoice.paid':
markInvoicePaid(event.data.invoice_id);
break;
}
res.sendStatus(200);
});
Third-Party Service Integration
Payment Processor Integration
// Stripe webhook handler
app.post('/webhooks/stripe', async (req, res) => {
const event = req.body;
if (event.type === 'payment_intent.succeeded') {
const payment = event.data.object;
// Record payment in accounting
await crane.invoices.recordPayment({
invoice_id: payment.metadata.invoice_id,
amount: payment.amount / 100, // Convert cents to dollars
payment_date: new Date(payment.created * 1000),
reference: `Stripe: ${payment.id}`
});
}
res.sendStatus(200);
});
Bank Feed Integration
// Automatic bank reconciliation
async processBankTransactions(transactions) {
for (const txn of transactions) {
// Check for matching accounting transaction
const match = await crane.transactions.find({
amount: txn.amount,
date: txn.date,
description: txn.description
});
if (match) {
// Auto-reconcile
await crane.reconciliations.reconcile({
transaction_id: match.id,
bank_transaction_id: txn.id
});
} else {
// Create new transaction
await crane.transactions.create({
description: txn.description,
amount: txn.amount,
date: txn.date,
account_id: checkingAccountId
});
}
}
}
Enterprise Integration Features
Multi-Organization Management
Client Isolation for Accounting Firms
class AccountingFirmAPI {
constructor(firmApiKey) {
this.firmApiKey = firmApiKey;
}
async createClientOrganization(clientData) {
// Create isolated client org
const clientOrg = await crane.organizations.createSub({
parent_id: this.firmOrgId,
name: clientData.name,
relationship_type: 'linked', // Data isolation
billing_type: 'shared' // Firm manages billing
});
// Create client API key
const clientKey = await crane.apiKeys.create({
organization_id: clientOrg.id,
name: `Client Portal - ${clientData.name}`
});
return { clientOrg, clientKey };
}
async getFirmOverview() {
// Consolidated view across all clients
const clients = await crane.organizations.list({
parent_id: this.firmOrgId
});
return Promise.all(
clients.map(client => crane.reports.trialBalance(client.id))
);
}
}
Advanced Security
API Key Management
// Create scoped API keys
const clientKey = await crane.apiKeys.create({
organization_id: clientOrg.id,
name: 'Client Portal',
permissions: ['read', 'write'],
expires_at: '2024-12-31'
});
// Rotate keys for security
await crane.apiKeys.rotate(clientKey.id);
Audit Trail Integration
// Complete audit history
const auditLog = await crane.events.list({
organization_id: orgId,
entity_type: 'transaction',
date_from: '2024-01-01'
});
// Export for compliance
await crane.events.export({
format: 'csv',
date_range: 'last_year'
});
Performance & Reliability
High Availability
- 99.9% Uptime SLA: Enterprise-grade reliability
- Global CDN: Fast access worldwide
- Automatic Failover: Regional redundancy
- Performance Monitoring: Real-time metrics
Scalability
- Horizontal Scaling: Add capacity as you grow
- Rate Limiting: Fair usage across all clients
- Caching: Intelligent response caching
- Background Processing: Non-blocking complex operations
Monitoring & Debugging
// API usage metrics
const metrics = await crane.system.metrics({
period: '24h',
organization_id: orgId
});
// Returns: request counts, error rates, latency stats
// Debug failed operations
const failedJobs = await crane.jobs.list({
status: 'failed',
organization_id: orgId
});
for (const job of failedJobs) {
const details = await crane.jobs.get(job.id);
console.log('Failed job:', details.error);
}
Migration Strategies
From Traditional Accounting Software
Data Export/Import
// Export from existing system
const exportData = await quickbooks.exportAll();
// Transform and import to Crane Ledger
const importJob = await crane.import.start({
source: 'quickbooks',
data: exportData,
organization_id: targetOrgId
});
// Monitor import progress
const status = await crane.jobs.poll(importJob.id);
Parallel Operation
// Run both systems during transition
class MigrationBridge {
async createTransaction(txnData) {
// Create in both systems
const [craneTxn, legacyTxn] = await Promise.all([
crane.transactions.create(txnData),
legacySystem.createTransaction(txnData)
]);
// Verify consistency
this.verifyConsistency(craneTxn, legacyTxn);
}
}
Phased Adoption
- Read-Only Integration: Access existing data via Crane Ledger
- Dual Writing: Write to both systems during testing
- Feature Migration: Move features one at a time
- Complete Cutover: Switch entirely to Crane Ledger
SDK Ecosystem
Official SDKs
// JavaScript/TypeScript
import { CraneLedger } from '@craneledger/js-sdk';
const client = new CraneLedger({
apiKey: 'cl_live_key',
organizationId: 'org_123'
});
// Type-safe operations
const invoice: Invoice = await client.invoices.create({
contactId: 'con_456',
items: [{ description: 'Service', quantity: 1, price: 100 }]
});
# Python
from craneledger import CraneLedger
client = CraneLedger(
api_key='cl_live_key',
organization_id='org_123'
)
# Async operations
invoice = await client.invoices.create({
'contact_id': 'con_456',
'items': [{'description': 'Service', 'quantity': 1, 'price': 100}]
})
// Rust
use craneledger::CraneLedger;
let client = CraneLedger::new(
"cl_live_key",
"org_123"
).await?;
// Compile-time type safety
let invoice = client.invoices().create(InvoiceCreate {
contact_id: "con_456".to_string(),
items: vec![InvoiceItem {
description: "Service".to_string(),
quantity: Decimal::from(1),
price: Decimal::from(100)
}]
}).await?;
Best Practices
Error Handling
async function safeApiCall(operation) {
try {
const result = await operation();
// Check for business logic errors
if (result.error) {
await handleBusinessError(result.error);
}
return result;
} catch (error) {
// Network or server errors
if (error.status === 429) {
await delay(1000);
return safeApiCall(operation); // Retry
}
if (error.status === 402) {
await purchaseCredits();
return safeApiCall(operation); // Retry with credits
}
throw error;
}
}
Rate Limiting Awareness
class RateLimitedClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.requests = 0;
this.resetTime = Date.now() + 60000;
}
async makeRequest(endpoint, options) {
if (Date.now() > this.resetTime) {
this.requests = 0;
this.resetTime = Date.now() + 60000;
}
if (this.requests >= 900) { // Leave buffer
await delay(this.resetTime - Date.now());
}
this.requests++;
return fetch(endpoint, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${this.apiKey}`
}
});
}
}
Webhook Security
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Future-Proofing
Protocol Evolution
Crane Ledger supports multiple protocols to ensure future compatibility:
- REST API: Industry standard, always supported
- GraphQL: Evolving query capabilities
- MCP: AI-native interactions
- Webhooks: Event-driven integrations
- WebSocket: Real-time data streaming
API Versioning
// Version-specific endpoints
const v1Client = new CraneLedger({ version: 'v1' });
const v2Client = new CraneLedger({ version: 'v2' });
// Backward compatibility
const legacyResponse = await v1Client.accounts.list();
const modernResponse = await v2Client.accounts.list();
Crane Ledger's headless architecture and multi-protocol support make it the most flexible accounting API available. Whether you're building a simple mobile app or a complex enterprise system, Crane Ledger integrates seamlessly with your technology stack.
Need help?
Create a free account to access our support portal. Once signed in, use the Support tab in your dashboard to submit a support ticket — our team typically responds within 24 hours.
- ✨ For LLMs/AI assistants: Read our structured API reference