GraphQL Accounts

This page documents GraphQL operations for managing the chart of accounts in Crane Ledger.

Account Queries

Get Account by ID

Retrieve a specific account by its unique identifier.

query GetAccount($id: ID!) {
  account(id: $id) {
    id
    code
    name
    accountType
    status
    description
    isSystem
    parentAccountId
    createdAt
    updatedAt
    metadata
  }
}

Arguments:

  • id: ID! - Account unique identifier

Returns:

  • Complete account information
  • Account hierarchy (parent relationships)
  • System account flags

Get Account Balance

Retrieve the current balance for a specific account.

query GetAccountBalance($id: ID!) {
  account(id: $id) {
    id
    code
    name
    balance {
      amount
      currency {
        code
        name
        symbol
        decimalPlaces
      }
      formatted
    }
  }
}

Returns:

  • Current account balance
  • Currency information
  • Formatted display string

Get Account Transactions

Retrieve transactions that affect a specific account.

query GetAccountTransactions($id: ID!, $limit: Int) {
  account(id: $id) {
    id
    code
    name
    transactions(limit: $limit) {
      id
      description
      date
      amount
      status
      currency {
        code
        symbol
      }
      entries {
        accountId
        entryType
        amount
        description
        reference
      }
    }
  }
}

Arguments:

  • limit: Int - Maximum transactions to return (default: 50)

Returns:

  • Transactions affecting this account
  • Full journal entries for each transaction
  • Chronological order (newest first)

Organization Account Queries

List All Accounts

Get all accounts in the organization's chart of accounts.

query {
  organization {
    accounts {
      id
      code
      name
      accountType
      status
      description
      isSystem
      balance {
        formatted
      }
    }
  }
}

Filter Accounts by Type

Get accounts of specific types.

query GetAssetAccounts {
  organization {
    accounts(where: { accountType: { eq: ASSET } }) {
      id
      code
      name
      accountType
      balance {
        formatted
      }
    }
  }
}

query GetRevenueAccounts {
  organization {
    accounts(where: { accountType: { eq: REVENUE } }) {
      id
      code
      name
      accountType
      balance {
        formatted
      }
    }
  }
}

Get Active Accounts Only

Filter for currently active accounts.

query GetActiveAccounts {
  organization {
    accounts(where: { status: { eq: ACTIVE } }) {
      id
      code
      name
      accountType
      balance {
        formatted
      }
    }
  }
}

Account Mutations

Create Account

Add a new account to the chart of accounts.

mutation CreateAccount(
  $code: String!
  $name: String!
  $accountType: AccountType!
  $description: String
) {
  createAccount(
    code: $code
    name: $name
    accountType: $accountType
    description: $description
  ) {
    id
    code
    name
    accountType
    status
    description
    createdAt
  }
}

Required Fields:

  • code: Unique account code (e.g., "1001", "2001")
  • name: Account display name
  • accountType: Account classification

Optional Fields:

  • description: Account description

Account Type Options:

  • ASSET: Assets (balance sheet)
  • LIABILITY: Liabilities (balance sheet)
  • EQUITY: Equity (balance sheet)
  • REVENUE: Revenue (income statement)
  • EXPENSE: Expenses (income statement)

Update Account

Modify an existing account's properties.

mutation UpdateAccount(
  $id: ID!
  $code: String
  $name: String
  $description: String
) {
  updateAccount(
    id: $id
    code: $code
    name: $name
    description: $description
  ) {
    id
    code
    name
    description
    updatedAt
  }
}

Fields: Any combination of code, name, description

Restrictions:

  • Cannot change accountType after creation
  • Cannot modify system accounts
  • Account code must be unique within organization

Delete Account

Remove an account from the chart of accounts.

mutation DeleteAccount($id: ID!) {
  deleteAccount(id: $id)
}

Restrictions:

  • Account must not have any transactions
  • Cannot delete system accounts
  • Account must belong to your organization

