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.

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.

EndpointMethodPurpose
/api/v1/gl/transactionsPOSTCreate new business transaction
/api/v1/gl/transactionsGETList business transactions
/api/v1/gl/transactions/{id}GETGet transaction details
/api/v1/gl/transactions/{id}PUTUpdate transaction
/api/v1/gl/transactions/{id}DELETEDelete draft transaction

Transaction Actions API

Control transaction status and posting.

EndpointMethodPurpose
/api/v1/gl/transactions/{id}/approvePOSTApprove for posting
/api/v1/gl/transactions/{id}/postPOSTPost to GL
/api/v1/gl/transactions/{id}/reversePOSTReverse posted transaction

GL Reporting API

Generate financial reports and queries.

EndpointMethodPurpose
/api/v1/gl/reports/trial-balanceGETTrial balance report
/api/v1/gl/reports/account-activityGETAccount activity ledger
/api/v1/gl/reports/general-ledgerGETGeneral ledger entries
/api/v1/gl/gl-transactionsGETList GL transactions
/api/v1/gl/gl-transactions/{id}GETGL 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

  1. Use Descriptive Line Items: Include detailed descriptions for audit purposes
  2. Apply Dimensions: Use class, department, and location for segment reporting
  3. Validate Amounts: Ensure all transactions balance before posting
  4. Follow Status Workflow: Respect the defined approval process

Performance Optimization

  1. Batch Operations: Group related transactions for efficiency
  2. Use Pagination: Apply appropriate page sizes for large queries
  3. Filter Effectively: Use date ranges and dimension filters
  4. Cache Reference Data: Cache account, customer, and subsidiary data

Error Handling

  1. Validate Input: Use proper validation before API calls
  2. Handle Status Conflicts: Check transaction status before operations
  3. Retry Logic: Implement retry for transient failures
  4. 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

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.

Was this page helpful?