Beetles Docs

Small Business Accounting

Monthly invoicing, tax payments, and bank reconciliation for low-volume operations.

Small Business Accounting

A common scenario for service companies: one invoice per month, one receipt, tax obligations, and a need to reconcile bank statements against internal accounting records.

This model uses Beetles as the internal accounting engine — all monetary events (invoicing, receipts, tax payments) are recorded as immutable double-entry transfers, making reconciliation with your bank trivial.

Entity Structure

A single ledger with purpose-specific accounts:

AccountCodePurpose
@world9999External boundary (bank, clients, government)
Accounts Receivable1100Outstanding invoices awaiting payment
Revenue4000Recognized service revenue
Cash1000Bank account mirror — reconciles against statement
Tax Payable (ISS)2100Municipal service tax obligation
Tax Payable (IR)2200Income tax withholding
Tax Payable (PIS/COFINS)2300Federal contributions
Operating Expenses5000General operating costs

The @world account represents everything outside your books — your clients paying you, the bank receiving deposits, and the government collecting taxes.

Visual Flow

The monthly cycle: Invoice → Receipt → Tax Payment → Reconciliation.

Implementation

Create the Ledger and Accounts

POST /v1/ledgers
{
  "name": "Accounting - 2026"
}

Then create each account. The @world account is automatic. For the others:

POST /v1/ledgers/{id}/accounts
{
  "name": "Accounts Receivable",
  "code": 1100
}

Repeat for Cash (1000), Revenue (4000), Tax Payable (ISS) (2100), Tax Payable (IR) (2200), Tax Payable (PIS/COFINS) (2300), and Operating Expenses (5000).

Record Monthly Invoice (NFS-e Emitted)

When you issue the invoice, record the receivable and the revenue simultaneously:

POST /v1/transfers — Invoice Receivable
{
  "ledger_id": "...",
  "debit_account_id": "@world_id",
  "credit_account_id": "accounts_receivable_id",
  "amount": 1000000,
  "code": 1,
  "metadata": {
    "nfse_number": "2026-001",
    "client": "ACME Corp",
    "competence": "2026-01",
    "description": "Consulting services - Jan/2026"
  }
}
POST /v1/transfers — Revenue Recognition
{
  "ledger_id": "...",
  "debit_account_id": "@world_id",
  "credit_account_id": "revenue_id",
  "amount": 1000000,
  "code": 2,
  "metadata": {
    "nfse_number": "2026-001",
    "type": "revenue_recognition"
  }
}

Record Payment Received

When the client pays, move from Receivable to Cash:

POST /v1/transfers — Payment Receipt
{
  "ledger_id": "...",
  "debit_account_id": "accounts_receivable_id",
  "credit_account_id": "cash_id",
  "amount": 1000000,
  "code": 3,
  "metadata": {
    "nfse_number": "2026-001",
    "bank_reference": "PIX-2026-01-15-ABC",
    "payment_date": "2026-01-15"
  }
}

The bank_reference metadata field is your reconciliation anchor — match it against your bank statement line.

Record Tax Obligations

Book the tax liabilities from revenue:

POST /v1/transfers — ISS (5%)
{
  "ledger_id": "...",
  "debit_account_id": "revenue_id",
  "credit_account_id": "tax_iss_id",
  "amount": 50000,
  "code": 10,
  "metadata": { "tax": "ISS", "rate": "5%", "competence": "2026-01" }
}
POST /v1/transfers — IRPJ (15%)
{
  "ledger_id": "...",
  "debit_account_id": "revenue_id",
  "credit_account_id": "tax_ir_id",
  "amount": 150000,
  "code": 11,
  "metadata": { "tax": "IRPJ", "rate": "15%", "competence": "2026-01" }
}
POST /v1/transfers — PIS/COFINS (3.65%)
{
  "ledger_id": "...",
  "debit_account_id": "revenue_id",
  "credit_account_id": "tax_pis_cofins_id",
  "amount": 36500,
  "code": 12,
  "metadata": { "tax": "PIS/COFINS", "rate": "3.65%", "competence": "2026-01" }
}

Record Tax Payments (DAS/DARF)

When you actually pay the taxes, reduce the liability and Cash:

POST /v1/transfers — Pay ISS
{
  "ledger_id": "...",
  "debit_account_id": "tax_iss_id",
  "credit_account_id": "@world_id",
  "amount": 50000,
  "code": 20,
  "metadata": { "darf_number": "DARF-2026-01-ISS", "payment_date": "2026-02-20" }
}

And the corresponding bank debit:

POST /v1/transfers — Bank Debit for Taxes
{
  "ledger_id": "...",
  "debit_account_id": "cash_id",
  "credit_account_id": "@world_id",
  "amount": 236500,
  "code": 21,
  "metadata": { "type": "tax_payment_batch", "competence": "2026-01" }
}

Reconciliation

Bank reconciliation becomes a simple query. Your Cash account's balance in Beetles should match your bank statement:

Check Cash balance
curl /v1/accounts/{cash_id}/balance
Expected Response
{
  "account_id": "...",
  "balance": 763500,
  "credits_posted": 1000000,
  "debits_posted": 236500
}

If the balance matches your bank statement ($10,000 received − $2,365 taxes = $7,635), the month is reconciled. ✅

For discrepancies, use the transfer history:

List all Cash account movements
curl /v1/transfers?account_id={cash_id}

Each transfer has bank_reference or darf_number in its metadata, making it straightforward to match against bank statement lines.

Key Benefits

  • Immutable audit trail: Every invoice, receipt, and tax payment is a permanent, timestamped ledger entry.
  • Natural double-entry: Debits always equal credits — your books are balanced by construction, not by hope.
  • Metadata-driven reconciliation: bank_reference, nfse_number, and darf_number fields link ledger entries to external documents.
  • Low-volume friendly: This model works perfectly for 5–50 transfers/month — no batch infrastructure needed.
  • Tax-ready: Each tax type has its own account, making tax reporting a simple balance query.

On this page