Search expense categories
Operation ID: searchExpenseCategory
Group: Accounting › Expense Categories
Open in the interactive reference
POST /accounting/expense-categories/search
Read-only: A read that takes its filters in the body. Changes nothing, and ignores Idempotency-Key.
Searches expense categories. You can filter by id, name, kind, status, or external identifier. Results are returned newest first, and each item has the same fields as GET accounting/expense-categories/:id.
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: searchExpenseCategoryInput.
| Field | Type | Required | Description |
|---|---|---|---|
filters |
object | no | The filters to apply. A category must match every filter you send. Omit to return all expense categories. Example: {"status":"active"}. |
filters.id |
string | no | Limits results to the category with this identifier. |
filters.category |
string | no | Limits results to the category with this exact name, for example 'Meals'. The name is unique within the tenant, so this returns at most one category. The match is case-sensitive. |
filters.categoryType |
string | no | Limits results to categories of this kind. Accepted values: 'Pur', 'Dis', 'PerDiem'. Any other value matches no category. |
filters.status |
string | no | Limits results to categories in this lifecycle status. Accepted values: 'active', 'inactive'. Any other value matches no category. |
filters.externalId |
string | no | Limits results to categories with this external identifier. It is not unique, so this can return several categories. |
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 page. |
page.size |
number | no | The number of expense categories per page. Defaults to 50. A value above 200 is treated as 200, not rejected. |
{
"filters": {
"status": "active"
},
"page": {
"size": 50
}
}
Response
200 Success
Under data (searchExpenseCategoryOutput):
| Field | Type | Required | Description |
|---|---|---|---|
items |
array<object> | yes | The expense categories on this page, most recently created first. An empty array when nothing matches. |
items[].id |
string | yes | The unique identifier for the expense category. |
items[].category |
string | yes | The display name of the expense category, for example 'Meals'. Unique within the tenant. |
items[].categoryType |
string | no | The kind of expense. Possible values: 'Pur', 'Dis', 'PerDiem'. 'Dis' is distance traveled. |
items[].reimbursable |
boolean | yes | Whether expenses in this category are reimbursed to the employee. |
items[].status |
string | no | The lifecycle status of the expense category. Possible values: 'active', 'inactive'. An inactive category stays readable so historical expense items still resolve, and is not offered for new ones. |
items[].requireAttachment |
boolean | no | Whether an expense in this category must have a receipt attachment. |
items[].requireAttendees |
boolean | no | Whether an expense in this category must list attendees. |
items[].externalId |
string | no | The identifier this category has in an external system. It is not unique. |
items[].lastModifiedDate |
date-time | yes | The date and time the expense category last changed, in UTC. Format YYYY-MM-DDTHH:mm:ss.sssZ. |
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 matches remain beyond this page. |
{
"data": {
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"category": "<category>",
"categoryType": "<categoryType>",
"reimbursable": true,
"status": "<status>",
"requireAttachment": true,
"requireAttendees": true,
"externalId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"lastModifiedDate": "2026-01-15T09:30:00.000Z"
}
],
"pagination": {
"nextCursor": "<nextCursor>",
"hasMore": true
}
},
"diagnostics": [
{
"code": "<code>",
"message": "<message>",
"severity": "error",
"path": [
"<path>"
],
"details": "<details>"
}
]
}
Statuses
400— Invalid request or business failure401— The request carries no valid access token.403— Not authorized404— Not found429— Too many requests from this client address. The response has no body and noRetry-Afterheader.500— Internal server error