Expense Details API
curl --request GET \
--url https://api.pazy.io/v1.0/expense/:expenseIdimport requests
url = "https://api.pazy.io/v1.0/expense/:expenseId"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.pazy.io/v1.0/expense/:expenseId', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pazy.io/v1.0/expense/:expenseId",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.pazy.io/v1.0/expense/:expenseId"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.pazy.io/v1.0/expense/:expenseId")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pazy.io/v1.0/expense/:expenseId")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyExpense APIs
Expense Details API
Retrieve detailed information for a single expense including line items, taxes, merchant, and transaction data
Expense Details API
curl --request GET \
--url https://api.pazy.io/v1.0/expense/:expenseIdimport requests
url = "https://api.pazy.io/v1.0/expense/:expenseId"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.pazy.io/v1.0/expense/:expenseId', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pazy.io/v1.0/expense/:expenseId",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.pazy.io/v1.0/expense/:expenseId"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.pazy.io/v1.0/expense/:expenseId")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pazy.io/v1.0/expense/:expenseId")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyAuthentication
All requests require an API key in the request headers. Headers:Authorization: Api-Key YOUR_API_KEY
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
expenseId | string | Yes | The unique slug identifier of the expense |
Code Examples
curl -X GET https://api.pazy.io/v1.0/expense/expense_identifier \
-H "Authorization: Api-Key YOUR_API_KEY"
const response = await fetch('https://api.pazy.io/v1.0/expense/expense_identifier', {
method: 'GET',
headers: {
'Authorization': 'Api-Key YOUR_API_KEY'
}
});
const result = await response.json();
import requests
url = "https://api.pazy.io/v1.0/expense/expense_identifier"
headers = {
"Authorization": "Api-Key YOUR_API_KEY"
}
response = requests.get(url, headers=headers)
result = response.json()
Success Response
HTTP Status:200 OK
Response Fields:
| Field | Type | Description |
|---|---|---|
ok | boolean | Indicates whether the request was successful |
data | object | Contains the expense details |
data.id | string | Unique identifier (slug) for the expense |
data.expenseType | string | Type of the expense |
data.description | string | Description of the expense |
data.itemCount | number | Number of line items in the expense |
data.expenseDate | string | Date the expense was incurred (ISO 8601 format) |
data.dueDate | string | Due date for the expense (ISO 8601 format) |
data.accountingDate | string | Accounting date for the expense (ISO 8601 format) |
data.approvedDate | string | Date the expense was approved (ISO 8601 format) |
data.recipientId | string | Identifier of the payment recipient |
data.recipientType | string | Type of the payment recipient |
data.paymentDate | string | Date the expense was paid (ISO 8601 format) |
data.amount | number or string | Total amount of the expense |
data.currency | string | Currency code (e.g., INR) |
data.state | string | Current state of the expense. Possible values: DRAFTED, PENDING, APPROVED, OUT_OF_POLICY |
data.paymentState | string | Payment state of the expense |
data.amountPaid | number or string | Amount that has been paid against the expense |
data.dateCreated | string | Date the expense was created in the system (ISO 8601 format) |
data.remarks | string | Notes / remarks on the expense |
data.source | string | Source of the expense. Manual entries are returned as WEB; other possible values include EMAIL, SLACK |
data.syncedReferenceId | string | Reference identifier of the expense in the connected accounting platform |
data.documentId | string | Identifier of the source document, if any |
data.syncState | string | Synchronization state with the accounting system (e.g., SYNCED, NOT_SYNCED) |
data.syncMode | string | Synchronization mode for the expense |
data.accountingPlatform | string | Name of the connected accounting platform. Present only when an accounting integration is connected |
data.selfUrl | string | Shareable URL for viewing the expense in the web interface |
data.identifier | string | Human-readable identifier / number for the expense |
data.cardInfo | object | Card details if paid by card. Empty object if not applicable |
data.cardInfo.name | string | Card name |
data.cardInfo.slug | string | Card slug identifier |
data.cardInfo.maskedCardNumber | string | Masked card number |
data.cardInfo.description | string | Card description |
data.cardInfo.dateCreated | string | Date the card was created |
data.cardInfo.provider | string | Card provider |
data.transaction | object | Transaction details |
data.transaction.utr | string | Unique Transaction Reference (UTR) of the payment |
data.transaction.dateConfirmed | string | Date the transaction was confirmed |
data.transaction.narration | string | Bank narration for the transaction |
data.transaction.ledgerId | string or null | Ledger / instrument identifier the transaction is mapped to |
data.initiator | object | Details of the user who raised the expense |
data.initiator.slug | string | Unique slug identifier of the initiator |
data.initiator.name | string | Full name of the initiator |
data.initiator.email | string | Email address of the initiator |
data.merchant | object | Merchant details |
data.merchant.name | string or null | Merchant name |
data.merchant.vpa | string or null | Merchant VPA (UPI address) |
data.merchant.mcc | object | Merchant Category Code details. Present only when MCC data is available |
data.merchant.mcc.code | string or null | MCC code |
data.merchant.mcc.groupSlug | string or null | MCC group slug |
data.merchant.mcc.groupName | string or null | MCC group name |
data.merchant.mcc.groupDescription | string or null | MCC group description |
data.merchant.mcc.groupExtra | object or null | Additional MCC group metadata |
data.vendor | object | Linked vendor details. Empty object if no vendor is linked |
data.vendor.slug | string | Unique slug identifier of the vendor |
data.vendor.name | string | Vendor display name (falls back to legal name) |
data.vendor.email | string | Vendor email address |
data.lineItems | array | Line items on the expense |
data.lineItems[].id | string | Unique identifier of the line item |
data.lineItems[].description | string | Line item description |
data.lineItems[].amount | number | Total amount for the line item |
data.lineItems[].rate | number or null | Unit rate for the line item |
data.lineItems[].quantity | number or null | Quantity for the line item |
data.lineItems[].ledgerType | string or null | Ledger type mapped to the line item |
data.lineItems[].ledgerId | string or null | Ledger identifier mapped to the line item |
data.lineItems[].skuId | string or null | SKU identifier mapped to the line item |
data.lineItems[].trxTax | object | Transaction (e.g., GST) tax details for the line item |
data.lineItems[].trxTax.type | string | Tax type |
data.lineItems[].trxTax.amount | number | Tax amount |
data.lineItems[].trxTax.name | string | Tax name |
data.lineItems[].trxTax.deductionType | string or null | Tax deduction type |
data.lineItems[].trxTax.deductionValue | number or null | Tax deduction value |
data.lineItems[].trxTax.id | number or string or null | Tax identifier |
data.lineItems[].whtTax | object | Withholding (e.g., TDS) tax details for the line item |
data.lineItems[].whtTax.type | string | Withholding tax type |
data.lineItems[].whtTax.amount | number | Withholding tax amount |
data.lineItems[].whtTax.name | string | Withholding tax name |
data.lineItems[].whtTax.deductionType | string or null | Withholding deduction type |
data.lineItems[].whtTax.deductionValue | number or null | Withholding deduction value |
data.lineItems[].whtTax.id | number or string or null | Withholding tax identifier |
data.lineItems[].amountBreakdown | object | Computed amount breakdown for the line item |
data.lineItems[].amountBreakdown.subTotal | number | Amount before transaction tax |
data.lineItems[].amountBreakdown.grossTotal | number | Sub-total plus transaction tax |
data.lineItems[].amountBreakdown.netPayable | number | Gross total minus withholding tax |
data.processingStatus | object | Document-processing status. Present only when the expense was created from a document being processed |
data.processingStatus.processingId | string | Identifier of the processing job |
data.processingStatus.status | string | Current processing state |
data.processingStatus.isReady | boolean | Whether processing has completed and the data is ready |
Response Example
{
"ok": true,
"data": {
"id": "expense_identifier",
"expenseType": "GENERAL",
"description": "Team lunch",
"itemCount": 1,
"expenseDate": "2026-01-15",
"dueDate": "",
"accountingDate": "2026-01-15",
"approvedDate": "2026-01-16T09:00:00Z",
"recipientId": "merchant_identifier",
"recipientType": "MERCHANT",
"paymentDate": "2026-01-17T11:00:00Z",
"amount": 1500.00,
"currency": "INR",
"state": "APPROVED",
"paymentState": "PAID",
"amountPaid": 1500.00,
"dateCreated": "2026-01-15T10:30:00Z",
"remarks": "Approved by manager",
"source": "WEB",
"syncedReferenceId": "ACC-REF-001",
"documentId": "document_identifier",
"syncState": "SYNCED",
"syncMode": "AUTO",
"selfUrl": "https://app.pazy.io/p/expense/expense_identifier",
"identifier": "EXP-2026-001",
"cardInfo": {
"name": "John Doe",
"slug": "card_identifier",
"maskedCardNumber": "XXXX XXXX XXXX 1234",
"description": "Corporate Card",
"dateCreated": "2025-12-01T00:00:00Z",
"provider": "VISA"
},
"transaction": {
"utr": "123456789012",
"dateConfirmed": "2026-01-15T10:30:00Z",
"narration": "UPI/abc@bank/Team lunch",
"ledgerId": "ledger_identifier"
},
"initiator": {
"slug": "user_identifier",
"name": "John Doe",
"email": "john@example.com"
},
"merchant": {
"name": "ABC Restaurant",
"vpa": "abc@bank",
"mcc": {
"code": "5812",
"groupSlug": "food-and-dining",
"groupName": "Food & Dining",
"groupDescription": "Restaurants and eating places",
"groupExtra": null
}
},
"vendor": {
"slug": "vendor_identifier",
"name": "ABC Restaurant Pvt Ltd",
"email": "billing@abcrestaurant.com"
},
"lineItems": [
{
"id": "line_item_identifier",
"description": "Lunch",
"amount": 1500.00,
"rate": 1500.00,
"quantity": 1,
"ledgerType": "EXPENSE",
"ledgerId": "ledger_identifier",
"skuId": null,
"trxTax": {
"type": "GST",
"amount": 75.00,
"name": "GST 5%",
"deductionType": null,
"deductionValue": null,
"id": 132
},
"whtTax": {
"type": "TDS",
"amount": 0,
"name": "",
"deductionType": null,
"deductionValue": null,
"id": null
},
"amountBreakdown": {
"subTotal": 1425.00,
"grossTotal": 1500.00,
"netPayable": 1500.00
}
}
]
}
}
Error Responses
Missing Expense ID
HTTP Status:400 Bad Request
{
"ok": false,
"error": {
"code": "MISSING_REQUIRED_FIELD",
"message": "Expense ID is required"
}
}
Expense Not Found
HTTP Status:404 Not Found
{
"ok": false,
"error": {
"code": "EXPENSE_NOT_FOUND",
"message": "Expense not found"
}
}
Access Denied
HTTP Status:403 Forbidden
{
"ok": false,
"error": {
"code": "ACCESS_DENIED",
"message": "Access denied: You can only view vendors you own"
}
}
Authentication Errors
HTTP Status:401 Unauthorized
{
"ok": false,
"error": {
"code": "MISSING_CREDENTIALS",
"message": "Missing Credentials"
}
}
{
"ok": false,
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid API Key"
}
}
Permission Errors
HTTP Status:403 Forbidden
{
"ok": false,
"error": {
"code": "INSUFFICIENT_PERMISSIONS",
"message": "Permission check failed - PERMISSION_CHECK_FAILED"
}
}
Internal Error
HTTP Status:500 Internal Server Error
{
"ok": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal error"
}
}
Best Practices
- Use the
idreturned by the Expense List API as theexpenseIdpath parameter amountBreakdownis computed per line item:subTotalexcludes transaction tax,grossTotaladds it back, andnetPayablesubtracts withholding taxmerchant.mccandprocessingStatusare only present when the underlying data exists — guard for their absence- Access is limited to users with expense read permission and an admin or bookkeeper role
Was this page helpful?