Chatzuri
Pricing
Guides
Guides
Introduction
  1. 1Getting Started
  2. 2Your Agent
  3. 3Knowledge & Sources
  4. 4Agent actions & Tools
    • Tools & actions overview
    • Credentials & safety
    • Built-in tools
    • Messaging tools
    • E-commerce tools
    • Payments tools
    • Scheduling tools
    • Database tools
    • Cloud storage tools
    • Business & productivity tools
    • Developer tools
    • Build a custom action
    • Trigger webhooks
  5. 5Agent Tasks
  6. 6WorkflowsBeta
  7. 7Channels
  8. 8Customers & Conversations
  9. 9Run Your Team
  10. 10Developer Tools
Developer reference →Showcase →
Guides4. Agent actions & ToolsBuild a custom action
Chapter 4 · Agent actions & Tools

Build a custom action

Write a small async JavaScript function the agent can call — connect to any HTTP API, including ones not listed above.

7 min read

A custom action is a short async JavaScript function that the agent can call. Reach for one when the provider you want isn't in the catalogue, or when you want to combine a few API calls into a single named step.

You write the body of the function. Chatzuri wraps it, injects the parameters the agent supplied, decrypts your credential, runs it with a 10-second timeout, and returns the result to the agent.

The five-minute version

1

Open the action builder

On any agent: Tools & Actions → + New custom action.
2

Name it and describe what it does

The name and description are how the agent decides when to call it. Be specific — “fetch a customer's outstanding invoices” beats “invoices”.
3

Declare parameters

Each parameter has a name, type, required flag, and a description for the model. The agent fills these in at call time.
4

Pick a credential (optional)

Choose an existing credential — api key, bearer token, basic auth, webhook, or any provider credential the team has saved.
5

Write the function body

The code field is the async function body. You have access to params, credentials, and config. See the contract below.
6

Test it

The Test button runs the action with a sample payload you supply. The response is shown in the builder so you can iterate.

The execution contract

The executor wraps your code in roughly this shape:

new Function(
  'params', 'credentials', 'config',
  `return (async () => { ${YOUR_CODE} })()`,
);

That means three variables are always in scope:

  • params — the input fields the agent extracted from the conversation. Access them as params.fieldName.
  • credentials — the decrypted credential, or null if you didn't bind one. Field names depend on the credential type (see below).
  • config — any agent-specific static config you stored when installing the action.

Your code must return a JSON-serialisable value. The convention is { success: boolean, data?: any, error?: string }, but anything serializable works.

Credential field names

Which fields credentials exposes depends on the credential type:

  • http_api_key → credentials.api_key
  • http_bearer_token → credentials.bearer_token
  • http_basic_auth → credentials.username, credentials.password, credentials.api_url
  • webhook → credentials.webhook_url, credentials.secret (optional)
  • Provider-specific credentials (Notion, Stripe, etc.) → the same field names the built-in tool would receive (e.g. credentials.access_token for Notion, credentials.secret_key for Stripe).

Minimal example: hello-world

return {
  success: true,
  data: {
    message: `Hello, ${params.name || 'world'}!`,
    timestamp: new Date().toISOString(),
  },
};

Realistic example: OpenWeather

Parameters: city (string, required), units (string, optional). Credential: http_api_key.

const apiKey = credentials.api_key;
if (!apiKey) throw new Error('OpenWeather api_key required');

const city = encodeURIComponent(params.city);
const units = params.units || 'metric';

const r = await fetch(
  `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=${units}&appid=${apiKey}`
);
if (!r.ok) throw new Error(`OpenWeather ${r.status}: ${await r.text()}`);

const d = await r.json();
return {
  success: true,
  data: {
    city: d.name,
    country: d.sys?.country,
    temp: d.main?.temp,
    description: d.weather?.[0]?.description,
  },
};

What's available at runtime

Standard Web/Node APIs are available:

  • fetch, URL, URLSearchParams
  • JSON, Date, Math
  • Buffer, setTimeout, setInterval

What's banned

The save-time and run-time guardrails reject code containing:

  • require( or import( (no module loading)
  • process / child_process (no shell)
  • fs (no file system)
  • eval( or new Function( (no dynamic code generation)
Heads up
These guardrails are a regex scan plus a 10-second timeout — not a full sandbox. Don't paste in code you haven't read. Treat custom actions like any other piece of production code in your stack.

The 10-second timeout

If your code hasn't resolved after 10 seconds the action returns an error to the agent. Long-running work (e.g. video encode, large report generation) belongs in an Agent Task or a background queue, not a live action.

Ready-made templates

The action builder ships with templates you can fork:

  • Get Weather (OpenWeather) — http_api_key
  • Post to Slack (Incoming Webhook) — webhook
  • Convert Currency (Frankfurter) — no credential
  • Geocode Address (OpenStreetMap) — no credential
  • Shorten URL (TinyURL) — no credential
  • Append Note to CRM (Webhook) — webhook
  • Track Shipment (AfterShip) — http_api_key
  • Create Zendesk Ticket (REST) — http_basic_auth
  • Fetch Mixpanel Metric (JQL) — http_basic_auth
  • Create Stripe Payment Link — http_bearer_token

How the agent sees your action

The model sees the action's name, description, and the parameters you declared (each one's name, type, required flag, and description). It never sees the code or the credential. Write clear names and descriptions — that's how the agent decides whether to call your action versus a built-in one.

Previous · Agent actions & ToolsDeveloper toolsNext · Agent actions & ToolsTrigger webhooks
Chatzuri

AI-powered agents are transforming customer interactions by providing instant, intelligent responses around the clock. They help businesses reduce operational costs, improve response times, and scale support without compromising quality. These agents understand natural language, learn from conversations, and integrate with existing systems to offer personalized experiences that enhance customer satisfaction and loyalty.

Chatzuri

AI-powered agents are transforming customer interactions by providing instant, intelligent responses around the clock. They help businesses reduce operational costs, improve response times, and scale support without compromising quality. These agents understand natural language, learn from conversations, and integrate with existing systems to offer personalized experiences that enhance customer satisfaction and loyalty.

Product

  • Pricing
  • Security
  • Affiliates

Resources

  • API
  • Guides
  • Blog
  • Help

Company

  • About us
  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DPA

About

  • Teams
  • Singapore, Nairobi

© 2026 Chatzuri. All rights reserved.

Chatzuri uses AI and can make mistakes.

Terms of ServicePrivacy PolicyCookie PolicyChatzuri