Kaizen #9 - Handling Product Line Items in the Inventory Modules #API

Kaizen #9 - Handling Product Line Items in the Inventory Modules #API

Hello everyone!

Welcome back to another post in the Kaizen series!
This week, we will discuss handling product line items associated with the inventory modules—Quotes, Invoices, Purchase Orders, and Sales Orders.

What is a product line item?

On the Quote, Invoice, Purchase Order, Sales Order create or edit page, you add individual products in the Product Details section. This section also contains other details like the List Price, Quantity, Amount, Discount, and Tax. Every product and the corresponding details are called product line items.

In this post, we will discuss 
  1. Adding product line items while inserting a quote (through the Insert Records API)
  2. Updating a quote by adding another product line item (through the Update Specific Records API)

The JSON input is similar while adding/updating an invoice, purchase order, and sales order.

1. Adding Product Line Items to a Quote

While adding a product to a quote you can,
      a. Select a price book to associate with the product
      b. Specify a different list price for the product

1. a. Selecting a price book to associate with the product
To associate a price book with the product, you must pass the ID of that price book in the input.

What happens when you pass the Price Book's ID?
  • The discount on the product is automatically applied based on the range you specified in the price book.
  • The cumulative tax (specified for the product) is automatically calculated based on the amount (after the discount).
  • The List Price of the product specified in the associated price book is automatically taken for calculating the amount.

The sample input for Product_Details is as follows.

"Product_Details": [
    {
      "product": {
        "id": "3652397000000491147"
      },
      "quantity": 100,
      "product_description": "product_description",
      "book": "3652397000000616007"
    }
  ]

The following table gives information about each key in the Product_Details JSON Array.
Key
Data Type
Description
product
JSON Object
The ID of the product in the quote.
quantity
Number
The number of units of the product the quote is generated for. Accepts only positive integer values. The amount is calculated based on this number and the price for each unit.
book
String
The ID of the Price Book you have associated with the product.
product_description
String
Description of the product.

Here is a screenshot from the UI.


1.b. Specifying a different list price for the product
When the product does not have an associated price book or you want to give a different list price, you must specify the list price and the discount in the Product_Details array. 
Otherwise, the system enters the value for the discount as 0 and takes the list price you specified while creating that product.
The sample input for the Product_Details JSON array is as follows.
"Product_Details": [
    {
      "product": {
        "id": "3652397000000491147"
      },
      "quantity": 150,
      "product_description": "product_description",
      "Discount": 1000,
      "list_price": 1100,
      "line_tax": [
        {
          "percentage": 1,
          "name": "VAT"
        }
      ]
    }
  ]

The following table gives information about each key in the Product_Details JSON Array.

Key
Data Type
Description
Product
JSON Object
ID of the product the quote generated for.
quantity
Number
The number of units of the product the quote is generated for. Accepts only positive integer values.
Discount
Currency
The discount, in decimals, you want to apply for the product. Accepts up to 16 digits before the decimal, and up to 9 digits after the decimal. This limit may vary based on the value configured in 'Maximum digits allowed' in the properties pop-up of the field, in the UI.
product_description
String
Description of the product.
list_price
Currency
The list price of the product.
line_tax
JSON Array
Contains the percentage and the name of the tax associated with the product.
percentage
Percent
The percentage of tax applied on the product. Accepts only numeric values, up to 5 digits.
name
String
The name of the tax applied on the product.

As mentioned earlier, the Product Details section encompasses the taxes applied for each product and the aggregate tax applied to the Sub Total of the quote or any other inventory module.

You can specify the different taxes you want to apply for your products in the CRM UI.
You can add them under Setup > Customization > Modules and Fields > Products as shown in the below image.


You can use these configured values as inputs in the API.

Adding taxes to the product while creating/updating an inventory module
When you add a product to an inventory module, to apply the taxes to that product, you must specify the tax details in the line_tax JSON array inside Product_Details.

You must specify the percentage and the name of the tax associated with the product as JSON objects.
You cannot specify the amount as the system calculates it automatically based on the quantity.

Example:

