Creating advanced action flows (EAP)

Advanced action flowsare AI-generated, code-based workflows that are designed to help Zendesk admins automate complex business processes across multiple systems.


What's my plan?







All Suites

Growth, Professional, Enterprise, or Enterprise Plus







Summary: ◀▼
Advanced action flows let you automate complex workflows across systems using AI-generated code. You can create, customize, and trigger flows based on events, schedules, manual input, or webhooks. They support API integrations, pauses, durable storage, and AI actions like sentiment analysis. Use OAuth, API keys, or no-auth HTTP calls to connect external services. This helps streamline processes like approvals, ticket classification, and notifications.




Advanced action flows are AI-generated, code-based workflows
that are designed to help Zendesk admins automate complex business processes across
multiple systems.
This article contains the following topics:
Joining the Advanced Action Flows EAP
Creating an advanced action flow
Configuring advanced action flow triggers
Understanding Zendesk API support
Understanding advanced action flow states, storage, and pauses
Understanding custom fields in advanced action flows
Understanding how AI actions run in an advanced action flow
Connecting advanced action flows to external systems



Related articles
Advanced action flows API
reference
Editing and managing advanced action
flows
Monitoring and troubleshooting advanced
action flows




Joining the Advanced Action Flows EAP

Before you can create advanced action flows, an admin must opt in to the Advanced
Action Flows EAP.

To join the Advanced Action Flows EAP
In Admin Center, click
Apps and integrations in the sidebar, then select Actions > Advanced action
flows.
Select Turn on early access.
In the confirmation dialog, select I agree to accept the terms and
conditions.
Click Submit.





Creating an advanced action flow

Advanced action flows are generated by AI based on the details provided by an admin.
You can create up to 100 advanced action flows.
When creating an advanced action flow, remember that all API calls made by an
advanced action flow are attributed to the administrator who created the workflow.
This means the workflow has the same permissions and access as the creator and are
constrained by your accounts normal rate limits.
Additionally, because of execution timeouts, don't try to process a
large batch of data in a single execution. Instead, design your workflow to process
one page of data per execution and store a cursor or split the data processing
across multiple advanced action flows.


In Admin Center, click
Apps and integrations in the sidebar, then select Actions > Advanced action
flows.
Click Create flow.
Under What would you like to automate today?, either:
Click View all and select a templated prompt to use as a
starting point for common workflows. See Advanced action flow template prompts.
Enter a description of the workflow you want to automate and press
Enter. See Writing prompts to generate advanced action flows.

AI generates JavaScript in the right panel, a visual flow chart in
the middle panel, and a trigger configuration dialog. This can take a
few minutes. Within the chat, notifications will appear indicating what
it's doing. If necessary, you can click Stop at any time to
interrupt it.

Review the code and flow chart for accuracy and completeness.
Review the flow chart first. It provides the fastest way to see the
overall workflow and quickly verify the correct trigger, branches,
loops, and expected paths are present.
Then review the code, paying particular attention to:

POST operations to confirming they target the correct
object

Conditionals to verify the comparison values match
your actual field values, including exact casing

Error handling to understand what happens when a call
fails

Loop bounds to avoid infinite loops and runaway
search results



Click any node in the flow chart to jump the code editor to that
function. You can edit the code directly, using in-line Save and
Discard controls. When necessary, click Regenerate
chart to update the flow chart to your latest changes. See Advanced action flows API
reference.
If you need to modify the trigger or pause
steps, see Configuring advanced action flow triggers and Understanding advanced action flow states, storage, and pauses.

If changes are needed, refine it by describing the adjustments in the chat
panel or editing the code directly.
Click Save.
(Optional) Test the workflow and fix any
issues.
Click Publish.




Advanced action flow template prompts

The following prompt templates are available to use as starting points when
generating advanced action flows:
Require approval for high-value refunds
Daily SLA breach report
Classify incoming tickets
Sync messaging conversation ID to custom ticket field
Tag tickets by sentiment
Escalate tickets from enterprise accounts
Welcome new users





