Ledger Management

Learn how to manage entities and transactions in Open Ledger.

Open Ledger provides comprehensive APIs for managing entities (ledgers) and their financial transactions. This guide covers how to create, update, and delete entities, as well as how to work with transactions within those entities.

Entities

An “entity” in Open Ledger represents a financial ledger for a business entity. It contains all financial transactions and accounts for that entity.

Creating an Entity

To create a new entity, use the following endpoint:

1POST /v1/entities
2Content-Type: application/json
3Authorization: Bearer {access_token}
4
5{
6 "legalName": "Acme Corporation",
7 "tin": "12-3456789",
8 "usState": "CA",
9 "entityType": "LLC",
10 "phoneNumber": "+14155551234",
11 "developerId": "dev_12345"
12}

Required Fields:

  • developerId - The ID of the developer creating the entity

Optional Fields:

  • legalName - Legal name of the entity
  • tin - Tax Identification Number
  • usState - US state code
  • entityType - Type of entity (LLC, CORPORATION, etc.)
  • phoneNumber - Contact phone number
  • externalId - Your own identifier for the entity
  • clerkId - Clerk ID (alternative to developerId)

Retrieving Entity Details

To get the details of a specific entity:

1GET /v1/entities?entityId=entity_123abc
2Authorization: Bearer {access_token}

Updating an Entity

To update an existing entity:

1PUT /v1/entities?entityId=entity_123abc
2Content-Type: application/json
3Authorization: Bearer {access_token}
4
5{
6 "legalName": "Acme Corporation LLC",
7 "phoneNumber": "+14155559876"
8}

Deleting an entity

To delete an entity:

1DELETE /v1/entities?entityId=entity_123abc
2Authorization: Bearer {access_token}

Transactions

Transactions record financial activities within an entity. Each transaction represents a financial event using double-entry accounting principles with debit and credit accounts.

Adding Transactions

To add a new transaction:

1POST /v1/transactions?entityId=entity_123abc
2Content-Type: application/json
3Authorization: Bearer {access_token}
4
5{
6 "amount": 99.99,
7 "description": "Software Subscription",
8 "debitAccountId": "acc_expense_12345",
9 "creditAccountId": "acc_cash_67890",
10 "metadata": {
11 "receipt_url": "https://example.com/receipts/123.pdf",
12 "vendor": "SaaS Company Inc"
13 }
14}

Required Fields:

  • amount - The transaction amount
  • debitAccountId - ID of the account to debit
  • creditAccountId - ID of the account to credit

Optional Fields:

  • description - Description of the transaction
  • date - Transaction date (defaults to current time)
  • currency - Currency code (defaults to USD)
  • status - Transaction status (PENDING or CLEARED)
  • metadata - Additional transaction data

Retrieving Transactions

To retrieve transactions for an entity:

1GET /v1/transactions?entityId=entity_123abc&cursor=cursor_abc123&pageSize=25
2Authorization: Bearer {access_token}

Query Parameters:

  • entityId - Required entity ID
  • cursor - Pagination cursor
  • pageSize - Number of transactions per page (default: 50)

Editing a Transaction

To edit an existing transaction:

1POST /v1/transactions/edit
2Content-Type: application/json
3Authorization: Bearer {access_token}
4
5{
6 "id": "txn_123456",
7 "debit_account_id": "acc_new_debit",
8 "credit_account_id": "acc_new_credit",
9 "description": "Updated Software Subscription"
10}

Deleting a Transaction

To delete a transaction:

1DELETE /v1/transactions?entityId=entity_123abc&transactionId=txn_123456
2Authorization: Bearer {access_token}

Approving Transactions

To approve transactions (change status from PENDING to POSTED):

1PUT /v1/transactions/approve?entityId=entity_123abc
2Authorization: Bearer {access_token}
3Content-Type: application/json
4
5["txn_123456", "txn_789012"]

Request Body Options:

  • Single transaction ID as string: "txn_123456"
  • Array of transaction IDs: ["txn_123456", "txn_789012"]
  • Array of transaction objects: [{"id": "txn_123456"}]
  • Single transaction object: {"id": "txn_123456"}

Additional Transaction Endpoints

Get Transactions by Month

1GET /v1/transactions/by-month?entityId=entity_123abc&month=1&year=2024
2Authorization: Bearer {access_token}