Account Hierarchies

Parent-Child Relationships

Accounts can have hierarchical relationships for reporting.

query GetAccountHierarchy {
  organization {
    accounts {
      id
      code
      name
      parentAccountId
      balance {
        formatted
      }
    }
  }
}

Sub-Account Queries

Get child accounts for a parent account.

query GetSubAccounts($parentId: ID!) {
  organization {
    accounts(where: { parentAccountId: { eq: $parentId } }) {
      id
      code
      name
      balance {
        formatted
      }
    }
  }
}

Account Balances

Real-time Balance Queries

Account balances are calculated in real-time from transaction history.

query GetAccountBalances {
  organization {
    accounts(where: { status: { eq: ACTIVE } }) {
      id
      code
      name
      accountType
      balance {
        amount
        currency {
          code
          symbol
        }
        formatted
      }
    }
  }
}

Balance Sheet Accounts

Get all balance sheet accounts with their balances.

query GetBalanceSheetAccounts {
  organization {
    accounts(where: {
      accountType: { in: [ASSET, LIABILITY, EQUITY] }
    }) {
      id
      code
      name
      accountType
      balance {
        amount
        formatted
      }
    }
  }
}

Income Statement Accounts

Get all income statement accounts.

query GetIncomeStatementAccounts {
  organization {
    accounts(where: {
      accountType: { in: [REVENUE, EXPENSE] }
    }) {
      id
      code
      name
      accountType
      balance {
        amount
        formatted
      }
    }
  }
}

Account Validation

Account Code Standards

Account codes follow standard chart of accounts numbering:

// Asset accounts: 1000-1999
// Liability accounts: 2000-2999
// Equity accounts: 3000-3999
// Revenue accounts: 4000-4999
// Expense accounts: 5000-9999

const validateAccountCode = (code, accountType) => {
  const codeNum = parseInt(code);

  switch (accountType) {
    case 'ASSET':
      return codeNum >= 1000 && codeNum < 2000;
    case 'LIABILITY':
      return codeNum >= 2000 && codeNum < 3000;
    case 'EQUITY':
      return codeNum >= 3000 && codeNum < 4000;
    case 'REVENUE':
      return codeNum >= 4000 && codeNum < 5000;
    case 'EXPENSE':
      return codeNum >= 5000 && codeNum < 10000;
    default:
      return false;
  }
};

Account Name Standards

Account names should be descriptive and follow conventions:

const formatAccountName = (name, accountType) => {
  // Capitalize first letter of each word
  const capitalized = name.replace(/\b\w/g, l => l.toUpperCase());

  // Add account type suffix for clarity
  const typeSuffixes = {
    ASSET: 'Asset',
    LIABILITY: 'Liability',
    EQUITY: 'Equity',
    REVENUE: 'Revenue',
    EXPENSE: 'Expense'
  };

  return capitalized;
};

Account Status Management

Account Status Types

enum AccountStatus {
  ACTIVE      # Account is active and can be used
  INACTIVE    # Account is inactive but retains history
  SUSPENDED   # Account is temporarily suspended
}

Status Transitions

# Activate an account
mutation ActivateAccount($id: ID!) {
  updateAccount(id: $id, status: ACTIVE) {
    id
    status
  }
}

# Deactivate an account
mutation DeactivateAccount($id: ID!) {
  updateAccount(id: $id, status: INACTIVE) {
    id
    status
  }
}

System Accounts

Identifying System Accounts

System accounts are created automatically and cannot be modified.

query GetSystemAccounts {
  organization {
    accounts(where: { isSystem: { eq: true } }) {
      id
      code
      name
      accountType
      description
    }
  }
}

Common System Accounts:

  • Undeposited Funds (Asset)
  • Accounts Receivable (Asset)
  • Accounts Payable (Liability)
  • Retained Earnings (Equity)

Account Reporting