Writing prompts to generate advanced action flows

Use the following best practices for writing prompts when using AI to create
action flows:


Use clear, simple language. Keep sentences straightforward and easy
to follow, avoid unexpected technical jargon, and be direct about what you
want the flow to do.

Be specific about the workflow. State what event or conditions should
start the workflow, specify the criteria the workflow should check, describe
what actions should happen next, and mention any important outputs or
notifications that need to be part of the action flow.

Include the business context. Explain the role and technical
capabilities that the workflow is for (such as admins or agents on the IT
team), describe the process the workflow supports, and mention any systems
or tools involved.

Break complex requests into smaller parts. Start with the core logic
first. In later prompts, add in branches, approvals, and extra actions. When
refining the generated action flow, focus on one step at a time to reduce
errors and improve outcomes.

Provide examples. It can be helpful to include simple example
conditions, outcomes, and decision points. Describe how the workflow should
behave in specific situations.

Avoid ambiguity. Replace vague phrases such as "hande it
appropriately" with specific, clear instructions. Define what should happen
for each condition or branch, including exceptions and edge cases.





Configuring advanced action flow triggers

An advanced action flow trigger is the condition under which the workflow runs.
Unlike most Zendesk business rules, there is no pre-defined list of advanced action
flow triggers to select from. Instead, the AI sets the workflow's trigger type based
on your description. That means your prompt must specify how the workflow should be
initiated.
For example, you might say When a ticket is created with the tag
new-hire, create asset records and post an internal note to
the Onboarding ticket, or Every Monday at 9 am, create a Slack post in
the it-team-managers channel summarizing the unassigned laptop stock.
The following advanced action flow trigger types are supported:

Zendesk events: A ticket, user, organization, asset, or custom object
is created, updated, or deleted.
Note: Condition
filters on event-based advanced action flow triggers help ensure the
workflow runs only when it actually needs to. Without filtering
conditions, a workflow triggered on ticket creation would run for every
new ticket. See Specifying filter conditions for Zendesk event advanced action flow triggers.


Schedule: A recurring schedule, in UTC time, on which the workflow
should run. For example, Every 15 minutes, The first day of each
month, or Weekdays at 6 pm.


Manual: The workflow is initiated manually by admins or agents, with
inputs provided, as needed. If a start condition isn't specified when
creating an advanced action flow, the manual trigger is used.
Additionally, manual triggers are used to test all advanced action
flows, regardless of the final trigger used.
See Understanding parameter limits for manual advanced action flow triggers.


Web trigger: An external system calls a webhook URL.

AI agent or workflow invocation: An AI agent or other workflow
invokes the advanced action flow as a tool.


If you need to update an advanced action flow's trigger after creation, describe the
change in the AI chat panel. A set_trigger notification appears in
the chat when this happens, and the workflow's trigger is updated in the code and
visual flow chart. This method works to update all advanced action flow triggers.
However, you can directly edit a Zendesk event trigger's filter conditions, a manual
trigger's input parameters, and view or copy a webhook trigger's URL. See Editing and managing advanced action
flows.


Specifying filter conditions for Zendesk event advanced action flow triggers

Conditions on advanced action flow triggers use JMESPath, a query language for
JSON. The condition is evaluated against the event payload, and the workflow
runs only when it evaluates to true.
Example conditions in JMESPath:
High-priority tickets only: priority == "high"

High priority unsolved tickets only: priority == "high"
&& status != 'solved'

Tickets with the tag new-hire: contains (tags,
'new-hire')

A specific ticket form: ticket_form_id ==
\120001234567``

Only when the department field has a value:
custom_fields.department != null






Understanding parameter limits for manual advanced action flow triggers

The user initiating an advanced action flow manually must supply input values.
The run form validates inputs prior to running the workflow.
The following parameter types are supported: text, number, integer, Boolean,
date, user, ticket, object, file, and binary. The following parameter
limitations apply:
There can be a maximum of 20 parameters per advanced action flow.
There can be a maximum of 100 items in an array parameter.
A file or binary value can't exceed 5 MB.
A text value can have a maximum of 16,384 characters.


