# Returns a PSA project's expenses with their budget assignments.

`GET /psa/expenses/summary`

Group: PSA › Expenses · Operation ID: `getExpensesSummary`

Returns one PSA project's expenses together with their budget assignments and every budget defined for the project, selected by a numeric psaProjectId in the query string. Only the expenses array is paginated. budgetMappings covers just the expenses on the current page, while expenseBudgets lists every budget for the project on every page, and defaultBudget is the catch-all budget when one is set. Every amount is a bare decimal with its currency in a sibling field. With only View permission you see only your own expenses, and with Edit permission you see all of the project's expenses. The expenses cursor wraps an offset, so a page is not stable if expenses are added or removed between fetches.

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

## 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`. |
| `psaProjectId` | query | number | yes | The id of the PSA project. It is the numeric package-layer key, not the UUID that GET psa/projects/:id takes. |
| `pageCursor` | query | string | no | The cursor from the previous response's pagination.nextCursor. Omit on the first request. |
| `pageSize` | query | number | no | The number of expenses per page, between 1 and 200. Defaults to 50. The maximum is 200. |

## Response

`200` Success

Under `data` (getExpensesSummaryOutput):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `expenses` | array of object | yes | The expense entries on this page, each linked to the project through its assigned budget. |
| `expenses[].id` | number | no | The unique identifier for the expense entry. |
| `expenses[].expenseReportId` | number | no | The id of the expense report this expense belongs to. It is a numeric package-layer key, not the UUID that GET accounting/expense-reports/:id takes. |
| `expenses[].employeeName` | string | no | The name of the employee who incurred the expense. |
| `expenses[].categoryName` | string | no | The name of the expense category. |
| `expenses[].amount` | string (decimal) | no | The gross amount of the expense, in the currency given by amountCurrency. |
| `expenses[].amountCurrency` | string | no | The currency of amount. Format ISO 4217, for example 'USD'. |
| `expenses[].reimbursableNetAmount` | string (decimal) | no | The reimbursable net amount of the expense, after tax and any company-paid portions, in the currency given by reimbursableNetAmountCurrency. |
| `expenses[].reimbursableNetAmountCurrency` | string | no | The currency of reimbursableNetAmount. Format ISO 4217, for example 'USD'. |
| `expenses[].status` | string | no | The status of the expense entry. |
| `expenses[].notes` | string | no | Free-form notes on the expense. |
| `expenses[].billDate` | string (date) | no | The date the expense was incurred. Format YYYY-MM-DD. |
| `expenses[].billableExpense` | string | no | The billable classification of the expense. |
| `expenses[].expenseReportNumber` | string | no | The human-readable number of the expense report. |
| `budgetMappings` | array of object | yes | The mapping of each expense on this page to its assigned budget. It covers only the expenses in this page's expenses array. |
| `budgetMappings[].expenseItemBaseId` | number | yes | The id of the expense this mapping is for. It matches an id in the expenses array of this response. |
| `budgetMappings[].expenseBudgetId` | number | yes | The id of the budget this expense is mapped to. It matches an id in the expenseBudgets array of this response. |
| `budgetMappings[].name` | string | yes | The display name of the budget. |
| `budgetMappings[].budget` | string (decimal) | no | The budget amount, in the currency given by currency. Absent when the budget has no amount. |
| `budgetMappings[].currency` | string | no | The currency of budget. Format ISO 4217, for example 'USD'. Absent when the budget has no amount. |
| `budgetMappings[].isDefault` | boolean or null | no | Whether this is the project's default catch-all budget. |
| `budgetMappings[].billable` | boolean or null | no | Whether expenses against this budget are billable to the customer. |
| `budgetMappings[].productId` | number or null | no | The id of the product tied to this budget. It is a numeric package-layer key, not the UUID that GET accounting/products/:id takes. Absent when the budget is not tied to a product. |
| `budgetMappings[].productLineId` | number or null | no | The id of the product line tied to this budget. It is a numeric package-layer key, not the UUID that GET accounting/product-lines/:id takes. Absent when the budget is not tied to a product line. |
| `budgetMappings[].salesOrderId` | number | no | The id of the sales order this budget bills against. It is a numeric package-layer key, not the UUID that GET accounting/sales-orders/:id takes. |
| `expenseBudgets` | array of object | yes | Every budget defined for the project. This array is never paginated. |
| `expenseBudgets[].id` | number | yes | The unique identifier for the budget. |
| `expenseBudgets[].name` | string | yes | The display name of the budget. |
| `expenseBudgets[].budget` | string (decimal) | no | The budget amount, in the currency given by currency. Absent when the budget has no amount. |
| `expenseBudgets[].currency` | string | no | The currency of budget. Format ISO 4217, for example 'USD'. Absent when the budget has no amount. |
| `expenseBudgets[].isDefault` | boolean | yes | Whether this is the project's default catch-all budget. |
| `expenseBudgets[].lastModifiedDate` | string (date-time) | no | The date and time the budget definition last changed, in UTC. Format YYYY-MM-DDTHH:mm:ss.sssZ. |
| `expenseBudgets[].billable` | boolean or null | no | Whether expenses against this budget are billable to the customer. |
| `expenseBudgets[].productId` | number or null | no | The id of the product tied to this budget. It is a numeric package-layer key, not the UUID that GET accounting/products/:id takes. Absent when the budget is not tied to a product. |
| `expenseBudgets[].productLineId` | number or null | no | The id of the product line tied to this budget. It is a numeric package-layer key, not the UUID that GET accounting/product-lines/:id takes. Absent when the budget is not tied to a product line. |
| `expenseBudgets[].salesOrderId` | number | no | The id of the sales order this budget bills against. It is a numeric package-layer key, not the UUID that GET accounting/sales-orders/:id takes. |
| `defaultBudget` | object | no | The project's default catch-all budget for expenses with no explicit mapping. Absent when the project has no default budget. |
| `defaultBudget.id` | number | yes | The unique identifier for the budget. |
| `defaultBudget.name` | string | yes | The display name of the budget. |
| `defaultBudget.budget` | string (decimal) | no | The budget amount, in the currency given by currency. Absent when the budget has no amount. |
| `defaultBudget.currency` | string | no | The currency of budget. Format ISO 4217, for example 'USD'. Absent when the budget has no amount. |
| `defaultBudget.isDefault` | boolean | yes | Always true, because this is the default budget. |
| `defaultBudget.lastModifiedDate` | string (date-time) | no | The date and time the budget definition last changed, in UTC. Format YYYY-MM-DDTHH:mm:ss.sssZ. |
| `defaultBudget.billable` | boolean or null | no | Whether expenses against this budget are billable to the customer. |
| `defaultBudget.productId` | number or null | no | The id of the product tied to this budget. It is a numeric package-layer key, not the UUID that GET accounting/products/:id takes. Absent when the budget is not tied to a product. |
| `defaultBudget.productLineId` | number or null | no | The id of the product line tied to this budget. It is a numeric package-layer key, not the UUID that GET accounting/product-lines/:id takes. Absent when the budget is not tied to a product line. |
| `defaultBudget.salesOrderId` | number | no | The id of the sales order this budget bills against. It is a numeric package-layer key, not the UUID that GET accounting/sales-orders/:id takes. |
| `pagination` | object | yes | The pagination cursor for the expenses array. |
| `pagination.nextCursor` | string | no | The cursor for the next page. Pass it as the pageCursor query parameter. Absent on the last page. |
| `pagination.hasMore` | boolean | yes | True when more expenses remain beyond this page. |

## Errors

| Code | Status |
| --- | --- |
| `EMPLOYEE_NOT_FOUND` | 400 |

## Statuses

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