getApprovalDetails: the undocumented Zoho People approvals API
Zoho People’s documented API tells you a record’s approval status and not much else. getApprovalDetails returns the whole trail: every approver, when they acted, how long each took, any comments, and who’s still pending. It isn’t in the official API docs. Here’s how to call it, what comes back, and what the codes mean.
- Record ID
- getRecordByID
- Status only
- Record ID
- getApprovalDetails
- Approvers and times
- Full trail
How I came across it
Another developer brought me a question. Their client was splitting into two companies and wanted a new Zoho People organization that kept the approvals already given on existing records. I went looking for a way to pull approval details out of Zoho People and found getApprovalDetails in a reply on a Zoho community thread. Since then, someone from Zoho has added a short PDF reference to the same thread. That PDF is the closest thing to documentation there is, and this post draws on it.
As it turned out, they didn’t need it. The standard export already includes approval data. But the endpoint is too useful to leave buried in one reply, so here it is properly written up.
What the documented API gives you
Fetch a record through the documented API and you’ll see whether it’s approved, rejected or pending. That’s it. You won’t see who approved it, at which level, when, or with what comment. That’s exactly what the person on the community thread was asking for.
Calling it
This custom function calls the endpoint for one record. id is the record ID, passed in as the function’s argument.
uri = "https://people.zoho.com/people/api/getApprovalDetails";
params = Map();
params.put("recordId",id);
params.put("formId","YOUR_FORM_ID");
Response = invokeurl
[
url :uri
type :GET
parameters:params
connection:"allaccess"
];
info Response;
return "success";
Before you run it: your connection needs the ZOHOPEOPLE.forms.ALL scope. You’ll find the form ID in the address bar when you edit the form in Settings. If you’d rather not look it up, you can pass formLinkName (the form’s link name) instead of formId. You only need one of the two. If your organization is on another data center, swap the domain, for example people.zoho.eu.
What it returns
Here’s the response for a record with two approval levels, redacted. The approvals live under response → result → processed, one entry per approver who has acted. Anyone still due to act is listed under pending, and approvalTimelineSummary sums up the whole thing.
{
"response": {
"result": [
{
"currentApprovalStatus": 1,
"canceledRecord": false,
"processed": [
{
"actedInDuration": "23 Hrs 59 Mins",
"approvalStatus": 3,
"erecno": "9xxxxxxxx2",
"name": "Axxxxx Axxxxxxx",
"approvedTime": "02-10-2026 08:22 AM",
"photo": "viewPhoto?filename=4xxxxxxxxxxxx8",
"comment": "",
"employeeid": "xxx-xxx",
"email": "axxxxx.axxxxxx@xxxxx.xxx",
"zuid": 9xxxxxx2,
"approvalStatusStr": "Approved"
},
{
"actedInDuration": "3 Hrs 33 Mins",
"approvalStatus": 1,
"erecno": "9xxxxxxxxxx1",
"approverDtls": {
"roleId": "9xxxxxxxxxx9",
"name": "Human Resources Specialist",
"photo": "https://static.zohocdn.com/zohopeople/people2/images/role.dbc42533c6f8xxxxxxxx2ab775.png",
"shortName": "HR",
"email": "sxxxxx@xxxxx.xxx,xxxxx@xxxxx.xxx",
"approvertype": "Role"
},
"name": "Nxxxx Axxxxx",
"approvedTime": "02-10-2026 11:56 AM",
"photo": "viewPhoto?filename=4653xxxxx7848",
"comment": "",
"employeeid": "xxxxx",
"email": "xxxxx@xxxxx.xxx",
"zuid": 9xxxxx7,
"approvalStatusStr": "Approved"
}
],
"code": 7000,
"addedBy": {
"erecno": "9xxxxx1",
"name": "Sxxxxx Axxxxx",
"photo": "https://people.zoho.com/api/viewEmployeePhoto?filename=465xxxxx7",
"employeeid": "xxx-xxx",
"email": "xxxxx@xxxxx.xxx",
"zuid": 9xxxxx0
},
"pending": [],
"approvalSubmissionTime": "01-10-2026 08:22 AM",
"recordowner": {
"erecno": "9xxxxx1",
"name": "Sxxxx Axxxxx",
"photo": "https://people.zoho.com/api/viewEmployeePhoto?filename=4xxxxx7",
"employeeid": "xxx-xxx",
"email": "xxxxx@xxxxx.xxx",
"zuid": 9xxxxx0
},
"systemApproved": false,
"approvalAction": 0,
"approvalTimelineSummary": {
"totalDuration": "1 Day 3 Hrs",
"completedLevels": 2,
"statusDate": "02-10-2026 11:56 AM",
"durationSubLabel": "Submitted to Completed",
"totalLevels": 2,
"levelsSubLabel": "Completed",
"statusLabel": "Approved"
}
}
],
"message": "Data fetched successfully",
"uri": "/api/getApprovalDetails",
"status": 0
}
}
The status codes
currentApprovalStatus tells you where the record stands overall:
| Value | Meaning |
|---|---|
1 | Approved |
0 | Rejected |
-1 | Waiting for the next level of approval |
2 | Record cancelled |
-3 | Approval hasn’t been triggered |
And code tells you whether the call worked. Check it before you read anything else:
| Code | Meaning |
|---|---|
7000 | Success |
7352 | No data found |
7011 | The form name is invalid |
7024 | Record not found |
7326 | Permission denied |
7329 | No approval is configured or enabled for the form |
7330 | This action can’t be performed for the form |
The fields you’ll use most
| Field | What it holds |
|---|---|
name | The approver’s name |
approvalStatusStr | The status, such as approved or rejected |
approvedTime | When they acted on it |
actedInDuration | How long they took to act |
comment | Any comment they left |
approverDtls | Only there when the approval went to a role, like HR, rather than a named person |
current | Who has to approve it right now, when it’s still waiting |
pendingApprovalLevel | The level the record is currently waiting at |
pending | Approvers who haven’t acted yet |
approvalTimelineSummary | Total time from submission to completion, and levels completed out of total |
Where it’s useful
- Approval time reports.
actedInDurationtells you which level or approver is slowing things down. - Audit trails. Write who approved what, and when, into a field or another system, such as Creator or CRM.
- Chasing pending approvals. Find records where
currentApprovalStatusis-1on a schedule, and send a reminder to whoever is incurrent. - Showing approvers elsewhere. Put the approval trail in an email, a report or a client-facing view without giving people access to Zoho People.
A word of caution
As of October 2026, getApprovalDetails still isn’t in Zoho People’s API documentation. The PDF on the community thread is all there is. Because it’s not officially documented, Zoho can change or remove it without notice. Test it in your own organization before you build anything important on it, and handle the case where it stops responding the way you expect.
Building something on Zoho People?
Tell me what you’re trying to do, and I’ll tell you what’s possible.
Start a conversation