Parameter values are added to your code through the input
object: const ticket = await tickets.get(input.ticket_id);
const reason = input.reason;





Using web advanced action flow triggers

Zendesk webhook URLs are formatted as: POST
https://<your-subdomain>.zendesk.com/api/code-flows/web-trigger/<workflow-id>,
and is configured for a specific HTTP method. Requests using a different method
are rejected. Webhook URLscan be copied directly from the advanced action flow's
trigger card in the flow chart.
The incoming payload to the webhook is available on
input: // Body: { "employee_email": "sam@example.com", "action": "add_to_list" }
const email = input.employee_email;


Asynchronous webhook responses
When an external system calls a webhook URL, Zendesk validates the request,
enqueues the step to run, and immediately returns 200 OK with
an execution ID. It doesn't wait for the workflow to finish, and the response
never contains the workflow's result. This means webhooks are not a good fit for
request/response interactions, such as a Slack forward slash command that should
reply with an answer. Webhooks don't always run immediately.
There are two ways to handle this:
Have the advanced action flow deliver it's own answer after it runs.
Invoke the workflow from an AI agent or other workflow to return the
workflow's output inline.





Understanding AI agent and other workflow invocations

When you publish an advanced action flow to the Action Catalog, the workflow
becomes discoverable and can be invoked by:
Employee Service and Customer Service AI agents, which can select and
run advanced action flows autonomously when it matches a user's
intent
Other advanced action flows by calling it directly in the code
Action flows, where it appears as a custom action with inputs generated
from its schema.


Within the code, calling another workflow from within an advanced action flow
might look
like: // Calling another flow from within a flow.
const execution = await workflows.enrichCustomerRecord({
userId: ticket.requester_id,
});


These methods to initiate an advanced action flow are the only way to return the
workflow's output inline. Therefore, it is the recommended approach for
conversation automations, such as messaging-based communication.




Understanding Zendesk API support

Zendesk API access for advanced action flows has a deny-by-default policy. Only API
endpoints that are explicitly on the allowlist can be accessed. This approach limits
the damage a mistake or malicious flow can cause.
Additionally, for the most common endpoints with full read and write access,
pre-built helpers are provided to make them easier to use.


Zendesk API allowlist

The following table reflects which API endpoints are allowed and what type of
access is supported.








Access level
API endpoints




Full read and write access
Tickets, ticket fields, ticket forms, ticket import,
requests, users, user fields, organizations (including
memberships and subscriptions), organization fields, custom
objects, assets, approval requests, task list templates,
groups, group memberships, tags, uploads and attachments,
macros, views, triggers, automations, SLA policies,
schedules, and search


Read and create access
Help center content


Read access
Brands, custom roles, locales, routing, ticket metrics,
and satisfaction ratings


Denied (no access)
Account settings, OAuth, API tokens, sessions, webhooks,
targets, apps, and audit logs Anything not listed in this
table is denied by default.






If an advanced action flow requests a denied endpoint, the error names the
blocked API so you can identify the cause quickly.
Tip: Because webhooks and targets are denied, an advanced action flow
can't create or modify Zendesk webhooks. If you need a workflow to receive
external events, use a web trigger
instead.




Pre-built Zendesk API helpers

Although advanced action flows can use any Zendesk API in the allowlist, the
following common endpoints have been packaged into pre-built helpers that you
can use more easily:

tickets: The tickets helper covers getting, creating,
updating, deleting, searching, and listing tickets, as well as reading
and attaching task lists.

users: The users helper covers getting, creating,
updating, deleting, listing, and searching for users.

objects.<TypeName>: The objects.<TypeName>
helper covers creating, reading, updating, and deleting custom object
records.

assets.<TypeName>: The assets.<TypeName> helper
covers creating, updating, assigning, and deleting IT assets.