Search Transactions

1POST /v1/transactions/search?entityId=entity_123abc
2Authorization: Bearer {access_token}
3Content-Type: application/json
4
5{
6 "query": "software",
7 "filters": {
8 "dateFrom": "2024-01-01",
9 "dateTo": "2024-01-31",
10 "amountMin": 50,
11 "amountMax": 1000
12 }
13}

Categorize a Transaction

1POST /v1/transactions/categorize?entityId=entity_123abc
2Authorization: Bearer {access_token}
3Content-Type: application/json
4
5{
6 "transactionId": "txn_123456",
7 "categoryId": "cat_98765"
8}

Bank Connection

Open Ledger allows you to connect bank accounts to automatically import transactions:

1POST /v1/banks/create-link?entityId=entity_123abc
2Authorization: Bearer {access_token}

Response:

1{
2 "link_token": "link-sandbox-abc123def456",
3 "expiration": "2024-01-31T23:59:59Z"
4}

Adding Bank Accounts

1PUT /v1/banks/accounts?entityId=entity_123abc
2Content-Type: application/json
3Authorization: Bearer {access_token}
4
5{
6 "public_token": "public-sandbox-abc123def456"
7}

Code Example

1// Example using fetch API
2const API_BASE = "https://api.openledger.com";
3const ACCESS_TOKEN = "your_access_token";
4
5// Create a new entity
6const createEntity = async () => {
7 const response = await fetch(`${API_BASE}/v1/entities`, {
8 method: 'POST',
9 headers: {
10 'Content-Type': 'application/json',
11 'Authorization': `Bearer ${ACCESS_TOKEN}`
12 },
13 body: JSON.stringify({
14 legalName: "Acme Corporation",
15 tin: "12-3456789",
16 usState: "CA",
17 entityType: "LLC",
18 phoneNumber: "+14155551234",
19 developerId: "dev_12345"
20 })
21 });
22
23 const entity = await response.json();
24 return entity;
25};
26
27// Add a transaction
28const createTransaction = async (entityId: string) => {
29 const response = await fetch(`${API_BASE}/v1/transactions?entityId=${entityId}`, {
30 method: 'POST',
31 headers: {
32 'Content-Type': 'application/json',
33 'Authorization': `Bearer ${ACCESS_TOKEN}`
34 },
35 body: JSON.stringify({
36 amount: 99.99,
37 description: "Software Subscription",
38 debitAccountId: "acc_expense_12345",
39 creditAccountId: "acc_cash_67890"
40 })
41 });
42
43 const transaction = await response.json();
44 return transaction;
45};
46
47// Retrieve transactions
48const getTransactions = async (entityId: string) => {
49 const response = await fetch(
50 `${API_BASE}/v1/transactions?entityId=${entityId}&pageSize=25`,
51 {
52 headers: {
53 'Authorization': `Bearer ${ACCESS_TOKEN}`
54 }
55 }
56 );
57
58 const data = await response.json();
59 return data.transactions;
60};
61
62// Generate a bank link token
63const createBankLink = async (entityId: string) => {
64 const response = await fetch(
65 `${API_BASE}/v1/banks/create-link?entityId=${entityId}`,
66 {
67 method: 'POST',
68 headers: {
69 'Authorization': `Bearer ${ACCESS_TOKEN}`
70 }
71 }
72 );
73
74 const data = await response.json();
75 return data.link_token;
76};

Best Practices

  1. Use Double-Entry Accounting: Always specify both debit and credit accounts for transactions
  2. Regular Reconciliation: Regularly reconcile transactions with external sources
  3. Consistent Account Structure: Maintain a well-organized chart of accounts
  4. Transaction Documentation: Add detailed descriptions and metadata to transactions
  5. Handle Pagination: Use cursor-based pagination for large datasets
  6. Error Handling: Implement robust error handling for all API calls
  7. Secure API Keys: Keep your API keys secure and rotate them regularly
  8. Use Appropriate Status: Start with PENDING status and approve transactions when ready

Important Notes

  • No Bulk Operations: The API currently does not support bulk create/update/delete operations for transactions
  • Required Developer ID: All entities must be associated with a developer or clerk ID
  • Double-Entry Required: All transactions must specify both debit and credit accounts
  • Cursor Pagination: Use cursor-based pagination instead of offset-based for better performance