Line Item
Line Item
A line item represents a subscription or fee attached to a deal. Line items are the basis for revenue recognition in Planhat - mrr, arr, and value roll up from line items to their parent deal and company.
Line items have two product types: **subscription** (recurring revenue with a start and end dates and recurring revenue) and **fee** (one-off charges with a start date and value). Different field rules apply depending on the type.
Subscriptions can either have fixedPeriod be true, in which case fromDate, toDate, length and mrr/arr/value must be defined, or they can have fixedPeriod be false (AKA an evergreen subscription), in which case only fromDate and mrr/arr must be defined. Once an evergreen line item is cancelled, you can set its status as such, and populate an end date.
If you provide the productId when creating a line item, any fields defined on the product level not defined in the creation payload will be autofilled on the new line item, appending the data you provided. E.g. if creating a line item and providing fromDate but no toDate, toDate and length will be populated on the line item from the product catalog.
Line items must belong to a Deal. The recurring or non-recurring revenue (mrr/arr or value) on a line item is recognised as contracted revenue when the parent deal stage is set to Closed Won.
The status of a line item is auto-set to ongoing, but can be set to renewed or lost. This is not important for revenue recognition as that is based on the deal stage and the date-span of line items, not their status, but it can be useful if using Planhat's native auto-renewal features.
mrr and arr are bidirectionally calculated fields, meaning that if one value is provided, the other will be calculated by the system. This also extends to the value field, in cases where the line item has both a fromDate and toDate.
Property | Required | Type | Description |
|---|---|---|---|
| objectId | Planhat identifier. | |
| string | The line item id in your own system. | |
| string | The line item id from an integration (Salesforce, HubSpot, etc). | |
| Yes | objectId | Related deal id (Planhat identifier). |
| string | Deal name. (Autogenerated). | |
| objectId | Related company id. Inherited from the deal. (Autogenerated). | |
| string | Company name. (Autogenerated). | |
| objectId | Related product id (Planhat identifier). | |
| string | Product name. (Autogenerated). | |
| string | Type of line item. Either | |
| string | Package name associated with the line item. | |
| Yes | date | Start date of the line item. |
| Conditional | date | End date of the line item. Required when |
| string | Status of the line item. One of | |
| boolean | Whether the line item has a fixed end date. Locked when | |
| boolean | Whether the line item auto-renews. | |
| number | Length of the subscription period in months. Can be used instead of | |
| Conditional | number | Monthly Recurring Revenue. Required for subscriptions unless |
| Conditional | number | Annual Recurring Revenue. Calculated from |
| Conditional | number | Total value. Required when |
| string | Currency of the line item. (Autogenerated from company). | |
| boolean | Whether revenue has been recognized. (Autogenerated). | |
| date | Expected renewal date. | |
| number | Days until renewal from today. | |
| number | Renewal period length in months. | |
| string | Unit for the renewal period. Can be "day", "week", or "month". Defaults to "month". (Autogenerated) | |
| number | Expected MRR at renewal. | |
| number | Expected ARR at renewal. Calculated from | |
| number | Notice period length. | |
| string | Unit for the notice period. One of | |
| number | MRR forecast. | |
| number | ARR forecast. Calculated from | |
| number | Optimistic MRR forecast. | |
| number | Optimistic ARR forecast. Calculated from | |
| number | Pessimistic MRR forecast. | |
| number | Pessimistic ARR forecast. Calculated from | |
| objectId | The parent line item this was renewed from. | |
| object | A flexible object with custom data. | |
| date time | ISO date when line item was created. (Autogenerated). | |
| date time | ISO date when line item was last updated. (Autogenerated). |
A line item represents a subscription or fee attached to a deal. Line items are the basis for revenue recognition in Planhat - mrr, arr, and value roll up from line items to their parent deal and company.
Line items have two product types: **subscription** (recurring revenue with a start and end dates and recurring revenue) and **fee** (one-off charges with a start date and value). Different field rules apply depending on the type.
Subscriptions can either have fixedPeriod be true, in which case fromDate, toDate, length and mrr/arr/value must be defined, or they can have fixedPeriod be false (AKA an evergreen subscription), in which case only fromDate and mrr/arr must be defined. Once an evergreen line item is cancelled, you can set its status as such, and populate an end date.
If you provide the productId when creating a line item, any fields defined on the product level not defined in the creation payload will be autofilled on the new line item, appending the data you provided. E.g. if creating a line item and providing fromDate but no toDate, toDate and length will be populated on the line item from the product catalog.
Line items must belong to a Deal. The recurring or non-recurring revenue (mrr/arr or value) on a line item is recognised as contracted revenue when the parent deal stage is set to Closed Won.
The status of a line item is auto-set to ongoing, but can be set to renewed or lost. This is not important for revenue recognition as that is based on the deal stage and the date-span of line items, not their status, but it can be useful if using Planhat's native auto-renewal features.
mrr and arr are bidirectionally calculated fields, meaning that if one value is provided, the other will be calculated by the system. This also extends to the value field, in cases where the line item has both a fromDate and toDate.
Property | Required | Type | Description |
|---|---|---|---|
| objectId | Planhat identifier. | |
| string | The line item id in your own system. | |
| string | The line item id from an integration (Salesforce, HubSpot, etc). | |
| Yes | objectId | Related deal id (Planhat identifier). |
| string | Deal name. (Autogenerated). | |
| objectId | Related company id. Inherited from the deal. (Autogenerated). | |
| string | Company name. (Autogenerated). | |
| objectId | Related product id (Planhat identifier). | |
| string | Product name. (Autogenerated). | |
| string | Type of line item. Either | |
| string | Package name associated with the line item. | |
| Yes | date | Start date of the line item. |
| Conditional | date | End date of the line item. Required when |
| string | Status of the line item. One of | |
| boolean | Whether the line item has a fixed end date. Locked when | |
| boolean | Whether the line item auto-renews. | |
| number | Length of the subscription period in months. Can be used instead of | |
| Conditional | number | Monthly Recurring Revenue. Required for subscriptions unless |
| Conditional | number | Annual Recurring Revenue. Calculated from |
| Conditional | number | Total value. Required when |
| string | Currency of the line item. (Autogenerated from company). | |
| boolean | Whether revenue has been recognized. (Autogenerated). | |
| date | Expected renewal date. | |
| number | Days until renewal from today. | |
| number | Renewal period length in months. | |
| string | Unit for the renewal period. Can be "day", "week", or "month". Defaults to "month". (Autogenerated) | |
| number | Expected MRR at renewal. | |
| number | Expected ARR at renewal. Calculated from | |
| number | Notice period length. | |
| string | Unit for the notice period. One of | |
| number | MRR forecast. | |
| number | ARR forecast. Calculated from | |
| number | Optimistic MRR forecast. | |
| number | Optimistic ARR forecast. Calculated from | |
| number | Pessimistic MRR forecast. | |
| number | Pessimistic ARR forecast. Calculated from | |
| objectId | The parent line item this was renewed from. | |
| object | A flexible object with custom data. | |
| date time | ISO date when line item was created. (Autogenerated). | |
| date time | ISO date when line item was last updated. (Autogenerated). |
https://api.planhat.com/lineitems
To create a line item, `dealId` and `fromDate` are required. You can reference the deal using its externalId or sourceId: `"dealId": "extid-[deal externalId]"` or `"dealId": "srcid-[deal sourceId]"`.
For **subscriptions**: at least one of `mrr`, `arr`, or `value` is required. For **fees**: `value` is required.
Example Request
curl --location -g --request POST 'https://api.planhat.com/lineitems' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '{ "dealId": "610091916d643a7c418aef42", "productId": "61009abc6d643a7c418aef99", "fromDate": "2026-06-01", "toDate": "2027-05-31", "mrr": 5000, "fixedPeriod": true }'
Example Response
{ "_id": "610097ab6d643a7c418af100", "dealId": "610091916d643a7c418aef42", "dealName": "Acme Renewal 2026", "companyId": "61006bc89a3e0b702ed8ea49", "companyName": "Acme", "productId": "61009abc6d643a7c418aef99", "productName": "Platform", "productType": "subscription", "fromDate": "2026-06-01T00:00:00.000Z", "toDate": "2027-05-31T00:00:00.000Z", "mrr": 5000, "arr": 60000, "fixedPeriod": true, "status": "ongoing", "autoRenews": false, "createdAt": "2026-05-11T10:00:00.000Z", "updatedAt": "2026-05-11T10:00:00.000Z" }
https://api.planhat.com/lineitems
To create a line item, `dealId` and `fromDate` are required. You can reference the deal using its externalId or sourceId: `"dealId": "extid-[deal externalId]"` or `"dealId": "srcid-[deal sourceId]"`.
For **subscriptions**: at least one of `mrr`, `arr`, or `value` is required. For **fees**: `value` is required.
Example Request
curl --location -g --request POST 'https://api.planhat.com/lineitems' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '{ "dealId": "610091916d643a7c418aef42", "productId": "61009abc6d643a7c418aef99", "fromDate": "2026-06-01", "toDate": "2027-05-31", "mrr": 5000, "fixedPeriod": true }'
Example Response
{ "_id": "610097ab6d643a7c418af100", "dealId": "610091916d643a7c418aef42", "dealName": "Acme Renewal 2026", "companyId": "61006bc89a3e0b702ed8ea49", "companyName": "Acme", "productId": "61009abc6d643a7c418aef99", "productName": "Platform", "productType": "subscription", "fromDate": "2026-06-01T00:00:00.000Z", "toDate": "2027-05-31T00:00:00.000Z", "mrr": 5000, "arr": 60000, "fixedPeriod": true, "status": "ongoing", "autoRenews": false, "createdAt": "2026-05-11T10:00:00.000Z", "updatedAt": "2026-05-11T10:00:00.000Z" }
https://api.planhat.com/lineitems
To create a line item, `dealId` and `fromDate` are required. You can reference the deal using its externalId or sourceId: `"dealId": "extid-[deal externalId]"` or `"dealId": "srcid-[deal sourceId]"`.
For **subscriptions**: at least one of `mrr`, `arr`, or `value` is required. For **fees**: `value` is required.
Example Request
curl --location -g --request POST 'https://api.planhat.com/lineitems' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '{ "dealId": "610091916d643a7c418aef42", "productId": "61009abc6d643a7c418aef99", "fromDate": "2026-06-01", "toDate": "2027-05-31", "mrr": 5000, "fixedPeriod": true }'
Example Response
{ "_id": "610097ab6d643a7c418af100", "dealId": "610091916d643a7c418aef42", "dealName": "Acme Renewal 2026", "companyId": "61006bc89a3e0b702ed8ea49", "companyName": "Acme", "productId": "61009abc6d643a7c418aef99", "productName": "Platform", "productType": "subscription", "fromDate": "2026-06-01T00:00:00.000Z", "toDate": "2027-05-31T00:00:00.000Z", "mrr": 5000, "arr": 60000, "fixedPeriod": true, "status": "ongoing", "autoRenews": false, "createdAt": "2026-05-11T10:00:00.000Z", "updatedAt": "2026-05-11T10:00:00.000Z" }
https://api.planhat.com/lineitems/:_id
You can also use prefixed identifiers:
https://api.planhat.com/lineitems/extid-{{externalId}}
Or
https://api.planhat.com/lineitems/srcid-{{sourceId}}
Example Request
curl --location -g --request PUT 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '{ "status": "renewed", "renewalMrr": 5500 }'
https://api.planhat.com/lineitems/:_id
You can also use prefixed identifiers:
https://api.planhat.com/lineitems/extid-{{externalId}}
Or
https://api.planhat.com/lineitems/srcid-{{sourceId}}
Example Request
curl --location -g --request PUT 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '{ "status": "renewed", "renewalMrr": 5500 }'
https://api.planhat.com/lineitems/:_id
You can also use prefixed identifiers:
https://api.planhat.com/lineitems/extid-{{externalId}}
Or
https://api.planhat.com/lineitems/srcid-{{sourceId}}
Example Request
curl --location -g --request PUT 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '{ "status": "renewed", "renewalMrr": 5500 }'
https://api.planhat.com/lineitems/:_id
To get a specific line item, pass the _id in the request URL. Alternatively use a prefixed externalId or sourceId:
https://api.planhat.com/lineitems/extid-{{externalId}}
Or
https://api.planhat.com/lineitems/srcid-{{sourceId}}
Example Request
curl --location -g --request GET 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
https://api.planhat.com/lineitems/:_id
To get a specific line item, pass the _id in the request URL. Alternatively use a prefixed externalId or sourceId:
https://api.planhat.com/lineitems/extid-{{externalId}}
Or
https://api.planhat.com/lineitems/srcid-{{sourceId}}
Example Request
curl --location -g --request GET 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
https://api.planhat.com/lineitems/:_id
To get a specific line item, pass the _id in the request URL. Alternatively use a prefixed externalId or sourceId:
https://api.planhat.com/lineitems/extid-{{externalId}}
Or
https://api.planhat.com/lineitems/srcid-{{sourceId}}
Example Request
curl --location -g --request GET 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
https://api.planhat.com/lineitems
The following query params are available:
companyId — Filter by company id. Multiple ids can be separated by commas.
dealId — Filter by deal id.
limit — Limit the list length. Default 100, max 2000.
offset — Start the list at a specific integer index.
sort — Sort by a specific property. Prefix with - to reverse sort order.
select — Return specific properties only. Multiple properties separated by commas.
Example Request
curl --location -g --request GET 'https://api.planhat.com/lineitems?dealId=610091916d643a7c418aef42' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
https://api.planhat.com/lineitems
The following query params are available:
companyId — Filter by company id. Multiple ids can be separated by commas.
dealId — Filter by deal id.
limit — Limit the list length. Default 100, max 2000.
offset — Start the list at a specific integer index.
sort — Sort by a specific property. Prefix with - to reverse sort order.
select — Return specific properties only. Multiple properties separated by commas.
Example Request
curl --location -g --request GET 'https://api.planhat.com/lineitems?dealId=610091916d643a7c418aef42' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
https://api.planhat.com/lineitems
The following query params are available:
companyId — Filter by company id. Multiple ids can be separated by commas.
dealId — Filter by deal id.
limit — Limit the list length. Default 100, max 2000.
offset — Start the list at a specific integer index.
sort — Sort by a specific property. Prefix with - to reverse sort order.
select — Return specific properties only. Multiple properties separated by commas.
Example Request
curl --location -g --request GET 'https://api.planhat.com/lineitems?dealId=610091916d643a7c418aef42' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
https://api.planhat.com/lineitems/:_id
To delete a line item, pass the _id in the request URL.
Example Request
curl --location -g --request DELETE 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
Example Response
{ "n": 1, "ok": 1, "deletedCount": 1 }
https://api.planhat.com/lineitems/:_id
To delete a line item, pass the _id in the request URL.
Example Request
curl --location -g --request DELETE 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
Example Response
{ "n": 1, "ok": 1, "deletedCount": 1 }
https://api.planhat.com/lineitems/:_id
To delete a line item, pass the _id in the request URL.
Example Request
curl --location -g --request DELETE 'https://api.planhat.com/lineitems/610097ab6d643a7c418af100' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}'
Example Response
{ "n": 1, "ok": 1, "deletedCount": 1 }
https://api.planhat.com/lineitems
To create a line item, dealId and fromDate are required. To update, specify one of the following keyables in the payload (in order of priority): _id, sourceId, externalId. There is an upper limit of 5,000 items per request.
Example Request
curl --location -g --request PUT 'https://api.planhat.com/lineitems' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '[ { "externalId": "li-001", "dealId": "extid-deal-001", "fromDate": "2026-06-01", "toDate": "2027-05-31", "mrr": 5000, "fixedPeriod": true }, { "externalId": "li-002", "dealId": "extid-deal-001", "fromDate": "2026-06-01", "productType": "fee", "value": 2000 } ]
Example Response
{ "created": 2, "createdErrors": [], "insertsKeys": [ { "_id": "610097ab6d643a7c418af100", "externalId": "li-001" }, { "_id": "610097ab6d643a7c418af101", "externalId": "li-002" } ], "updated": 0, "updatedErrors": [], "updatesKeys": [], "nonupdates": 0, "modified": [], "upsertedIds": ["610097ab6d643a7c418af100", "610097ab6d643a7c418af101"], "permissionErrors": [] }
https://api.planhat.com/lineitems
To create a line item, dealId and fromDate are required. To update, specify one of the following keyables in the payload (in order of priority): _id, sourceId, externalId. There is an upper limit of 5,000 items per request.
Example Request
curl --location -g --request PUT 'https://api.planhat.com/lineitems' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '[ { "externalId": "li-001", "dealId": "extid-deal-001", "fromDate": "2026-06-01", "toDate": "2027-05-31", "mrr": 5000, "fixedPeriod": true }, { "externalId": "li-002", "dealId": "extid-deal-001", "fromDate": "2026-06-01", "productType": "fee", "value": 2000 } ]
Example Response
{ "created": 2, "createdErrors": [], "insertsKeys": [ { "_id": "610097ab6d643a7c418af100", "externalId": "li-001" }, { "_id": "610097ab6d643a7c418af101", "externalId": "li-002" } ], "updated": 0, "updatedErrors": [], "updatesKeys": [], "nonupdates": 0, "modified": [], "upsertedIds": ["610097ab6d643a7c418af100", "610097ab6d643a7c418af101"], "permissionErrors": [] }
https://api.planhat.com/lineitems
To create a line item, dealId and fromDate are required. To update, specify one of the following keyables in the payload (in order of priority): _id, sourceId, externalId. There is an upper limit of 5,000 items per request.
Example Request
curl --location -g --request PUT 'https://api.planhat.com/lineitems' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {{apiToken}}' \ --data-raw '[ { "externalId": "li-001", "dealId": "extid-deal-001", "fromDate": "2026-06-01", "toDate": "2027-05-31", "mrr": 5000, "fixedPeriod": true }, { "externalId": "li-002", "dealId": "extid-deal-001", "fromDate": "2026-06-01", "productType": "fee", "value": 2000 } ]
Example Response
{ "created": 2, "createdErrors": [], "insertsKeys": [ { "_id": "610097ab6d643a7c418af100", "externalId": "li-001" }, { "_id": "610097ab6d643a7c418af101", "externalId": "li-002" } ], "updated": 0, "updatedErrors": [], "updatesKeys": [], "nonupdates": 0, "modified": [], "upsertedIds": ["610097ab6d643a7c418af100", "610097ab6d643a7c418af101"], "permissionErrors": [] }