hieuvnlabs logo
Hiusvu

How To Delete Rows in a Zoho People Tabular Section (Subform) with the API

Published on September 9, 2026

How To Delete Rows in a Zoho People Tabular Section (Subform) with the API

Introduction

In Zoho People, a tabular section (subform) such as Work Experience or Education holds several rows per employee. Deleting one of those rows through the API takes a single updateRecord call, but that call needs three identifiers: the form's formLinkName, the section's sectionId and the row's tabular.ROWID. This guide shows the shortest working version: look the IDs up once, then run one Deluge function that removes the first row of a section.

Prerequisites

  • A Zoho People Connection (or an OAuth token) with the ZOHOPEOPLE.forms.ALL scope. Older docs use authtoken in the URL; that method is deprecated, so use Authorization: Zoho-oauthtoken ... or a Connection instead.
  • The recordId of the employee you want to edit. It is visible in the URL when you open the employee in Zoho People.

Step 1. Look Up the Three IDs

You only need to do this once per form. Each lookup is a plain GET; the full parameter lists are in Zoho's documentation, linked below.

What you needWhere it comes fromExample
formLinkNameFetch Forms API: GET /people/api/formsemployee
sectionIdForm Components API: GET /people/api/forms/employee/components?version=2. Tabular sections have isTabular: true and their own sectionId3000000000375 (Work Experience)
tabular.ROWIDFetch Record API: GET /people/api/forms/employee/getRecordByID?recordId=.... Rows are under tabularSections, keyed by section name3000000130017

Reference: Fetch a single record, Update records with tabularData, and the Zoho People API overview for Fetch Forms and Form Components.

Two things to keep in mind: the sectionId is different in every organisation, so read it from your own account rather than copying an example, and a deleted row cannot be restored.

Step 2. The Deluge Function

This function fetches the employee, takes the first row of the Work Experience section, and deletes it. Replace recordId, sectionId and the Connection name with your own values.

recordId  = "3000000130001";
sectionId = "3000000000375";   // Work Experience, from the components API

// 1. Read the record to get the row ID
record = invokeUrl
[
    url : "https://people.zoho.com/people/api/forms/employee/getRecordByID?recordId=" + recordId
    type : GET
    connection : "zoho_people"
];

rows  = record.get("response").get("result").get("tabularSections").get("Work Experience");
rowId = rows.get(0).get("tabular.ROWID");   // first row of the section

// 2. Build tabularData: { "<sectionId>": { "delete": ["<rowId>"] } }
rowsToDelete = List();
rowsToDelete.add(rowId);

tabularData = Map();
tabularData.put(sectionId, {"delete": rowsToDelete});

// 3. Send the update
params = Map();
params.put("recordId", recordId);
params.put("tabularData", tabularData.toString());

result = invokeUrl
[
    url : "https://people.zoho.com/people/api/forms/json/employee/updateRecord"
    type : POST
    parameters : params
    connection : "zoho_people"
];

info result;

A successful response looks like this:

{
  "response": {
    "result": { "pkId": "3000000130001", "message": "Success" },
    "message": "Data updated successfully",
    "status": 0
  }
}

To delete a different row, change the index in rows.get(0) or pick the row by any field value. To delete several rows at once, put all of their IDs in the delete list.

The tabularData Format

updateRecord accepts one tabularData object keyed by sectionId. Each section can carry three operations, and you can combine sections and operations in one call:

{
  "3000000000375": {
    "add":    [ { "Employer": "ABC", "Jobtitle": "Developer" } ],
    "update": { "3000000130015": { "Jobtitle": "Senior Developer" } },
    "delete": [ "3000000130017" ]
  }
}
  • add is an array of row objects, using the field labelNames from the components API.
  • update is an object keyed by row ID.
  • delete is an array of row IDs.

Linear fields go in a separate inputData parameter; it can be omitted when you only touch tabular rows.

The Same Call with curl

For a quick test outside Deluge:

curl -X POST "https://people.zoho.com/people/api/forms/json/employee/updateRecord" \
  -H "Authorization: Zoho-oauthtoken 1000.xxxxxxxx.yyyyyyyy" \
  --data-urlencode "recordId=3000000130001" \
  --data-urlencode 'tabularData={"3000000000375":{"delete":["3000000130017"]}}'

Note the extra json segment in the path: the read endpoints live under /api/forms/<formLinkName>/, but updateRecord lives under /api/forms/json/<formLinkName>/.

Conclusion

Deleting a subform row in Zoho People is one updateRecord call with a tabularData payload of the shape { sectionId: { delete: [rowId] } }. The only real work is collecting the three IDs, and the same payload format lets you add and update rows once you have them.