# Product Lines

`GET /accounting/product-lines`

Group: Accounting › Products › Product Lines · Operation ID: `productLines`

List product lines with structured filters. GET data-set exposing filter[field][op]= (eq/ne/gt/gte/lt/lte/in/notIn/between/like), sort=-lastModifiedDate,name, sparse fields=, and page[size]/page[cursor] cursor pagination. Filter by parent product with filter[productId][eq]=<uuid>. Returns the scalar header of each line; tax records, pricing and external identifiers come from GET accounting/product-lines/:id or POST accounting/product-lines/search. Every request must carry the Api-Version header.

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

## 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`. |

## Query surface

- `id` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `productId` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `lineType` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `priceModel` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `pricingTerm` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `invoiceFrequency` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `unitOfMeasure` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `taxMode` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `enforceListPrice` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `hasUsage` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `hasBeenUsed` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `parentProductLineId` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `dataSource` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `createdDate` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- `lastModifiedDate` — filter by eq, ne, gt, gte, lt, lte, in, notIn, between, like
- Orderable: id, productId, productName, name, lineType, priceModel, pricingTerm, invoiceFrequency, unitOfMeasure, taxMode, enforceListPrice, hasUsage, hasBeenUsed, parentProductLineId, dataSource, createdDate, lastModifiedDate
- Selectable: id, productId, productName, productLineNumber, name, lineType, priceModel, pricingTerm, invoiceFrequency, unitOfMeasure, taxMode, enforceListPrice, hasUsage, hasBeenUsed, commitInvoicing, prepaidBalanceOverConsumptionBehavior, prepaidBalanceRolloverAtRenewal, parentProductLineId, crmProductId, dataSource, createdDate, lastModifiedDate

## Response

`200` Success

Under `data`, an array of productLinesRow:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | no | Stable, platform-assigned id (a UUID) of the product line — the public identifier used by GET accounting/product-lines/:id. Filter e.g. filter[id][in]=<id1>,<id2>. |
| `productId` | string | no | Id of the parent product (a UUID). Filter target: filter[productId][eq]=<uuid>. |
| `productName` | string or null | no | Display name of the parent product. Orderable only. |
| `productLineNumber` | string or null | no | System-generated product line number. Returned only — neither filterable nor orderable; look a line up by number through POST accounting/product-lines/search. |
| `name` | string | no | Product line display name. Orderable only; substring matching is a search concern (POST accounting/product-lines/search term). |
| `lineType` | string or null | no | Line type. One of 'recurring', 'oneTime', 'commitWithOverage', 'payAsYouGo', 'usage', 'prepaid', 'billableTime', 'billableTravelExpense', 'billablePassThrough'. Filter target: filter[lineType][in]=recurring,prepaid. |
| `priceModel` | string or null | no | Price model. One of 'flat', 'perUnit', 'tiered', 'volume', 'stairstep', 'rateCard', 'thresholdBased'. Filter target: filter[priceModel][eq]=tiered. |
| `pricingTerm` | string or null | no | Pricing term. One of 'monthly', 'biMonthly', 'once', 'quarterly', 'semiAnnually', 'annually'. |
| `invoiceFrequency` | string or null | no | Invoice frequency. One of 'monthly', 'biMonthly', 'quarterly', 'semiAnnually', 'annually', 'once', 'custom', 'template', 'milestone', 'allAtOnce', 'termEnd'. |
| `unitOfMeasure` | string or null | no | Unit of measure quantities are tracked in, e.g. 'user', 'seat', 'hour', 'each'. See GET accounting/product-lines/:id for the full set. |
| `taxMode` | string or null | no | Tax mode. One of 'TaxInclusive', 'TaxExclusive' (PascalCase members). |
| `enforceListPrice` | boolean or null | no | When true, sales transactions on this line cannot override the list price. Filter target: filter[enforceListPrice][eq]=true. |
| `hasUsage` | boolean or null | no | True when this Prepaid line has a paired Usage line. |
| `hasBeenUsed` | boolean or null | no | True once the line has been sold on at least one sales order. Computed; never settable. |
| `commitInvoicing` | string or null | no | Invoice timing of a commit line. One of 'advance', 'arrears'. Absent on other line types. |
| `prepaidBalanceOverConsumptionBehavior` | string or null | no | What happens when usage exceeds the prepaid balance. One of 'allowNegative', 'overage'. Prepaid lines only. |
| `prepaidBalanceRolloverAtRenewal` | boolean or null | no | Whether the remaining prepaid balance rolls over at renewal. Prepaid lines only. |
| `parentProductLineId` | string or null | no | Id of the parent Prepaid product line (a UUID) when this is its paired Usage line. Filter target: filter[parentProductLineId][eq]=<uuid>. |
| `crmProductId` | string or null | no | CRM system's own identifier for this line, when integrated from one. Returned only — neither filterable nor orderable; filter on it through POST accounting/product-lines/search. |
| `dataSource` | string or null | no | Upstream system or import job that produced this line, e.g. 'Everest', 'Salesforce'. Filter target: filter[dataSource][eq]=Salesforce. |
| `createdDate` | string (date-time) or null | no | Instant the record was created, as ISO 8601 UTC (YYYY-MM-DDTHH:mm:ss.sssZ). |
| `lastModifiedDate` | string (date-time) | no | Instant the record last changed, as ISO 8601 UTC (YYYY-MM-DDTHH:mm:ss.sssZ). Filter target: filter[lastModifiedDate][gte]=2026-08-01T00:00:00.000Z, with sort=lastModifiedDate, is a complete incremental-sync cursor. |

## 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