Account Summary Report

Generate a summary of all accounts with balances.

query GetAccountSummary {
  organization {
    accounts {
      id
      code
      name
      accountType
      status
      balance {
        amount
        formatted
      }
      transactions(limit: 1) {
        id
        date
      }
    }
  }
}

Account Activity Report

Get detailed transaction activity for accounts.

query GetAccountActivity($accountId: ID!) {
  account(id: $accountId) {
    id
    code
    name
    balance {
      formatted
    }
    transactions(limit: 100) {
      id
      description
      date
      amount
      status
      entries {
        entryType
        amount
        description
      }
    }
  }
}

Bulk Account Operations

Create Multiple Accounts

mutation CreateChartOfAccounts(
  $assets: [CreateAccountInput!]!
  $liabilities: [CreateAccountInput!]!
  $equity: [CreateAccountInput!]!
  $revenue: [CreateAccountInput!]!
  $expenses: [CreateAccountInput!]!
) {
  # Assets
  asset1: createAccount(input: $assets[0]) { id code name }
  asset2: createAccount(input: $assets[1]) { id code name }

  # Liabilities
  liability1: createAccount(input: $liabilities[0]) { id code name }

  # Equity
  equity1: createAccount(input: $equity[0]) { id code name }

  # Revenue
  revenue1: createAccount(input: $revenue[0]) { id code name }

  # Expenses
  expense1: createAccount(input: $expenses[0]) { id code name }
}

Error Handling

Account Creation Errors

  • VALIDATION_ERROR: Invalid account code format or type
  • CONFLICT: Account code already exists
  • FORBIDDEN: Insufficient permissions

Account Update Errors

  • NOT_FOUND: Account not found
  • VALIDATION_ERROR: Invalid account data
  • FORBIDDEN: Cannot modify system accounts

Account Deletion Errors

  • NOT_FOUND: Account not found
  • VALIDATION_ERROR: Account has transactions or is system account
  • FORBIDDEN: Insufficient permissions

Balance Query Errors

  • NOT_FOUND: Account not found
  • INTERNAL_ERROR: Balance calculation failed

Best Practices

Account Code Conventions

Follow standard accounting practices:

const ACCOUNT_CODE_RANGES = {
  ASSETS: { min: 1000, max: 1999 },
  LIABILITIES: { min: 2000, max: 2999 },
  EQUITY: { min: 3000, max: 3999 },
  REVENUE: { min: 4000, max: 4999 },
  EXPENSES: { min: 5000, max: 9999 }
};

const isValidAccountCode = (code, accountType) => {
  const numCode = parseInt(code);
  const range = ACCOUNT_CODE_RANGES[accountType];
  return range && numCode >= range.min && numCode <= range.max;
};

Account Naming

Use descriptive, consistent naming:

const formatAccountName = (baseName, accountType) => {
  // Remove extra spaces and capitalize
  const cleanName = baseName.trim().replace(/\s+/g, ' ');
  const capitalized = cleanName.split(' ')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
    .join(' ');

  return capitalized;
};

Account Maintenance

Regular account maintenance practices:

// Check for unused accounts
const findUnusedAccounts = async () => {
  const accounts = await getAllAccounts();
  const unused = [];

  for (const account of accounts) {
    const transactions = await getAccountTransactions(account.id, 1);
    if (transactions.length === 0) {
      unused.push(account);
    }
  }

  return unused;
};

Balance Verification

Regular balance verification:

const verifyAccountBalances = async () => {
  const accounts = await getAllAccounts();
  const imbalances = [];

  for (const account of accounts) {
    const balance = await getAccountBalance(account.id);
    const calculated = await calculateBalanceFromTransactions(account.id);

    if (Math.abs(balance.amount - calculated) > 0.01) {
      imbalances.push({
        account: account.code,
        expected: calculated,
        actual: balance.amount
      });
    }
  }

  return imbalances;
};

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.