"Product_Details": [
    {
      "product": {
        "id": "3652397000001363004"
      },
      "quantity": 100,
      "Discount": 20.1,
      "product_description": "product_description",
      "line_tax": [
        {
          "percentage": 10,
          "name": "Sales Tax"
        },
        {
          "percentage": 1,
          "name": "Vat"
        }
      ]
    }
  ]

Adding aggregate tax to the quote or other inventory modules
This is the tax that you want to apply to the Sub Total of the line items while generating the invoice, quote, sales order, or purchase order. The taxes you specify in the $line_tax key are added to the ones already applied to the product through the line_tax key.
The $line_tax key is present outside the Product_Details JSON array.

The structure for this JSON array is as follows.

"Product_Details": [
    {
      "product": {
        "id": "3652397000001363004"
      },
      "quantity": 100,
      "product_description": "product_description",
      "line_tax": [
        {
          "percentage": 10,
          "name": "Sales Tax"
        },
        {
          "percentage": 1,
          "name": "Vat"
        }
      ]
    }
  ],
  "$line_tax": [
    {
      "percentage": 1.5,
      "name": "Common Tax",
      "id": "3652397000001376005"
    }
  ]

Key
Data type
Description
$line_tax
JSON Array
Contains the name, ID, and the percentage of the tax you want to apply to the quote.
percentage
Percent
The percentage of tax applied on the quote. Accepts only numeric values, up to 5 digits.
name
String
The name of the tax.
id
String
The unique ID of the tax.

Note
Make a GET request to "{{api-domain}}/crm/v2/org/taxes" to obtain the IDs of all the taxes for your organization.

The below image shows the data corresponding to the line_tax and $line_tax keys in the UI for a quote.


Points to note
  • For Product_Details
    When you have associated a price book with an inventory module, and you include the key and value for Discount inside Product_Details, this discount value overrides the discount calculated from the price book.
  • For line_tax
    You must specify the percentage of tax in every JSON object inside the line_tax array.

2. Updating a Quote by adding Product Line Items
You can associate multiple products to a quote.
While updating a quote, you can add/update/remove a line item.
Let us consider an example where you have five line items in a quote, and you want to remove two line items, and add a new one.
In this case, you must
  • Pass the IDs of the line items you want to retain as individual JSON objects.
  • Add the new line item with the required details as a new JSON object.
  • Do not include any details about the line item you want to remove. When you do not specify the ID of any line item, the system deletes it automatically.
A sample JSON structure for the above scenario is as follows.         

"Product_Details": [
    {
      "id": "3652397000001377174"
    },
    {
      "id": "3652397000001378168"
    },
    {
      "id": "3652397000001379172"
    },
    {
      "product": {
        "id": "3652397000001351002"
      },
      "quantity": 100,
      "book": "3652397000000616007"
    }
  ] 

To obtain the ID of the existing line item, make a GET request to fetch the Quote you want to update. The response contains the ID of the existing line item in the Product_Details array.

Note
  • You can add a maximum of 200 line items to an inventory module.

We hope you found this post useful. Please reach out to us if you have any questions, or let us know in the comment section.