taskLists: The taskLists helper covers task list templates
and per-ticket task lists.

approvals: The approvals helper covers the creation of
approval requests for human sign-off.


Addtionally, you can use fetch against the Zendesk APIs to reach
organizations, SLAs, business rules, and other allowlisted resources even though
there aren't dedicated helpers for them.




Understanding advanced action flow states, storage, and pauses

Workflows often depend on variables to pass data from one function to another while
an advanced action flow is actively running. However, if a workflow pauses, the
runner is shut down entirely and local states don't survive. This means variables
are temporary within each execution of an advanced action flow.


Pausing advanced action flows

Advanced action flows can stop and wait for some event to occur or time to elapse
and then continue where it left off. A workflow can be paused for a maximum of
30 days. If the workflow fails to resume by that time, it fails. If it is
expected for a pause to take longer than 30 days, have the workflow record its
state in durable storage and use a scheduled advanced action flow to check on
it. While an advanced action flow is paused, it consumes no resources, so
waiting days for a manager's approval is inexpensive.
Resuming an advanced action flow after a pause causes the workflow to re-run from
the top, replaying completed operations from their recorded results. Any values
you need after a pause must come from input, platform call, or
durable storage. Local variables
aren't available after a pause.
The following types of pauses are supported:

pause(): Must be explicitly resumed either through the
execution history or an API call.

pause(durationMs): A period of time, up to 30 days. The
workflow resumes when the timer expires.

pause({ event, condition }): A Zendesk event that
satisfies the JMESPath condition.

pause({ event: 'approval', approval_id }): An approver
either approves or rejects an approval request.

