General Ledger API Overview
The General Ledger (GL) API provides a comprehensive transactional backbone for the Revenue Recognition System. It manages the complete lifecycle of business transactions from creation through GL posting, and provides powerful reporting capabilities for financial analysis.
The GL system is designed for multi-subsidiary operations with full accounting dimension support (class, department, location) and multi-currency capabilities.
System Architecture
The GL API is built on a multi-layered architecture that separates business transactions from GL entries:
Business Transaction Layer
- Purpose: Captures commercial activities (sales orders, invoices, purchase orders)
- Features: Multi-line transactions, approval workflow, status management
- Integration: Links to customers, vendors, items, and other business entities
GL Posting Engine
- Purpose: Converts business transactions into balanced journal entries
- Features: Rules-based posting, automatic account determination, multi-currency support
- Controls: Validation, approval requirements, period controls
Reporting Layer
- Purpose: Provides financial reports and account analysis
- Features: Trial balance, account activity, general ledger, custom queries
- Performance: Optimized for large datasets with pagination and filtering
Key Features
Multi-Entity Support
- Organizations: Top-level isolation for complete data separation
- Subsidiaries: Legal entities within organizations for consolidated reporting
- Dimensions: Class, department, and location for segment analysis
Transaction Lifecycle
DRAFT → PENDING_APPROVAL → APPROVED → POSTED → PAID → CLOSED
↓ ↓ ↓
CANCELLED CANCELLED REVERSED
Posting Rules Engine
- Automatic Posting: Rules-based conversion of business transactions to GL
- Account Determination: Configurable logic for account assignment
- Validation: Ensures all transactions are balanced and complete
Real-time Balances
- Account Balances: Maintained in real-time as transactions are posted
- Period Balances: Historical snapshots by accounting period
- Multi-Currency: Base and transaction currency support
API Endpoints Overview
Business Transactions API
Manage the complete lifecycle of business transactions.
Endpoint | Method | Purpose |
---|---|---|
/api/v1/gl/transactions | POST | Create new business transaction |
/api/v1/gl/transactions | GET | List business transactions |
/api/v1/gl/transactions/{id} | GET | Get transaction details |
/api/v1/gl/transactions/{id} | PUT | Update transaction |
/api/v1/gl/transactions/{id} | DELETE | Delete draft transaction |
Transaction Actions API
Control transaction status and posting.
Endpoint | Method | Purpose |
---|---|---|
/api/v1/gl/transactions/{id}/approve | POST | Approve for posting |
/api/v1/gl/transactions/{id}/post | POST | Post to GL |
/api/v1/gl/transactions/{id}/reverse | POST | Reverse posted transaction |
GL Reporting API
Generate financial reports and queries.
Endpoint | Method | Purpose |
---|---|---|
/api/v1/gl/reports/trial-balance | GET | Trial balance report |
/api/v1/gl/reports/account-activity | GET | Account activity ledger |
/api/v1/gl/reports/general-ledger | GET | General ledger entries |
/api/v1/gl/gl-transactions | GET | List GL transactions |
/api/v1/gl/gl-transactions/{id} | GET | GL transaction details |
Getting Started
1. Authentication
All GL API endpoints require authentication with organization context:
curl -H "x-stytch-organization-id: your-org-id" \
-H "Authorization: Bearer your-token" \
https://api.example.com/api/v1/gl/transactions
2. Create Your First Transaction
curl -X POST https://api.example.com/api/v1/gl/transactions \
-H "Content-Type: application/json" \
-H "x-stytch-organization-id: your-org-id" \
-d '{
"transaction": {
"transactionTypeId": "invoice-type-id",
"subsidiaryId": "main-subsidiary-id",
"entityId": "customer-id",
"entityType": "CUSTOMER",
"transactionDate": "2025-06-03",
"currencyCode": "USD",
"status": "DRAFT"
},
"lines": [
{
"lineNumber": 1,
"lineType": "SERVICE",
"description": "Consulting services",
"quantity": "10.0",
"unitPrice": "150.00",
"lineAmount": "1500.00"
}
]
}'
3. Post to General Ledger
# First approve the transaction
curl -X POST https://api.example.com/api/v1/gl/transactions/{id}/approve \
-H "x-stytch-organization-id: your-org-id"
# Then post to GL
curl -X POST https://api.example.com/api/v1/gl/transactions/{id}/post \
-H "x-stytch-organization-id: your-org-id"
4. Generate Reports
# Get trial balance
curl "https://api.example.com/api/v1/gl/reports/trial-balance?periodId=current-period" \
-H "x-stytch-organization-id: your-org-id"
# Get account activity
curl "https://api.example.com/api/v1/gl/reports/account-activity?accountId=cash-account&dateFrom=2025-06-01&dateTo=2025-06-30" \
-H "x-stytch-organization-id: your-org-id"
Data Models
Business Transaction
The core commercial document containing header and line information:
interface BusinessTransaction {
id: string;
transactionNumber: string;
transactionTypeId: string;
subsidiaryId: string;
entityId?: string;
entityType?: 'CUSTOMER' | 'VENDOR' | 'EMPLOYEE';
transactionDate: string;
currencyCode: string;
totalAmount: string;
status: TransactionStatus;
lines: BusinessTransactionLine[];
}
GL Transaction
The accounting journal entry generated from business transactions:
interface GlTransaction {
id: string;
transactionNumber: string;
subsidiaryId: string;
transactionDate: string;
postingDate: string;
periodId: string;
transactionType: 'JOURNAL' | 'POSTING' | 'REVERSAL' | 'CLOSING';
totalDebitAmount: string;
totalCreditAmount: string;
status: 'DRAFT' | 'PENDING' | 'POSTED' | 'REVERSED';
lines: GlTransactionLine[];
}
Account Balance
Real-time and period account balances:
interface AccountBalance {
accountId: string;
subsidiaryId: string;
periodId: string;
currencyCode: string;
beginningBalanceDebit: string;
beginningBalanceCredit: string;
periodDebitAmount: string;
periodCreditAmount: string;
endingBalanceDebit: string;
endingBalanceCredit: string;
}
Security and Access Control
Organization Isolation
- All data is automatically filtered by organization context
- Users can only access their organization's data
- API keys are scoped to specific organizations
Role-Based Permissions
- Transaction Entry: Create and modify draft transactions
- Transaction Approval: Approve transactions for posting
- GL Posting: Post approved transactions to the general ledger
- Financial Reporting: Access to financial reports and GL queries
Audit Trail
- All transaction changes are logged with user and timestamp
- GL postings cannot be deleted, only reversed
- Complete audit trail for financial compliance
Best Practices
Transaction Design
- Use Descriptive Line Items: Include detailed descriptions for audit purposes
- Apply Dimensions: Use class, department, and location for segment reporting
- Validate Amounts: Ensure all transactions balance before posting
- Follow Status Workflow: Respect the defined approval process
Performance Optimization
- Batch Operations: Group related transactions for efficiency
- Use Pagination: Apply appropriate page sizes for large queries
- Filter Effectively: Use date ranges and dimension filters
- Cache Reference Data: Cache account, customer, and subsidiary data
Error Handling
- Validate Input: Use proper validation before API calls
- Handle Status Conflicts: Check transaction status before operations
- Retry Logic: Implement retry for transient failures
- Graceful Degradation: Handle partial failures appropriately
Integration Examples
TypeScript/JavaScript
import { GlTransactionService, GlReportingService } from '@glapi/api-service';
class FinancialOperations {
private transactionService: GlTransactionService;
private reportingService: GlReportingService;
constructor(context: { organizationId: string; userId: string }) {
this.transactionService = new GlTransactionService(context);
this.reportingService = new GlReportingService(context);
}
async createAndPostInvoice(invoiceData: any) {
// Create the invoice
const transaction = await this.transactionService.createBusinessTransaction({
transaction: invoiceData.header,
lines: invoiceData.lines
});
// Approve if auto-approval is enabled
if (invoiceData.autoApprove) {
await this.transactionService.approveTransaction({
transactionId: transaction.id
});
}
// Post to GL if approved
if (transaction.status === 'APPROVED') {
await this.transactionService.postTransaction({
transactionId: transaction.id
});
}
return transaction;
}
async generateMonthEndReports(periodId: string) {
const [trialBalance, glTransactions] = await Promise.all([
this.reportingService.getTrialBalance({ periodId }),
this.reportingService.listGlTransactions({ page: 1, limit: 1000 }, { periodId })
]);
return {
trialBalance,
transactionCount: glTransactions.total,
isBalanced: Math.abs(trialBalance.totals.difference) < 0.01
};
}
}
Python Integration
import requests
from typing import Dict, List, Optional
class GLAPIClient:
def __init__(self, base_url: str, org_id: str, auth_token: str):
self.base_url = base_url
self.headers = {
'Content-Type': 'application/json',
'x-stytch-organization-id': org_id,
'Authorization': f'Bearer {auth_token}'
}
def create_transaction(self, transaction_data: Dict) -> Dict:
response = requests.post(
f'{self.base_url}/api/v1/gl/transactions',
json=transaction_data,
headers=self.headers
)
response.raise_for_status()
return response.json()
def get_trial_balance(self, period_id: str, subsidiary_id: Optional[str] = None) -> Dict:
params = {'periodId': period_id}
if subsidiary_id:
params['subsidiaryId'] = subsidiary_id
response = requests.get(
f'{self.base_url}/api/v1/gl/reports/trial-balance',
params=params,
headers=self.headers
)
response.raise_for_status()
return response.json()
# Usage example
client = GLAPIClient('https://api.example.com', 'your-org-id', 'your-token')
# Create an invoice
invoice = client.create_transaction({
'transaction': {
'transactionTypeId': 'invoice-type',
'entityId': 'customer-123',
'transactionDate': '2025-06-03',
'currencyCode': 'USD',
'status': 'DRAFT'
},
'lines': [
{
'lineNumber': 1,
'lineType': 'SERVICE',
'description': 'Consulting',
'quantity': '10.0',
'unitPrice': '100.00',
'lineAmount': '1000.00'
}
]
})
# Get trial balance
trial_balance = client.get_trial_balance('current-period')
print(f"Trial balance difference: {trial_balance['totals']['difference']}")
Support and Resources
Documentation
- GL Transactions API - Business transaction management
- GL Reports API - Financial reporting and queries
- Authentication - API authentication and authorization
Common Use Cases
- Revenue Recognition: Automated posting of sales transactions
- Expense Management: Purchase order and vendor invoice processing
- Financial Reporting: Month-end and year-end report generation
- Audit Preparation: Transaction trails and account reconciliation
Rate Limits
- Transaction Creation: 100 requests per minute
- Reporting Queries: 500 requests per minute
- GL Queries: 200 requests per minute
For higher limits or enterprise features, contact our support team.