Cheers!










    • Recent Topics

    • Free webinar: Streamlining customer service paperwork with the Zoho Sign extension for Zoho Desk

      Hello Everyone! Have you been wondering about bridging the gap between digitised customer service and business paperwork? Join our free webinar to learn how you can do this by connecting Zoho Sign, our digital signature app, with Zoho Desk, our online
    • Zoho Books | Product updates | July 2025

      Hello users, We’ve rolled out new features and enhancements in Zoho Books. From plan-based trials to the option to mark PDF templates as inactive, explore the updates designed to enhance your bookkeeping experience. Introducing Plan Based Trials in Zoho
    • Mail Search should allow grouping by conversation like Gmail.

      Having switched from gmail I have found the search function hard to use. Mostly because mail is not grouped by conversation in search. If I search for a word when looking for a conversation had with someone then sometimes 10 emails will come up from the
    • Improve Zoho Learn updated article notifications

      I noticed today while updating an article, that the notification users get says "[User Name] has published article [Article Name]..." My feedback to the product team is that it would be really helpful for an end user, if the system notification differentiated
    • Safari Support

      Safari, the world's second largest browser, zoho desk does not officially or fully support. That needs to change.
    • Can I get images from an "Image Upload" field in a webhook?

      I want to send images from 2 "image upload" fields via a webhook. Is this possible?
    • Ticket closure notification - all contacts cc'd on email thread

      Hello, If a client sends an email to our service desk and cc's in other people that work at the same company - so that they are in the loop of the service request. When the we close the ticket, only the ticket owner (person who emailed us - which created
    • Inactive account cleanup policy for Zoho Sign

      Zoho Sign reserves the right to delete accounts that are license free and inactive for more than 120 days. The account deletion will be initiated only after the user receives prior email notice about possible data deletion and how to backup the data.
    • Missde API documentation for Sales Receipt

      Hi! I noticed that the Sales Receipt endpoint is not currently listed in your API documentation (https://www.zoho.com/books/api/v3/introduction/). Could you please provide any available temporary documentation for this endpoint, along with a detailed
    • Multi-currency in Zoho CRM Forecast and Reports

      As a company we have branches in 4 different countries with as many different currencies. Our Sales Teams would like to work with their local currency as much as possible. The Forecast module using only 1 currency is practically usable only by the sales
    • How to select from pricebook when creating a salesorder or quote

      I am creating a sales order and when selecting the Products I do not see any where to select from pricebooks. How do i associate this to my orders?
    • Proposal for Creating a Unique "Address" Entity in Zoho FSM

      The "Address" entity is one of the most critical components for a service-oriented company. While homeowners may change and servicing companies may vary, the address itself remains constant. This constancy is essential for subsequent services, as it provides
    • I cannot find my older documents from 2024 and 2023

      I cannot find my older documents from 2024 and 2023.
    • System default SLA descriptions can't be modified

      The system default SLAs have identical descriptions for all SLA levels, but their settings differ. However, I am facing an issue where I cannot modify these descriptions and save the changes. The content of the description box can be edited but the changes
    • Customising Help Center

      Hi I don't think it is possible to add custom pages to help center? We'd like to use this as a customer portal with support tickets, FAQ/Guides, Billing and contracts. Is there any plans to add a feature like this or an alternative way to do it other
    • Replies sometimes creating separate ticket

      Sometimes when a customer responds to an email coming from Zoho Desk, instead of adding a reply to the original ticket, a separate ticket is created. This happens even though the response subject line contained the ticket number, and the person responding
    • Ticket Approvals - External Users

      The ticket approval option - we need to be able to select external users (Contacts) for approvals. Sometimes we are working with an end user and their boss needs to approve a purchase. For example, working with a cashier on a broken cash register and
    • Force Users to Ask Answer Bot a question... First

      End users will always skip talking to a bot. It would be nice if Zoho adopted the standard and forced users to first ask a question to answer bot (or zia in some fashion) and then pass to the agent if it wasn't answered. Options to force the user to speak
    • View Answer Bot conversations?

      We are trialing Zia and are experimenting with Answer Bot on our knowledge base. So far so good! Management asks me if it is possible to view Answer Bot conversations, the purpose being to look over its shoulder and confirm that it is working as des
    • Mass Email an Account

      It would be nice to mass email an account stating there is an outage at their business or something specific to an account is needed to be mass communicated. Even if it makes a ticket for every Email Out to every contact in the Account. Think: the customer
    • Multiple Topics assigned to a single Campaign

      Hello, is it possible to assign multiple Topics to a single Campaign? We frequently write a content to our subscribers that spans multiple Topics and we would like to send it to all Contacts that are subscribed to at least one of the Topics. But it looks
    • Zoho Projects Fonts and Accessibility missing

      I cannot find any more the tab where I can change the font in Zoho Project. I also checked the knowledgebase and there they have accessibility tab which I am completely missing. Is there some setup I am missing or is it a problem with our account?
    • Zoho Books Custom Widgets Deprecation Error

      I created a simple sample widget with zet and published it using sigma Both in the Sandbox and Production the Widgets are showing this error
    • Problems with PDF files in notebook

      I'm evaluating Zoho Notebook as an alternative to Evernote and imported my Evernote account to Zoho Notebook. First issue is that notes in Evernote that comprise a PDF are turned into a 'group' with a single note page (that has the text from the Evernote
    • API (v3) Tasks sorting issue

      We are using the v3 API for Projects. When we gat all tasks, per page of 100 tasks, we get the task info alright. But when we try to sort based on DESC(last_modified_time) we don't get the correct sort order. It is roughly sorted by the last_modified_time,
    • Assemblies make my stock go negative

      I am sure this is just the way that we are using this feature, but we use assemblies, a lot. The issue for us is the way that the relive inventory and the fact that it makes our composite item stock go negative. I have added flows to auto assemble and
    • User Activity Reports

      I'd like to get data related to user activity.  For example, Login and logout times, emails sent/received, new records created , etc. Is that currently available. I just can't seem to find anything . Thanks, Dave
    • Help: Populate “Contact Owner” details into Customer custom fields (for email templates) in Zoho Books

      We want to send invoices on behalf of our sales agents, and include the agent’s name, email, and phone in the email body using placeholders. Plan is to copy the Customer Owner details into three Customer custom fields, so they can be used as placeholders
    • Undocumented Books API error message - 1000 - The requested action could not be completed. Please try again. | Unexpected error

      This code sometimes throws this error 1000 - The requested action could not be completed. Please try again. | Unexpected error What does it mean? result = zoho.books.updateRecord("salesorders",organization.get("organization_id"),salesorder_id,sales_
    • Partial payments for retainer invoices

      When a customer does not pay the entire retainer invoice there is no way to apply a partial payment. PLEASE add this function.
    • Making Tags Mandatory

      When creating an expense, is it possible to make the Tags field mandatory?  I see the option in settings to make other fields mandatory, like Merchant, Description, Customer, etc, but nothing about Tags. Thanks! Kevin
    • Mass Update not trigger workflows

      Hi, I have performed a mass update of all records in a custom module using a custom view. I have a dummy checkbox on my module that I turn on or off - hoping to trigger all the new workflows that have been created for that module. However, no workflows
    • Multi-Select lookup field has reached its maximum??

      Hi there, I want to create a multi-select lookup field in a module but I can't select the model I want the relationship to be with from the list. From the help page on this I see that you can only create a max of 2 relationships per module? Is that true?
    • Generating CRM reports based on date moved in staged history

      Hi everyone, I'm trying to generate CRM reports of jobs (I think these are called usually deals) based on when they were moved to a particular stage, ie all jobs that were moved to Proposal/Quote in the previous financial year. I can see from other similar
    • Modules for missed calls, emails, texts etc

      Hi there. Is there a way to create a module that would automatically show a list of all inbound calls that were missed by our users, as well as any inbound SMS's, emails & WhatsApp messages. That way, a user who is available, can work through that list
    • Subforms and automation

      If a user updates a field how do we create an automation etc. We have a field for returned parts and i want to get an email when that field is ticked. How please as Zoho tells me no automation on subforms. The Reason- Why having waited for ever for FSM
    • Conditional layouts - support for multi-select picklists

      Hi, The documentation for conditional layouts says the following: "Layout Rules cannot be used on the following field types: Auto Number Lookup Multi Select Lookup User Lookup Formula File Upload Multi Line" I have a custom module with a multi-pick list
    • Ability to Set a General Email Signature for the Organization in Zoho Recruit

      Dear Zoho Recruit Team, I hope you're doing well. We would like to request a feature that would allow us to set a general email signature at the organizational level within Zoho Recruit. Currently it is only possible for individual users to create their
    • Custom Buttons & Links Now Supported in Portals

      We’ve just made portals in Zoho Recruit more powerful and customizable than ever! You can now bring the power of Custom Buttons and Links to your Candidate, Client, Vendor, and Custom Portals — enabling portal users to take direct action without recruiter
    • Is there a way to show contact emails in the Account?

      I know I can see the emails I have sent and received on a Contact detail view, but I want to be able to see all the emails that have been sent and received between all an Accounts Contacts on the Account Detail view. That way when I see the Account detail
    • Next Page