Skip to main content

What is the Ledger?

The Ledger is Owem’s accounting layer — the only source of truth for balances, reconciliations, and audits. Each financial movement generates an entry in the Ledger:
  • credit: money coming into the account (PIX IN)
  • debit: money going out of the account (PIX OUT)
No balance is changed directly. Every change occurs by creating a new entry in the Ledger.

Why Use the Ledger?

BenefitDescription
ImmutabilityEntries are not altered after creation
TraceabilityEvery operation has clear, auditable cause
ReconciliationBalances are always consistent
TransparencyEach credit/debit has documented origin

Available Queries

1. List Movements

curl -X GET "https://api.owem.com.br/v4/i/ledger?type=credit&status=succeeded&page=1&limit=50" \
  -u "API_KEY:API_SECRET"
Available filters:
ParameterDescription
typecredit or debit
reasonEx: pix_in:qrcode_paid, pix_out:processing
statusprocessing, succeeded, failed
startDateStart timestamp (ms)
endDateEnd timestamp (ms)
pagePage (default: 1)
limitItems per page (max: 100)

2. Search by externalId (Your Identifier)

Ideal for reconciliation when you use your own ID:
curl -X GET "https://api.owem.com.br/v4/i/ledger/external-id/{your_id}" \
  -u "API_KEY:API_SECRET"

3. Search by endToEndId (PIX Identifier)

To track by PIX E2E code:
curl -X GET "https://api.owem.com.br/v4/i/ledger/end-to-end/{e2eId}" \
  -u "API_KEY:API_SECRET"

4. Search by entryId/txId (QR Code ID)

To confirm QR Code payments:
curl -X GET "https://api.owem.com.br/v4/i/ledger/entry-id/{txId}" \
  -u "API_KEY:API_SECRET"
The txId returned when creating the QR is the same as entryId in the Ledger.

Reconciliation Flow

Daily Reconciliation

Example: PIX IN Reconciliation

// Fetch all PIX IN from previous day
const yesterday = Date.now() - 86400000
const today = Date.now()

const response = await fetch(
  `https://api.owem.com.br/v4/i/ledger?` +
    `type=credit&` +
    `reason=pix_in:qrcode_paid&` +
    `status=succeeded&` +
    `startDate=${yesterday}&` +
    `endDate=${today}&` +
    `limit=100`,
  {
    headers: {
      Authorization: `Basic ${btoa("API_KEY:API_SECRET")}`,
    },
  }
)

const { data, pagination } = await response.json()

for (const entry of data) {
  await reconcileEntry({
    id: entry.id,
    amount: entry.netAmount,
    endToEndId: entry.endToEndId,
    entryId: entry.entryId,
    createdAt: entry.createdAt,
  })
}

// If there are more pages, continue
if (pagination.page < pagination.totalPages) {
  // Fetch next page
}

Entry Structure

{
  "id": "E123456789...",
  "type": "credit",
  "reason": "pix_in:qrcode_paid",
  "status": "succeeded",
  "grossAmount": 100.0,
  "feeAmount": 0.15,
  "netAmount": 99.85,
  "endToEndId": "E123456789...",
  "entryId": "abc123def...",
  "externalId": "ORDER-001",
  "accountId": "123456789012",
  "userId": "usr_abc123",
  "createdAt": 1766523042000,
  "createdDate": "2025-12-24",
  "payer": {
    "name": "JOHN DOE",
    "cpfCnpj": "12345678900"
  },
  "receiver": {
    "name": "MY COMPANY"
  }
}

Important Fields

FieldDescription
idUnique entry identifier
typecredit (incoming) or debit (outgoing)
reasonAccounting reason (ex: pix_in:qrcode_paid)
statusprocessing, succeeded, failed
grossAmountGross amount
feeAmountFee charged
netAmountNet amount (gross - fee or gross + fee)
endToEndIdPIX E2E identifier
entryIdQR Code ID (PIX IN)
externalIdYour identifier (if sent)

Reasons

ReasonTypeDescription
pix_in:qrcode_paidcreditQR Code payment
pix_in:creditedcreditCredit via PIX key
pix_out:processingdebitPIX OUT sent
pix_in:refunded_processingdebitPIX IN refund
pix_out:refunded_processingcreditPIX OUT return

Best Practices

Always send your identifier in operations. Makes reconciliation much easier.
Run reconciliation routines at least once a day.
Entries in processing are not yet finalized. Check again later.
In case of support, requestId helps track issues quickly.

Next Steps