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. You describe when the agent should use it and which inputs to collect; during a chat the agent gathers those inputs conversationally, calls your endpoint, and speaks the response back to the visitor. You can create up to ten per agent on the Integrations tab → Custom actions.

Anatomy of an action

  • Name — snake_case, e.g. get_quote. This is the tool name the model sees and the name you reference in Instructions. Built-in names (book_meeting, create_ticket…) are reserved.
  • Description — the single most important field. The agent decides to call the action purely from this text, so write it like you'd brief a new employee: "Look up the status of an order when the visitor gives an order number."
  • Method & endpointPOST (JSON body) or GET (inputs become query parameters). HTTPS only.
  • Body shape (POST) — wrapped: { "action", "agent", "conversationId", "fields": {…} }, or flat: just the fields object, for endpoints you don't control.
  • Headers — extra request headers (API versions, content hints). Not treated as secrets — put credentials in the bearer token instead, which is stored server-side and sent as Authorization: Bearer ….
  • Inputs — each becomes a field the agent fills before calling. Mark the ones it must always collect as required; describe each one so the agent knows what a valid value looks like.

How the agent collects the inputs

You don't script the questions. Each input becomes a parameter of the tool, and the agent can't call your endpoint until it has the required ones — so it asks the visitor for them naturally, in conversation, in the visitor's own language. Two things steer it:

  • The action description tells it when to start ("Look up an order's status when the visitor asks where their order is.").
  • Each input's description tells it what to ask for and what a valid answer looks like.

A required input is a gate: the agent keeps talking until it has a valid value before calling. An optional input is included only if the visitor happens to provide it.

Worked example. Action get_order_status, method GET, endpoint https://api.yourstore.com/orders, with two required inputs — order_number ("The visitor's order number, e.g. #1024") and email ("The email used at checkout"):

Visitor:  where's my order?
Agent:    Happy to check — what's your order number?
Visitor:  1024
Agent:    Thanks. And the email you used at checkout?
Visitor:  sam@example.com
Agent:    Your order #1024 shipped yesterday and should arrive Thursday.

Once the visitor gives the email, the agent has both required inputs and calls GET …/orders?order_number=1024&email=sam@example.com. It asked for both because they're required, and one at a time because that's natural — not because you scripted it. Make each input's description specific (vague descriptions make the agent ask vague questions), and if you want to guarantee it never calls with something missing, reinforce it in the agent's Instructions: "Never call get_order_status without both the order number and the checkout email — if either is missing, ask for it."

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.

Custom actions · Kelma Docs · Kelma