Search expense reports

Operation ID: searchExpenseReport

Group: Accounting › Expense Reports

Open in the interactive reference

POST /accounting/expense-reports/search

Read-only: A read that takes its filters in the body. Changes nothing, and ignores Idempotency-Key.

Searches expense reports. Each match includes the report's main fields and its expense items. Results are returned newest first.

You can filter by employee or legal entity, by id or by name. GET accounting/expense-reports has none of these filters.

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.

Request body

Required, application/json: searchExpenseReportInput.

Field Type Required Description
filters object no The filters to apply. An expense report must match every filter you send. Omit to return all expense reports. Example: {"status":"pendingApproval"}.
filters.id string no Limits results to the expense report with this identifier.
filters.expenseNumber string no Limits results to reports with this expense number. It is not unique, so this can match several reports.
filters.employeeId string no Limits results to reports belonging to this employee, given as the employee id. See id on GET people/person/:id. An id that matches no employee yields an empty page, not an error.
filters.entityId string no Limits results to reports posted under this legal entity, given as the entity id. See id on GET base/entities. An id that matches no entity yields an empty page, not an error.
filters.employeeName string no Limits results to reports whose employee has this name. The match is exact and case-sensitive.
filters.entityName string no Limits results to reports whose legal entity has this name. The match is exact and case-sensitive.
filters.status string no Limits results to reports in this approval status. Values include 'draft', 'pendingApproval', 'approved', 'rejected' and 'paid'. Any other value matches no report.
filters.paymentStatus string no Limits results to reports in this payment status. Any other value matches no report.
filters.externalExpenseReportId string no Limits results to reports with this upstream identifier. It is not unique, so this can match several reports.
page object no Pagination controls. Omit for the first page. Example: {"size":50}.
page.cursor string no The cursor from the previous response's pagination.nextCursor. Omit for the first request.
page.size number no The number of expense reports per page. Defaults to 50. A value above 200 is treated as 200, not rejected.
{
  "filters": {
    "status": "pendingApproval"
  },
  "page": {
    "size": 50
  }
}

Response

200 Success

Under data (searchExpenseReportOutput):

Field Type Required Description
items array<object> yes The expense reports that match, most recently created first. An empty array when nothing matches.
items[].id string yes The unique identifier for the expense report.
items[].expenseNumber string no The expense number. Absent until one has been assigned.
items[].status string yes The approval status of the report. Values include 'draft', 'pendingApproval', 'approved', 'rejected' and 'paid'.
items[].paymentStatus string no The payment status of the report. Absent until a payment run has touched it.
items[].submittedDate date no The date the employee submitted the report for approval. Format YYYY-MM-DD.
items[].reimbursementCurrency string yes The currency the report is reimbursed in. Format ISO 4217, for example 'USD'. Governs every header total below.
items[].reimbursableTotal decimal no The total reimbursable amount across the report's items, in reimbursementCurrency.
items[].reimbursableTotalNetAmount decimal no The total reimbursable amount excluding VAT, in reimbursementCurrency.
items[].amountPaid decimal no The amount already reimbursed to the employee, in reimbursementCurrency.
items[].openAmount decimal no The amount still owed to the employee, reimbursableTotal minus amountPaid, in reimbursementCurrency.
items[].pendingAmount decimal no The amount committed to an in-flight payment run but not yet paid, in reimbursementCurrency.
items[].containsBillableItem boolean no Whether at least one item on the report is marked billable to a customer.
items[].markAsPaid boolean no Whether the report was flagged as paid without going through a payment run.
items[].pendingPayment boolean no Whether a payment for this report is in flight.
items[].skipJournalEntry boolean no Whether the report is configured not to post a journal entry.
items[].reviewMessage string no The reviewer's note left on approval or rejection.
items[].externalUrl string no A link to the report in the upstream system that produced it.
items[].externalExpenseReportId string no The identifier this report has in the upstream system that produced it. It is not unique.
items[].origin string no The source system this report came from, as free-form text.
items[].employeeId string no The employee the report belongs to. See id on GET people/person/:id.
items[].employeeName string no The name of the employee the report belongs to.
items[].entityId string no The legal entity the report is posted under. See id on GET base/entities.
items[].entityName string no The name of the legal entity the report is posted under.
items[].departmentId string no The department the report is charged to. See id on GET people/departments/:id.
items[].offsetAccountId string no The GL offset account for the reimbursement. See id on GET accounting/accounts/:id.
items[].lastModifiedDate date-time yes The date and time the expense report last changed, in UTC. Format YYYY-MM-DDTHH:mm:ss.sssZ.
items[].expenseItems array<object> no The expense items on the report, in their order on it. An empty array when the report has none.
items[].expenseItems[].id string yes The unique identifier for the expense item.
items[].expenseItems[].itemNumber string no The expense item number.
items[].expenseItems[].merchant string no The merchant the expense was incurred with.
items[].expenseItems[].billDate date no The date the expense was incurred. Format YYYY-MM-DD.
items[].expenseItems[].expenseType string no The kind of expense. Values include 'Pur' (purchase), 'Dis' (distance traveled) and 'PerDiem'.
items[].expenseItems[].description string no A description of the expense item.
items[].expenseItems[].amount decimal no The amount of the expense item, as a decimal in the item's own currency.
items[].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.
items[].expenseItems[].reimbursable boolean no Whether this item is reimbursable to the employee.
items[].expenseItems[].categoryId string no The expense category the item is booked to. See id on GET accounting/expense-categories/:id.
items[].expenseItems[].externalExpenseItemId string no The identifier this item has in the upstream system that produced it.
items[].expenseItems[].attendees string no Who attended, when the item's category requires it.
items[].expenseItems[].attachments array<object> no The receipts on this item.
items[].expenseItems[].attachments[].id string yes The unique identifier for the attachment record.
items[].expenseItems[].attachments[].fileName string no The display name of the attached file.
items[].expenseItems[].attachments[].fileId string no The identifier of the stored file. There is no endpoint for it.
items[].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.
items[].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.
items[].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.
items[].expenseItems[].amortizationSchedules[].bookName string no The name of the accounting book this schedule posts into.
items[].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.
items[].expenseItems[].amortizationSchedules[].amortizationMethod string no How the schedule spreads its total. Values include 'exactDays', 'pointInTime', 'straightLine', 'straightLineProRateFirstLast' and 'usageBased'.
items[].expenseItems[].amortizationSchedules[].amortizationStartDate date no The first day the schedule amortizes over. Format YYYY-MM-DD.
items[].expenseItems[].amortizationSchedules[].amortizationEndDate date no The last day the schedule amortizes over, inclusive. Format YYYY-MM-DD.
items[].expenseItems[].amortizationSchedules[].term decimal no The number of months the schedule spreads over. A count, not an amount, so it carries no currency.
items[].expenseItems[].amortizationSchedules[].description string no The note recorded against the schedule, where one was given.
items[].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.
items[].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.
items[].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.
pagination object yes The pagination cursor for this page.
pagination.nextCursor string no The cursor for the next page. Pass it as page.cursor. Absent on the last page.
pagination.hasMore boolean yes True when more reports remain beyond this page.
{
  "data": {
    "items": [
      {
        "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",
        "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": [
              null
            ],
            "amortizationSchedules": [
              null
            ]
          }
        ]
      }
    ],
    "pagination": {
      "nextCursor": "<nextCursor>",
      "hasMore": true
    }
  },
  "diagnostics": [
    {
      "code": "<code>",
      "message": "<message>",
      "severity": "error",
      "path": [
        "<path>"
      ],
      "details": "<details>"
    }
  ]
}

Statuses