Put it to work

Custom actions

Build your own tools: the agent collects inputs, calls your endpoint, and speaks the response.

A custom action is a tool you define yourself — like a single Zapier or Make step, but the agent triggers it mid-conversation. You build the exact HTTP request (method, URL, headers, JSON body) using a mix of static values you type and {{placeholders}} the agent fills in. Then the agent calls your endpoint and speaks the response back to the visitor. Create up to ten per agent on the Integrations tab → Custom actions.

The idea that makes this powerful: some of the request is fixed (your Jira project key, an issue type, a currency), and some of it is filled by the AI at call time (a ticket summary it writes, an email it collected). You decide which is which.

1 · Inputs — the values the agent provides

An input is a named value the agent supplies each time it calls the action. Reference it anywhere in the request as {{name}}. Each input has:

  • A name — snake_case, e.g. summary, used as {{summary}}.
  • A source — the switch that makes this feel like Zapier:
    • Collect — the agent gathers it from the visitor in conversation (their email, an order number, a phone number).
    • Generate — the agent writes it itself from the conversation (a one-line ticket summary, a tidy description of the problem, a suggested priority).
  • A description — tells the agent what to ask for, or how to write it.
  • Required or optional — a required input is a gate: the agent won't call until it has a valid value.

Three built-in placeholders are always available without defining an input: {{secret}} (your stored token), {{agent_name}} and {{conversation_id}}.

2 · The request — where static meets dynamic

  • Method & URLGET, POST, PUT, PATCH or DELETE (HTTPS only). The URL can be fully static, or contain placeholders in the path, e.g. …/issue/{{issue_key}}. On GET/DELETE, any input not used in the URL is appended as a query parameter.
  • AuthenticationNone, Bearer token (sent as Authorization: Bearer <token>), or Basic (paste email:api_token, we base64-encode it — this is exactly what Jira Cloud wants). The token is stored server-side and never returned to the browser.
  • Headers — any extra headers. Values can use placeholders too, including {{secret}}.
  • JSON body (for POST/PUT/PATCH) — write the body your endpoint expects as literal JSON, and drop {{placeholders}} (inside quotes) wherever the agent should fill a value. Values are safely JSON-escaped, so a quote or newline the AI produces can never break your JSON.

Worked example — raise a Jira ticket

Suppose a visitor reports a bug the agent can't resolve. You want a ticket on the CUS board with a summary and description the agent writes.

  • Name: create_jira_ticket
  • Description: "Raise a Jira ticket when a visitor reports a bug or issue we can't resolve from the knowledge base. First get a clear picture of the problem."
  • Inputs: summary (Generate"a short one-line title for the issue") and description (Generate"a clear description of the problem in the visitor's words, with any steps to reproduce").
  • Method / URL: POST https://yourco.atlassian.net/rest/api/3/issue
  • Auth: Basic — you@yourco.com:your_api_token
  • JSON body:
{
  "fields": {
    "project": { "key": "CUS" },
    "issuetype": { "name": "Task" },
    "summary": "{{summary}}",
    "description": "{{description}}"
  }
}

The project key and issue type are static — every ticket lands on CUS as a Task. The summary and description are generated by the agent from the conversation. You never scripted a single question; the agent asks what it needs, writes the two fields, and posts the ticket. If you'd rather the agent ask the visitor for a value instead of writing it, set that input's source to Collect.

To guarantee it never calls with something missing, reinforce it in the agent's Instructions: "Never call create_jira_ticket until you understand the problem well enough to write a clear summary."

What your endpoint should return

Reply within 10 seconds. The agent speaks whatever you return:

  • JSON with a message (or reply) string — "Your quote is €120, valid 30 days." — is spoken back through the agent's own voice.
  • Any other JSON (an object or array without message) is handed to the agent as data — up to ~1,800 characters — so it can answer from the actual payload. For big collections, prefer an endpoint that returns the one item asked about rather than the whole list.
  • Anything else is passed through as plain text (first 1,800 characters).
  • A non-2xx status makes the agent apologise gracefully — the visitor never sees a raw error.

Test it before you ship it

Open the agent's Playground tab, pick your action, type the inputs by hand and run it — you'll see the exact text the model would receive, including your endpoint's real response. The lead webhook can be tested the same way.