Appearance
Sales Vouchers
Returns Tally Sales vouchers built from invoices. Each invoice produces exactly one sales voucher.
A Sales voucher records that revenue was earned. It does not record that money changed hands. That is what Receipt vouchers are for. The same invoice will appear here once and, after it is paid, also appear in the Receipt feed once. The two are recorded independently.
Endpoint
| Method | URL |
|---|---|
GET | /tally/sales |
No query parameters. Returns every unrecorded sales voucher in one response, sorted by invoice creation date ascending.
Filtering rules
- Already-recorded sales vouchers are excluded.
There is no date range filter and no pagination.
Sales recording vs Receipt recording
Marking an invoice as Sales-recorded does not mark it as Receipt-recorded. They are independent.
Response schema
The response envelope is { status, data, message } (see Overview). The data field is an array of sales voucher objects:
| Field | Type | Description |
|---|---|---|
voucherid | string | Stable unique ID for the voucher |
vouchernumber | string | The invoice number, falling back to voucherid if not set |
vouchertypename | string | Always "Sales" |
date | string | ISO 8601 timestamp, or "" |
reference | string | The invoice reference number, or "" |
narration | string | Auto-generated description |
address | string | Client address, or "" |
vatregistrationtype | string | "Regular" if the invoice has VAT, "Unregistered" otherwise |
statename | string | Client region name, or "" |
country | string | Always "Tanzania" |
partyledger | string | Client name, or "" |
partyalias | string | Always "" |
mailingname | string | Client name, or "" |
salestaxno | string | Client VAT registration number, or "" |
despatchdocumentno | string | Always "" |
despatchthrough | string | Truck name when applicable, otherwise "" |
destination | string | Always "" |
vehicleno | string | Truck name when applicable, otherwise "" |
PIN | string | Client tax ID, or "" |
bills | Bill[] | Always exactly one entry. See Bill Object |
ledgers | Ledger[] | One or two entries. See Ledger Object |
_internalMetadata | string | Opaque base64 blob. Pass back to POST /tally/record to mark this voucher as Sales-recorded |
Ledger object
The ledgers array always contains the revenue ledger, and optionally a VAT ledger:
| Field | Type | Description |
|---|---|---|
ledgername | string | "Transport Sales" for the revenue ledger, "VAT - OUTPUT 18%" for the VAT ledger |
amount | number | The ledger amount |
costcentes | CostCenter[] | Always [] for sales vouchers |
The VAT ledger only appears when the invoice has VAT. Iterate the array, do not assume a fixed length.
Bill object
The top-level bills array always contains exactly one entry:
| Field | Type | Description |
|---|---|---|
name | string | Invoice reference number, or "" |
amount | number | Invoice grand total |
Example response
json
{
"status": "success",
"data": [
{
"voucherid": "65f1a2b3c4d5e6f7a8b9c0d3",
"vouchernumber": "INV-04812",
"vouchertypename": "Sales",
"date": "2026-04-01T09:00:00.000Z",
"reference": "REF-2026-04-001",
"narration": "Sales invoice REF-2026-04-001 for Acme Logistics Ltd",
"address": "Plot 42, Nyerere Road",
"vatregistrationtype": "Regular",
"statename": "Dar es Salaam",
"country": "Tanzania",
"partyledger": "Acme Logistics Ltd",
"partyalias": "",
"mailingname": "Acme Logistics Ltd",
"salestaxno": "40-001234-X",
"despatchdocumentno": "",
"despatchthrough": "T 827 EEX",
"destination": "",
"vehicleno": "T 827 EEX",
"PIN": "123-456-789",
"bills": [
{ "name": "REF-2026-04-001", "amount": 1180000 }
],
"ledgers": [
{
"ledgername": "Transport Sales",
"amount": 1000000,
"costcentes": []
},
{
"ledgername": "VAT - OUTPUT 18%",
"amount": 180000,
"costcentes": []
}
],
"_internalMetadata": "eyJ0Ijoic2FsZXMiLCJpZCI6IjY1ZjFhMmIzYzRkNWU2ZjdhOGI5YzBkMyJ9"
}
],
"message": "Sales vouchers fetched successfully"
}Example request
bash
curl -H "x-api-key: your-api-key-here" \
https://api.example.com/tally/salesjs
const res = await fetch("https://api.example.com/tally/sales", {
headers: {
"x-api-key": process.env.TALLY_API_KEY,
},
});
const { data: vouchers } = await res.json();Common mistakes
Confusing Sales with Receipt
Sales vouchers represent revenue earned. Receipt vouchers represent money received. The same invoice produces both, and they must be recorded independently.
Missing the optional VAT ledger
The ledgers array contains the VAT ledger only when the invoice has VAT. Iterate the array, do not index a fixed position.