List a performance obligation's products
Operation ID: listPerformanceObligationProducts
Group: Accounting › Performance Obligations
Open in the interactive reference
GET /accounting/performance-obligations/{id}/products
Read-only: Reads and returns; changes nothing.
Lists a performance obligation's products. This endpoint doesn't follow the standard collection rules in Pagination and querying.
Page through the results with pageSize and cursor, not page[size] and page[cursor]. A pageSize below 1 is treated as 1. The response lists the records in data.items and the next page's cursor in data.pagination.nextCursor. The endpoint takes no filters, and has no sort or fields.
The endpoint ignores any query parameter it doesn't declare, and returns no error. A request that follows the standard rules gets the first page, unfiltered, every time.
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 performance obligation whose products you want to retrieve. |
cursor |
query | string | no | The cursor from the previous response's data.pagination.nextCursor. Omit for the first page. |
pageSize |
query | number | no | The number of mappings per page. Defaults to 50. A value above 200 is treated as 200, not rejected. |
Response
200 Success
Under data (listPerformanceObligationProductsOutput):
| Field | Type | Required | Description |
|---|---|---|---|
items |
array<object> | yes | The obligation's product mappings on this page, newest first. An empty array when the obligation maps no products. |
items[].id |
string | no | The unique identifier for this product mapping. |
items[].productId |
string | no | The mapped product. See id on GET accounting/products/:id. |
items[].productCode |
string | no | The code of that product. |
items[].productName |
string | no | The name of that product. |
items[].entityBookId |
string | no | The entity book this mapping applies in. A product mapped in several entity books has one entry per book. See id on GET accounting/books/:bookId/entity-assignments. |
items[].entityName |
string | no | The name of the legal entity of that entity book. |
items[].bookName |
string | no | The name of the accounting book of that entity book. |
items[].effectiveStartDate |
date | yes | The first date this mapping applies. Format YYYY-MM-DD. |
items[].effectiveEndDate |
date | no | The last date this mapping applies. Format YYYY-MM-DD. Absent when the mapping is open-ended. |
items[].lastModifiedDate |
date-time | yes | The date and time this mapping 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 the cursor query parameter. Absent on the last page. |
pagination.hasMore |
boolean | yes | True when more mappings remain beyond this page. |
{
"data": {
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"productId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"productCode": "<productCode>",
"productName": "<productName>",
"entityBookId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"entityName": "<entityName>",
"bookName": "<bookName>",
"effectiveStartDate": "2026-01-15",
"effectiveEndDate": "2026-01-15",
"lastModifiedDate": "2026-01-15T09:30:00.000Z"
}
],
"pagination": {
"nextCursor": "<nextCursor>",
"hasMore": true
}
},
"diagnostics": [
{
"code": "<code>",
"message": "<message>",
"severity": "error",
"path": [
"<path>"
],
"details": "<details>"
}
]
}
Errors
| Code | Status |
|---|---|
NOT_FOUND |
400 |
Statuses
400— Invalid request or business failure. Codes: NOT_FOUND401— 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