How To Delete Rows in a Zoho People Tabular Section (Subform) with the API
Published on September 9, 2026

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.ALLscope. Older docs useauthtokenin the URL; that method is deprecated, so useAuthorization: Zoho-oauthtoken ...or a Connection instead. - The
recordIdof 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 need | Where it comes from | Example |
|---|---|---|
formLinkName | Fetch Forms API: GET /people/api/forms | employee |
sectionId | Form Components API: GET /people/api/forms/employee/components?version=2. Tabular sections have isTabular: true and their own sectionId | 3000000000375 (Work Experience) |
tabular.ROWID | Fetch Record API: GET /people/api/forms/employee/getRecordByID?recordId=.... Rows are under tabularSections, keyed by section name | 3000000130017 |
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" ]
}
}addis an array of row objects, using the fieldlabelNames from the components API.updateis an object keyed by row ID.deleteis 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.
