# Search Expense Report

`POST /accounting/expense-reports/search`

Group: Accounting › Expense Reports · Operation ID: `searchExpenseReport`

Returns the expense reports that match the given filters, each with its expense items.

Searches expense reports and pages through the matches, returning the full record, header and expense items, for each. Matching nothing returns an empty items array, not an error. The expenseNumber and externalExpenseReportId filters are not unique, so a match on either can return several reports. The employee and legal-entity name filters are here rather than on the collection because a name must not appear in a URL.

[Open in the interactive reference](https://docs.api.lensing.ai/?op=searchExpenseReport)

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Api-Version` | header | `"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. |
| `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/: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. |
| `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. |

Example:

```json
{
  "filters": {
    "status": "pendingApproval"
  },
  "page": {
    "size": 50
  }
}
```

## Response

`200` Success

Under `data` (searchExpenseReportOutput):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | array of 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` | string (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` | string (decimal) | no | The total reimbursable amount across the report's items, in reimbursementCurrency. |
| `items[].reimbursableTotalNetAmount` | string (decimal) | no | The total reimbursable amount excluding VAT, in reimbursementCurrency. |
| `items[].amountPaid` | string (decimal) | no | The amount already reimbursed to the employee, in reimbursementCurrency. |
| `items[].openAmount` | string (decimal) | no | The amount still owed to the employee, reimbursableTotal minus amountPaid, in reimbursementCurrency. |
| `items[].pendingAmount` | string (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/: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 departments/:id. |
| `items[].offsetAccountId` | string | no | The GL offset account for the reimbursement. See id on GET accounting/accounts/:id. |
| `items[].lastModifiedDate` | string (date-time) | yes | The date and time the expense report last changed, in UTC. Format YYYY-MM-DDTHH:mm:ss.sssZ. |
| `items[].expenseItems` | array of 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` | string (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` | string (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 of 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. |
| `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. |

## Statuses

- `400` — Invalid request or business failure
- `401` — Missing or invalid access token
- `403` — Not authorized
- `404` — Not found
- `429` — Too many requests
- `500` — Internal server error