pause({ event: 'workflow-complete, execution_id }): The
specified workflow completes running.

pause({ event: 'agent-complete, execution_id }): An
agent completes a specified task.


The following example demonstrates a pause for an
approval: if (invoice.total > 100) {
const approval = await approvals.create({
ticketId: ticket.id,
title: `Approve expense of $${invoice.total}?`,
description: `Submitted by ${requester.name} for ${invoice.description}.`,
approver: { type: 'user', id: managerId },
});

pause({ event: 'approval', approval_id: approval.id });

// Execution resumes here once decided.
if (input.approval_result.status === 'approved') {
await tickets.update(ticket.id, { status: 'solved' });
} else {
await tickets.update(ticket.id, { tags: [...ticket.tags, 'expense_rejected'] });
}
}





Storing data that must persist beyond an execution

Any values that must be accessible after an advanced action flow pauses must be
stored rather than handled as a local variable.
Consider the following when storing data:
Use storage to store values longer term for advanced
action flows.
Values in storage are stored as strings. To store
objects, use JSON.stringify() to serialize them prior
to writing them.
If the data can become stale, you can store a timestamp alongside the
value and check it in your workflow's code.
There is no locking or atomic-increment primitives that prevent stored
values being overwritten during concurrent executions. Design your
advanced action flows around this rather than relying on ordering.
Storage keys are tied to the advanced action flow's identity, not it's
version, so stored values aren't affected by editing and publishing
updates to the workflow.
When storing data, there are two scopes available:

Workflow: Default. Makes data visible to all executions
of an advanced action flow across all trigger types. Best for
per-flow state, such as cursors, deduplication keys, and
counters.


Account: Makes data visible to all advanced action flows
in your account. Should only be used for values that are truly
shared between advanced action flows.




The following example demonstrates how you might use storage to
save the date on which a ticket requester was last
notified. // Remember that we already notified this requester today.
await storage.set(`notified:${ticket.requester_id}`, new Date().toISOString());

const lastNotified = await storage.get(`notified:${ticket.requester_id}`);






Understanding custom fields in advanced action flows

To make it easier to work with custom fields in advanced action flows, custom ticket,
user, and organization fields are presented as named properties when reading the
records, but are converted back into the API's required structure for POST requests.
For
example: const ticket = await tickets.get(input.ticket_id);

// Read a custom field by its name, not its numeric id.
if (ticket.department === 'Finance') {
await tickets.update(ticket.id, { priority: 'high' });
}





Understanding how AI actions run in an advanced action flow

The AI that generates the code for advanced action flows doesn't run during a
workflows execution. However, your advanced action flow can call an AI model as an
action within the workflow. All run-time AI calls go through on function:
agents.run(). A workflow without an
agents.run() call can't send any data to any AI models under
any circumstances.
Sentiment analysis, entity extraction, omnichannel routing, classification, and
summarization are all prompt patterns of the agents.run() function.
There aren't separate helpers for sentiment or omnichannel routing. This approach
makes the code simpler and allows you to specify exactly which behavior you
need.
The following example demonstrates how you might use agents.run()
for sentiment
analysis: const sentiment = await agents.run({
prompt: `Classify the sentiment of this message as positive, negative, or neutral.
Respond with one word only.

${ticket.description}`,
});


The following example shows how omnichannel routing works by passing images and PDFs
in files within the agent.run()
call: const invoice = await agents.run({
prompt: 'Extract the invoice number, date, and total amount.',
files: [{ name: 'invoice.pdf', content: attachmentBytes }],
output: {
schema: {
type: 'object',
properties: {
invoiceNumber: { type: 'string' },
date: { type: 'string' },
total: { type: 'number' },
},
required: ['invoiceNumber', 'total'],
},
},
});

if (invoice.total > 100) {
// Route for approval.
}


For reliable machine-readable results, request structured output with a schema rather
than parsing free text.



Connecting advanced action flows to external systems

Advanced action flows can call REST APIs directly, but how you do that depends on the
external system's authentication requirements:
OAuth
API key (bearer token)
No authentication




Using registered OAuth connections

For services with a registered OAuth connection in your account, such as Slack,
Microsoft Teams, or Jira, you can authorize the connection once and then
reference it by name in your advanced action flow code. The authentication
headers are attached automatically, and no credentials appear directly in your
workflow. // The connection handles authentication; you only supply the path and body.
await connections.slack.post('/api/chat.postMessage', {
channel: '#it-alerts',
text: 'Laptop stock for MacBook Pro 14 is below 50 units.',
});





Using API key authentication

For services that use API keys or bearer tokens rather than OAuth, you must store
the credential as a secret.
When your advanced action flow needs a credential, the builder prompts you to
enter it in a secure field. Zendesk encrypts the value and places an encrypted
reference in your code that is a string beginning with
cfsec:v1:. Note that encrypted values are bound to your
account and can't be decrypted in another Zendesk account, even with identical
code. Additionally, plaintext credentials are never written to the database.
When the advanced action flow runs, it is decrypted and used.
const apiKey = await secrets.decrypt(STRIPE_API_KEY);

const charge = await http.post('https://api.stripe.com/v1/charges',
{ amount: 2000, currency: 'usd' },
{ Authorization: `Bearer ${apiKey}` },
);


A failed decryption returns a deliberately non-specific error so that trace logs
can't be used to probe the value.



Using APIs with no authentication

For fully public endpoints with no authentication requirements, use the built-in
HTTP client, which requires no
connection: const rates = await http.get('https://api.example.com/v1/public/rates');





{
"@context": "https://schema.org",
"@type": "TechArticle",
"@id": "https://support.zendesk.com/hc/en-us/articles/11149761264666-Creating-advanced-action-flows-EAP",
"url": "https://support.zendesk.com/hc/en-us/articles/11149761264666-Creating-advanced-action-flows-EAP",
"headline": "Creating advanced action flows (EAP)",
"description": "You can create and configure AI-generated, code-based workflows to automate complex business processes across multiple systems, including setting triggers, managing states, and integrating external APIs.",
"articleSection": "Product help",
"datePublished": "2026-08-19T19:28:10+00:00",
"dateModified": "2026-08-25T14:37:01.577616+00:00",
"inLanguage": "en-US",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://support.zendesk.com/hc/en-us/articles/11149761264666-Creating-advanced-action-flows-EAP"