Retrieve an expense report

Operation ID: getExpenseReport

Group: Accounting › Expense Reports

Open in the interactive reference

GET /accounting/expense-reports/{id}

Read-only: Reads and returns; changes nothing.

Retrieves an expense report. Use the report's id, not its expenseNumber.

The response has the report's main fields and every expense item on it.

POST accounting/expense-reports/search returns the same record for each report. GET accounting/expense-reports returns the main fields only.

The report totals are in reimbursementCurrency, and each item's amount is in the item's own currency.

Parameters

Name In Type Required Description
Api-Version header string · v1 yes The API version this request targets, named by its public identifier. Required on every request; omitting it, or naming a version this company does not have, is answered with 400. This document describes version v1.
id path string yes The unique identifier of the expense report you want to retrieve. Example: "3f8c5a91-7b2e-4d16-9c4a-8e1f2b6d5307".

Response

200 Success

Under data (getExpenseReportOutput):

Field Type Required Description
id string yes The unique identifier for the expense report.
expenseNumber string no The expense number. Absent until one has been assigned.
status string yes The approval status of the report. Values include 'draft', 'pendingApproval', 'approved', 'rejected' and 'paid'.
paymentStatus string no The payment status of the report. Absent until a payment run has touched it.
submittedDate date no The date the employee submitted the report for approval. Format YYYY-MM-DD. Absent while the report is still a draft.
reimbursementCurrency string yes The currency the report is reimbursed in. Format ISO 4217, for example 'USD'. Governs every header total below.
reimbursableTotal decimal no The total reimbursable amount across the report's items, in reimbursementCurrency.
reimbursableTotalNetAmount decimal no The total reimbursable amount excluding VAT, in reimbursementCurrency.
amountPaid decimal no The amount already reimbursed to the employee, in reimbursementCurrency.
openAmount decimal no The amount still owed to the employee, reimbursableTotal minus amountPaid, in reimbursementCurrency.
pendingAmount decimal no The amount committed to an in-flight payment run but not yet paid, in reimbursementCurrency.
containsBillableItem boolean no Whether at least one item on the report is marked billable to a customer.
markAsPaid boolean no Whether the report was flagged as paid without going through a payment run.
pendingPayment boolean no Whether a payment for this report is in flight.
skipJournalEntry boolean no Whether the report is configured not to post a journal entry.
reviewMessage string no The reviewer's note left on approval or rejection.
externalUrl string no A link to the report in the upstream system that produced it.
externalExpenseReportId string no The identifier this report has in the upstream system that produced it. It is not unique.
origin string no The source system this report came from, as free-form text.
employeeId string no The employee the report belongs to. See id on GET people/person/:id.
employeeName string no The name of the employee the report belongs to.
entityId string no The legal entity the report is posted under. See id on GET base/entities.
entityName string no The name of the legal entity the report is posted under.
departmentId string no The department the report is charged to. See id on GET people/departments/:id.
offsetAccountId string no The GL offset account for the reimbursement. See id on GET accounting/accounts/:id.
lastModifiedDate date-time yes The date and time the expense report last changed, in UTC. Format YYYY-MM-DDTHH:mm:ss.sssZ.
approvals array<object> no The approval decisions on this report, oldest first. An empty array when no approval policy has matched the report.
approvals[].decision string yes What was decided. Values include 'approve' and 'reject'.
approvals[].employeeName string no The name of the employee who decided.
approvals[].message string no The reviewer's note, where one was given.
approvals[].decidedAt date-time yes The date and time the decision was recorded, in UTC. Format YYYY-MM-DDTHH:mm:ss.sssZ.
expenseItems array<object> no The expense items on the report, in their order on it. An empty array when the report has none.
expenseItems[].id string yes The unique identifier for the expense item.
expenseItems[].itemNumber string no The expense item number.
expenseItems[].merchant string no The merchant the expense was incurred with.
expenseItems[].billDate date no The date the expense was incurred. Format YYYY-MM-DD.
expenseItems[].expenseType string no The kind of expense. Values include 'Pur' (purchase), 'Dis' (distance traveled) and 'PerDiem'.
expenseItems[].description string no A description of the expense item.
expenseItems[].amount decimal no The amount of the expense item, as a decimal in the item's own currency.
expenseItems[].currency string no The currency this item's amount is in. Format ISO 4217, for example 'USD'. May differ from the report's reimbursementCurrency.
expenseItems[].reimbursable boolean no Whether this item is reimbursable to the employee.
expenseItems[].categoryId string no The expense category the item is booked to. See id on GET accounting/expense-categories/:id.
expenseItems[].externalExpenseItemId string no The identifier this item has in the upstream system that produced it.
expenseItems[].attendees string no Who attended, when the item's category requires it.
expenseItems[].attachments array<object> no The receipts on this item.
expenseItems[].attachments[].id string yes The unique identifier for the attachment record.
expenseItems[].attachments[].fileName string no The display name of the attached file.
expenseItems[].attachments[].fileId string no The identifier of the stored file. There is no endpoint for it.
expenseItems[].amortizationSchedules array<object> no The amortization schedules this item is deferred over, one per accounting book. Absent when the item is not amortized. An expense item has no line type, so what makes it amortizable is its account: the category or account it books to must be a prepaid-expenses account. Read the scheduled installments with GET accounting/amortization-schedule-lines, filtering on amortizationScheduleHeaderId.
expenseItems[].amortizationSchedules[].id string yes The unique identifier for the amortization schedule. Pass it as amortizationScheduleHeaderId to GET accounting/amortization-schedule-lines to read its installments.
expenseItems[].amortizationSchedules[].bookId string no The accounting book this schedule posts into. It is what distinguishes the entries of this array. See id on GET accounting/books/:id.
expenseItems[].amortizationSchedules[].bookName string no The name of the accounting book this schedule posts into.
expenseItems[].amortizationSchedules[].status string no How far the schedule has progressed. Values include 'notStarted', 'inProgress', 'completed' and 'voided'. A schedule created alongside an unposted report reads 'notStarted' until the report posts.
expenseItems[].amortizationSchedules[].amortizationMethod string no How the schedule spreads its total. Values include 'exactDays', 'pointInTime', 'straightLine', 'straightLineProRateFirstLast' and 'usageBased'.
expenseItems[].amortizationSchedules[].amortizationStartDate date no The first day the schedule amortizes over. Format YYYY-MM-DD.
expenseItems[].amortizationSchedules[].amortizationEndDate date no The last day the schedule amortizes over, inclusive. Format YYYY-MM-DD.
expenseItems[].amortizationSchedules[].term decimal no The number of months the schedule spreads over. A count, not an amount, so it carries no currency.
expenseItems[].amortizationSchedules[].description string no The note recorded against the schedule, where one was given.
expenseItems[].amortizationSchedules[].deferredAccountId string no The general ledger account the deferred balance sits on until it is recognized. See id on GET accounting/accounts/:id.
expenseItems[].amortizationSchedules[].recognitionAccountId string no The general ledger account each installment recognizes the expense into. See id on GET accounting/accounts/:id. It is taken from the schedule's installments, so it is absent on a schedule that has none yet.
expenseItems[].amortizationSchedules[].totalRecognized decimal no The amount recognized so far across the schedule's posted installments, in this item's currency. Zero until the first installment posts.
{
  "data": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "expenseNumber": "<expenseNumber>",
    "status": "<status>",
    "paymentStatus": "<paymentStatus>",
    "submittedDate": "2026-01-15",
    "reimbursementCurrency": "<reimbursementCurrency>",
    "reimbursableTotal": "19.99",
    "reimbursableTotalNetAmount": "19.99",
    "amountPaid": "19.99",
    "openAmount": "19.99",
    "pendingAmount": "19.99",
    "containsBillableItem": true,
    "markAsPaid": true,
    "pendingPayment": true,
    "skipJournalEntry": true,
    "reviewMessage": "<reviewMessage>",
    "externalUrl": "<externalUrl>",
    "externalExpenseReportId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "origin": "<origin>",
    "employeeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "employeeName": "<employeeName>",
    "entityId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "entityName": "<entityName>",
    "departmentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "offsetAccountId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "lastModifiedDate": "2026-01-15T09:30:00.000Z",
    "approvals": [
      {
        "decision": "<decision>",
        "employeeName": "<employeeName>",
        "message": "<message>",
        "decidedAt": "2026-01-15T09:30:00.000Z"
      }
    ],
    "expenseItems": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "itemNumber": "<itemNumber>",
        "merchant": "<merchant>",
        "billDate": "2026-01-15",
        "expenseType": "<expenseType>",
        "description": "<description>",
        "amount": "19.99",
        "currency": "<currency>",
        "reimbursable": true,
        "categoryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "externalExpenseItemId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "attendees": "<attendees>",
        "attachments": [
          {
            "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "fileName": "<fileName>",
            "fileId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          }
        ],
        "amortizationSchedules": [
          {
            "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "bookId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "bookName": "<bookName>",
            "status": "<status>",
            "amortizationMethod": "<amortizationMethod>",
            "amortizationStartDate": "2026-01-15",
            "amortizationEndDate": "2026-01-15",
            "term": "19.99",
            "description": "<description>",
            "deferredAccountId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "recognitionAccountId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "totalRecognized": "19.99"
          }
        ]
      }
    ]
  },
  "diagnostics": [
    {
      "code": "<code>",
      "message": "<message>",
      "severity": "error",
      "path": [
        "<path>"
      ],
      "details": "<details>"
    }
  ]
}

Errors

Code Status
NOT_FOUND 400

Statuses