
If you have ever managed complex business processes, you know that Workflows are the quiet backbone of any well-run business process. They keep things moving; assigning owners, sending alerts, keeping deals on track, and much more. But until now, you could not manage them via APIs. That changes with the release of Workflow APIs.
In this series, we will work through a real-world scenario together, showing you how to transition from manually managing workflows to governing them using APIs. We’ll look at Zylker Cloud Services, an IT solutions provider trying to bring order to its growing CRM automations.
Zylker’s sales process touches multiple teams and modules like Leads, Deals, Calls, Appointments, etc. Over time, different team members created their own workflows. The result is familiar to anyone who has scaled fast:
Multiple versions of what should be the same process
Old, unused workflows still running.
Now, Zylker wants to bring structure and visibility to this automation sprawl. Their system administrators are building a custom admin dashboard to monitor and manage CRM workflows, without needing deep CRM expertise.
They want to:
Display a real-time list of all workflows with their status
Gain insights into workflow distribution across modules
Identify inactive or outdated workflows that may need cleanup.
However, the CRM UI only allows viewing one workflow at a time. There is no consolidated view to see all workflows, their triggers, and their status across modules. That makes auditing and governance tedious and error-prone, especially at scale.
This is exactly what the Workflow APIs solve. With this, they can:
Audit all existing workflows.
Review how and when they trigger.
Identify which modules and actions are supported before creating new rules or updating existing ones.
Update existing rules and create new rules.
Delete the rules that are no longer needed.
You can not build a dynamic admin dashboard or an automated audit system for Workflows through just clicks. But you can do this now, with Workflow APIs.
Before changing anything, we need to understand what we are working with. How many workflows do we have? What do they do? How many more can we create?
To get a complete inventory of Workflow rules, we can use the GET Workflow Rules API. This API returns a list of all the Workflow Rules configured for the CRM account.
GET {api-domain}/crm/v8/settings/automation/workflow_rules
This initial audit acts like a master list, giving us an overall picture. It helps understand the scope of the automation landscape and identify obvious redundancies, like multiple workflows with similar names or purposes.
{ "workflow_rules": [ { "created_time": "2024-01-15T14:20:30+05:30", "execute_when": { "details": { "trigger_module": { "api_name": "Deals", "id": "4876876000000002181" }, "repeat": false }, "type": "create_or_edit" }, "editable": true, "module": { "api_name": "Deals", "id": "4876876000000002181" }, "deprecated": false, "deletable": true, "description": "Alert VP of Sales for high-value opportunities", "source": "crm", "created_by": { "name": "Matthew Mayers", "id": "4876876000001360001" }, "last_executed_time": null, "modified_time": "2024-01-23T12:23:12+05:30", "name": "VP Alert - High Value Deal", "modified_by": { "name": "Matthew Mayers", "id": "4876876000001360001" }, "lock": { "locked_by": null, "message": null, "status": false }, "id": "4876876000016390024", "category": "default", "conditions": [ { "sequence_number": 1, "instant_actions": { "actions": [ { "related_details": null, "name": "VP notified", "details": { "module": { "api_name": "Deals", "id": "4876876000000002181" } }, "id": "4876876000016390063", "type": "field_updates" }, { "related_details": { "best_time": true }, "name": "High value deal alert", "id": "4876876000016390015", "type": "email_notifications" } ] }, "scheduled_actions": [ { "execute_after": { "period": "business_days", "unit": 1 }, "id": "4876876000016390074", "actions": [ { "related_details": null, "name": "Confirm VP follow-up", "id": "4876876000016390067", "type": "tasks" } ] } ], "criteria_details": { "relational_criteria": { "module_selection": null, "criteria": null, "module": null }, "criteria": { "group_operator": "AND", "group": [ { "comparator": "equal", "field": { "api_name": "Amount", "id": "4876876000000002557" }, "type": "value", "value": "50000" }, { "comparator": "equal", "field": { "api_name": "Stage", "id": "4876876000000002565" }, "type": "value", "value": "Negotiation/Review" } ] } }, "id": "4876876000016390025" } ], "status": { "active": true } }, { "id": "4876876000012015001", "name": "Lead Assignment - North Region", "module": {"api_name": "Leads"}, "status": {"active": true}, "execute_when": {"type": "create"}, "last_executed_time": "2025-10-14T11:56:20+05:30" // ... other keys omitted for brevity }, { "id": "4876876000012020001", "name": "Lead Assignment - South Region", "module": {"api_name": "Leads"}, "status": {"active": true}, "execute_when": {"type": "create"}, "last_executed_time": "2025-10-14T10:30:15+05:30" // ... other keys omitted for brevity } // ... additional workflows ], "info": { "per_page": 200, "count": 71, "page": 1, "more_records": false } } |
The response gives us a comprehensive overview of all configured workflows. For each rule, we get the metadata including its unique ID, name, description, the module it operates on, its activation status, and details about when it triggers. We also get audit information like creation timestamps and which user made changes.
When you have hundreds of workflows, pagination helps. The response includes an info object with pagination details:
count: The number of workflows on the current page
per_page: The maximum number of records per page (default and max is 200)
page: The current page number
more_records: Indicates if there are additional records to fetch.
If the more_records key is true, we can retrieve the next page by using the page parameter in the request.
While getting all workflows gives you the big picture, we may often want to focus on specific areas. This API offers several parameters to narrow down our search:
Parameter type | Description |
module | Filters workflows by the primary module they operate on. |
trigger_module | Filters by related modules that can trigger workflows. Use this when you want workflows that are triggered by changes in related records. |
execute_on | Filters by the specific action that triggers the workflow. |
status_active | Filters by activation status to see only active or inactive workflows. Useful for audits and cleanup operations. |
filter | Searches workflows by name using a JSON filter. |
page | Specifies which page of results to return. Use this for pagination when you have a large number of workflows. |
per_page | Limits the number of workflows returned per page. The default and maximum value is 200. |
sort_by | Sorts the workflows based on a specific field. The only supported value is modified_time. |
sort_order | Sorts the workflows in ascending (asc) or descending (desc) order. |
include_inner_details | Includes the inner details like conditions and actions of the workflows in the response. |
For example, to find all active lead workflows containing "Assignment" in their name, use:
Here is the API-call-ready version of the same, after URL encoding the filter value:
Now, if you inspect the response closely, you can see that we have two similar workflows: "Lead Assignment - North Region" and "Lead Assignment - South Region." And there is also an older workflow named "VP Alert - High Value Deal."
This workflow was created almost a year ago by a former team member, and it has not been modified for a long time. Is it still relevant? What exactly does it do? What criteria define a "high-value deal," and who exactly gets notified?
To answer these questions and understand the workflow's complete logic, we must examine it closely using the Get a Workflow API. This API returns the full configuration including all conditions, criteria thresholds, and specific actions for an individual workflow.
GET {api-domain}/crm/v8/settings/automation/workflow_rules/4876876000016390024
Here, 4876876000016390024 is the unique ID of the Workflow rule whose details we want to fetch, obtained from the response of Get all Workflows API.
{ "workflow_rules": [ { "created_time": "2024-01-15T14:20:30+05:30", "execute_when": { "details": { "trigger_module": { "api_name": "Deals", "id": "4876876000000002181" }, "repeat": false }, "type": "create_or_edit" }, "editable": true, "module": { "api_name": "Deals", "id": "4876876000000002181" }, "deprecated": false, "deletable": true, "description": "Alert VP of Sales for high-value opportunities", "source": "crm", "created_by": { "name": "Matthew Mayers", "id": "4876876000001360001" }, "last_executed_time": null, "modified_time": "2024-01-23T12:23:12+05:30", "name": "VP Alert - High Value Deal", "modified_by": { "name": "Matthew Mayers", "id": "4876876000001360001" }, "lock": { "locked_by": null, "message": null, "status": false }, "id": "4876876000016390024", "category": "default", "conditions": [ { "sequence_number": 1, "instant_actions": { "actions": [ { "related_details": null, "name": "VP notified", "details": { "module": { "api_name": "Deals", "id": "4876876000000002181" } }, "id": "4876876000016390063", "type": "field_updates" }, { "related_details": { "best_time": true }, "name": "High value deal alert", "id": "4876876000016390015", "type": "email_notifications" } ] }, "scheduled_actions": [ { "execute_after": { "period": "business_days", "unit": 1 }, "id": "4876876000016390074", "actions": [ { "related_details": null, "name": "Confirm VP follow-up", "id": "4876876000016390067", "type": "tasks" } ] } ], "criteria_details": { "relational_criteria": { "module_selection": null, "criteria": null, "module": null }, "criteria": { "group_operator": "AND", "group": [ { "comparator": "equal", "field": { "api_name": "Amount", "id": "4876876000000002557" }, "type": "value", "value": "50000" }, { "comparator": "equal", "field": { "api_name": "Stage", "id": "4876876000000002565" }, "type": "value", "value": "Negotiation/Review" } ] } }, "id": "4876876000016390025" } ], "status": { "active": true } }, { "id": "4876876000012015001", "name": "Lead Assignment - North Region", "module": {"api_name": "Leads"}, "status": {"active": true}, "execute_when": {"type": "create"}, "last_executed_time": "2025-10-14T11:56:20+05:30" // ... other keys omitted for brevity }, { "id": "4876876000012020001", "name": "Lead Assignment - South Region", "module": {"api_name": "Leads"}, "status": {"active": true}, "execute_when": {"type": "create"}, "last_executed_time": "2025-10-14T10:30:15+05:30" // ... other keys omitted for brevity } // ... additional workflows ... ], "info": { "per_page": 200, "count": 71, "page": 1, "more_records": false } } |
The detailed response gives us a complete blueprint of the workflow. We can now see the exact business logic: the workflow triggers when deals are edited and meet two specific conditions; when the amount equals exactly $50,000 AND the stage is Negotiation/Review.
More importantly, we can see all the actions that execute: an immediate field update to mark deals as "VP notified," an email notification sent at the optimal time, and a follow-up task scheduled for one business day later. Here's what is really interesting about this detail; this workflow has never actually executed, despite being active for nearly a year, because the last_executed_time is null in the response.
Now we are left with some important questions. Is that $50,000 threshold too narrow? What if a $49,000 deal is just as important? And is the VP still the right person to alert? Are there additional stakeholders who should be notified beyond just the VP? These are the type of questions you can start answering once you inspect your workflows closely.
Before making any changes, we must understand our automation capacity and how workflows are distributed across the organization. The Workflow APIs provide two key endpoints for this:
This API provides a comprehensive view of your organization's workflow capacity across multiple dimensions.
Sample Request:
GET {api-domain}/crm/v8/settings/automation/workflow_rules/actions/rules_count
Sample Response:
{ "rules_count": { "scheduled_actions_per_rule_limit": 5, "total_rules_limit": 2500, "active_rules_configured": 71, "rules_per_process_limit": 10, "total_actions_per_rule_limit": 50, "total_rules_limit_per_module": 125, "active_rules_limit": 2000, "total_rules_configured": 82, "active_rules_limit_per_module": 75 } } |
This response gives the following information:
Total Capacity: Zylker has a generous limit of 2,500 total workflows, with only 82 currently configured. This means that they are using just 3 percent of their total capacity.
Active Workflows: There are 71 active workflows, well below their 2,000 active workflow limit
Module-level Limits: Each module can support up to 125 total workflows, with 75 of those allowed to be active simultaneously.
Action Limits: Each condition in the Workflow can contain up to 50 total actions, with a maximum of five scheduled actions.
For Zylker, this is excellent news. Only 71 active workflows out of a 2,000 limit. This means we have substantial room for growth and can confidently create new workflows without worrying about capacity constraints.
This API tells you exactly how many workflow rules you have in each module. It shows both the total number of rules and how many are currently active. This helps you see where your automations are concentrated and where you might be missing opportunities.
Sample request:
GET {api-domain}/crm/v8/settings/automation/workflow_rules/actions/module_specific_count
Sample Response:
{ "module_specific_count": [ { "active_rules_configured": 2, "module": { "api_name": "Products", "id": "4876876000000002213" }, "total_rules_configured": 2 }, { "active_rules_configured": 2, "module": { "api_name": "Deals", "id": "4876876000000002181" }, "total_rules_configured": 2 }, { "active_rules_configured": 4, "module": { "api_name": "Contacts", "id": "4876876000000002179" }, "total_rules_configured": 5 }, { "active_rules_configured": 2, "module": { "api_name": "Appointments__s", "id": "4876876000002362026" }, "total_rules_configured": 3 }, { "active_rules_configured": 4, "module": { "api_name": "Calls", "id": "4876876000000033015" }, "total_rules_configured": 5 }, { "active_rules_configured": 43, "module": { "api_name": "Leads", "id": "4876876000000002175" }, "total_rules_configured": 51 }, { "active_rules_configured": 14, "module": { "api_name": "Emails", "id": "4876876000000014163" }, "total_rules_configured": 15 } ] } |
Looking at this response, we can see 43 active workflows in Leads but only two in Deals. This tells us that Zylker is heavily focused on lead management but might be missing opportunities to automate their sales process later in the pipeline.
Together, these two APIs give a complete picture of the automation capacity and distribution.
Now that we have our foundation, we are ready to start building and refining.
In the next part of this Kaizen series, we will move from discovery to design. We’ll use the Workflow Configuration, Create, and Update APIs to standardize Zylker’s automation management, create new workflow rules, and update existing ones for consistency and efficiency.
We hope that you find this post on Workflow APIs useful. If you have any feedback, or if there are any pain-points that you would like us to address in our Kaizen series, please let us know in the comments, or reach out to us via support@zohocrm.com. We will be happy to help!
Until we meet again next Friday, Happy coding!
