Skip to main content

The problem

When an agent processes a message, it returns actions — structured instructions your backend can execute. Each action has a type field:
By default, the AI invents the action type freely. It might return support.refund.process on one run, refund_customer on the next, and process_refund_request on another. This makes your backend parsing fragile and unpredictable.

The solution

Allowed actions let you declare exactly which action types your agent can return. The AI is constrained at the model level — it cannot return a type outside your list.
Now every run is guaranteed to return only these types. Your backend can safely case/when on them.

Format

Action types follow the domain.resource.action convention: Rules:
  • Exactly 3 segments separated by dots
  • Each segment: lowercase letters, digits, underscores
  • Must start with a letter
  • Max 10 action types per agent
Valid: support.refund.process, ops.task_v2.create, billing.invoice.send Invalid: refund (1 segment), Support.Refund.Process (uppercase), support.refund. (trailing dot)

How it works

Interactive Flow Diagram

See how allowed actions flow from configuration to LLM constraint.
Under the hood, allowed actions are injected as an enum constraint in the LLM’s function calling schema:
The model is natively constrained — it’s not just a prompt instruction, it’s a schema-level guarantee. The LLM physically cannot output a value outside this list.

When to use it

Example: end-to-end

1. Create the agent with constraints:
2. Run the agent:
3. Handle the output — the type is guaranteed:
4. Or use a registry for cleaner routing:

API

Set allowed_actions when creating or updating an agent:
The response includes allowed_actions in the agent object. The webhook payload (agent_run.completed) is unchanged — output.actions[].type now contains guaranteed values.

System actions

Two action types are automatically available to all agents — you don’t need to include them in allowed_actions: System actions are internal — they are never included in webhook payloads. Your backend only receives your domain-specific actions.
Start with free-form, observe which action types the AI produces, then lock them down with allowed_actions once you’re confident in your list.