Appearance
Receipt Vouchers
Returns Tally Receipt vouchers built from paid invoices. Each paid invoice produces exactly one receipt voucher recording the cash inflow.
A Receipt voucher is the cash counterpart to a Sales voucher. The same invoice produces both, and they are recorded independently.
Endpoint
| Method | URL |
|---|---|
GET | /tally/receipt |
No query parameters. Returns every unrecorded receipt voucher in one response, sorted by paid date ascending.
Filtering rules
- Only fully paid invoices are returned. Partially paid invoices are excluded.
- Already-recorded receipt vouchers are excluded.
There is no date range filter and no pagination.
Receipt recording vs Sales recording
Marking an invoice as Receipt-recorded does not mark it as Sales-recorded. They are independent.
Response schema
The response envelope is { status, data, message } (see Overview). The data field is an array of receipt voucher objects:
| Field | Type | Description |
|---|---|---|
voucherid | string | Stable unique ID for the voucher. Differs from the matching sales voucher's voucherid so they don't collide in Tally |
vouchernumber | string | Format RCPT-<invoiceNumber> |
vouchertypename | string | Always "Receipt" |
date | string | ISO 8601 timestamp of when the invoice was paid, or "" |
narration | string | Auto-generated description |
ledgers | Ledger[] | Always exactly two entries. See Ledger Object |
_internalMetadata | string | Opaque base64 blob. Pass back to POST /tally/record to mark this voucher as Receipt-recorded |
Ledger object
The two ledgers are positional. Ledger 1 is the client, ledger 2 is the receiving bank or cash account.
| Field | Type | Description |
|---|---|---|
ledgername | string | Client name (ledger 1) or payment account name (ledger 2) |
amount | number | Invoice grand total. Both ledgers carry the same value |
isdr | boolean | false on ledger 1, true on ledger 2 |
bills | Bill[] | Only present on ledger 1 |
costcentes | CostCenter[] | Only present on ledger 1, always [] |
bankdet | BankDetails[] | Only present on ledger 2. May be empty when no bank info is available, otherwise contains one entry |
Bill object
Inside ledgers[0].bills[]:
| Field | Type | Description |
|---|---|---|
nane | string | Invoice reference number. Note the field is spelled nane, not name. Preserved verbatim from the Tally schema |
amount | number | Invoice grand total |
Bank details object
Inside ledgers[1].bankdet[]:
| Field | Type | Description |
|---|---|---|
transactiontype | string | Always "" |
instrumentnumber | string | Always "" |
instrumentdate | string | Always "" |
bankname | string | Bank name |
accountnumber | string | Account number |
branchname | string | Branch name |
amount | number | Invoice grand total |
Example response
json
{
"status": "success",
"data": [
{
"voucherid": "R-65f1a2b3c4d5e6f7a8b9c0d3",
"vouchernumber": "RCPT-INV-04812",
"vouchertypename": "Receipt",
"date": "2026-04-05T11:20:00.000Z",
"narration": "Payment received for REF-2026-04-001 from Acme Logistics Ltd",
"ledgers": [
{
"ledgername": "Acme Logistics Ltd",
"amount": 1180000,
"isdr": false,
"bills": [
{ "nane": "REF-2026-04-001", "amount": 1180000 }
],
"costcentes": []
},
{
"ledgername": "CRDB Operating Account",
"amount": 1180000,
"isdr": true,
"bankdet": [
{
"transactiontype": "",
"instrumentnumber": "",
"instrumentdate": "",
"bankname": "CRDB Bank",
"accountnumber": "0150000000123",
"branchname": "Mlimani City",
"amount": 1180000
}
]
}
],
"_internalMetadata": "eyJ0IjoicmVjZWlwdCIsImlkIjoiNjVmMWEyYjNjNGQ1ZTZmN2E4YjljMGQzIn0="
}
],
"message": "Receipt vouchers fetched successfully"
}Example request
bash
curl -H "x-api-key: your-api-key-here" \
https://api.example.com/tally/receiptjs
const res = await fetch("https://api.example.com/tally/receipt", {
headers: {
"x-api-key": process.env.TALLY_API_KEY,
},
});
const { data: vouchers } = await res.json();Common mistakes
Confusing Receipt with Sales
Receipt vouchers represent money received. Sales vouchers represent revenue earned. The same invoice produces both, and they must be recorded independently.
Indexing into bankdet blindly
The bankdet array on ledger 2 may be empty when no bank info is available. Check the length before accessing the first element.