Appearance
Payment Vouchers
Returns Tally Payment vouchers for money sent out to suppliers. Both single-installment and multi-supplier payments appear in the same data array. They share vouchertypename: "Payment" but use slightly different voucherid formats and vouchernumber prefixes so you can tell them apart.
A Payment voucher is the cash counterpart to a Purchase voucher.
Endpoint
| Method | URL |
|---|---|
GET | /tally/payment |
No query parameters. Returns every unrecorded payment voucher in one response.
Filtering rules
- Pending and rejected source records are excluded.
- Already-recorded payment vouchers are excluded.
There is no date range filter and no pagination.
Multi-installment payments
A purchase that gets paid in multiple installments produces one voucher per installment. Recording one installment leaves the others untouched.
Multi-supplier purchases
A purchase that involves items from multiple suppliers produces one payment voucher per supplier. Recording one supplier's voucher leaves the others untouched.
Response schema
The response envelope is { status, data, message } (see Overview). The data field is an array of payment voucher objects.
Top-level fields
| Field | Type | Description |
|---|---|---|
voucherid | string | Stable unique ID for the voucher |
vouchernumber | string | Display number. Single-supplier payments use the PYMT-PR- prefix with an installment suffix (e.g. PYMT-PR-218-1 for the first installment, -2 for the second). Multi-supplier payments use the PYMT-PC- prefix |
vouchertypename | string | Always "Payment" |
date | string | ISO 8601 timestamp |
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 recorded |
Ledger object
The two ledgers are positional. Ledger 1 is the payment account, ledger 2 is the supplier.
| Field | Type | Description |
|---|---|---|
ledgername | string | Payment account name (ledger 1) or supplier name (ledger 2) |
amount | number | The amount paid in this voucher |
isdr | boolean | false on ledger 1, true on ledger 2 |
bankdet | BankDetails[] | Only present on ledger 1. May be empty when no bank info is available |
bills | Bill[] | Only present on ledger 2 |
costcentes | CostCenter[] | Only present on ledger 2, always [] |
Bank details object
Inside ledgers[0].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 | The amount paid |
Bill object
Inside ledgers[1].bills[]:
| Field | Type | Description |
|---|---|---|
nane | string | Bill reference. Note the field is spelled nane, not name. Preserved verbatim from the Tally schema |
amount | number | The supplier's full bill amount. May be larger than the ledger amount when this voucher is a partial payment against the bill |
nane.amount versus ledger.amount
On a partial payment, bills[0].amount is the supplier's full bill while ledgers[1].amount is just what was paid in this voucher. This is intentional and matches how Tally tracks "paid X of Y" against a bill reference.
Example response
This example shows two vouchers in the same response. The first uses the PYMT-PR- prefix, the second uses the PYMT-PC- prefix.
json
{
"status": "success",
"data": [
{
"voucherid": "65f1a2b3c4d5e6f7a8b9c0e1-0",
"vouchernumber": "PYMT-PR-218-1",
"vouchertypename": "Payment",
"date": "2026-04-03T15:45:00.000Z",
"narration": "Payment for PR-PR-2026-03-018 to Mwananchi Auto Workshop",
"ledgers": [
{
"ledgername": "CRDB Operating Account",
"amount": 826000,
"isdr": false,
"bankdet": [
{
"transactiontype": "",
"instrumentnumber": "",
"instrumentdate": "",
"bankname": "CRDB Bank",
"accountnumber": "0150000000123",
"branchname": "Mlimani City",
"amount": 826000
}
]
},
{
"ledgername": "Mwananchi Auto Workshop",
"amount": 826000,
"isdr": true,
"bills": [
{ "nane": "PR-PR-2026-03-018", "amount": 826000 }
],
"costcentes": []
}
],
"_internalMetadata": "eyJ0IjoicGF5bWVudCIsInMiOiJwciIsImlkIjoiNjVmMWEyYjNjNGQ1ZTZmN2E4YjljMGUxIiwicGkiOjB9"
},
{
"voucherid": "65f1a2b3c4d5e6f7a8b9c0f0-65f1a2b3c4d5e6f7a8b9c0f1",
"vouchernumber": "PYMT-PC-PROC-2026-005-acmesupplies",
"vouchertypename": "Payment",
"date": "2026-04-08T09:15:00.000Z",
"narration": "Payment for PC-PROC-2026-005 to Acme Supplies",
"ledgers": [
{
"ledgername": "NMB Petty Cash",
"amount": 200000,
"isdr": false,
"bankdet": []
},
{
"ledgername": "Acme Supplies",
"amount": 200000,
"isdr": true,
"bills": [
{ "nane": "PC-PROC-2026-005-acmesupplies", "amount": 472000 }
],
"costcentes": []
}
],
"_internalMetadata": "eyJ0IjoicGF5bWVudCIsInMiOiJwcm9jdXJlbWVudCIsImlkIjoiNjVmMWEyYjNjNGQ1ZTZmN2E4YjljMGYwIiwic3VwIjoiNjVmMWEyYjNjNGQ1ZTZmN2E4YjljMGYxIn0="
}
],
"message": "Payment vouchers fetched successfully"
}In the second example, ledger 2's amount is 200000 (one item paid) while the bill reference shows 472000 (the supplier's full bill across all items). The remaining balance will appear as a separate payment voucher when the other items get paid.
Example request
bash
curl -H "x-api-key: your-api-key-here" \
https://api.example.com/tally/paymentjs
const res = await fetch("https://api.example.com/tally/payment", {
headers: {
"x-api-key": process.env.TALLY_API_KEY,
},
});
const { data: vouchers } = await res.json();Common mistakes
Treating PYMT-PR and PYMT-PC vouchers identically
Both kinds share vouchertypename: "Payment" but use different voucherid formats and vouchernumber prefixes. Do not assume a fixed shape across all entries.
Multi-installment payments
A purchase paid in multiple installments produces multiple separate vouchers. The installment number is encoded in the vouchernumber suffix (e.g. -1, -2, -3). Recording one installment does not record the others.
Confusing amount with the bill amount
On partial payments, ledgers[1].amount is what was paid and bills[0].amount is the supplier's full bill. They are intentionally different.
Recording payment vouchers and assuming purchase vouchers are also done
Recording a payment voucher does not record the matching purchase voucher. They must be recorded independently.