Build a custom action
When the built-in integrations don’t cover what you need, build a custom action. Custom actions can call any HTTPS endpoint — your own API, a third-party API, a Zapier webhook — using OAuth, API keys, or no auth.
In this guide:
- When to build custom
- Open the Action Builder
- Pick a starter template
- Configure the fields
- Test
- Save
When to build custom
- Your own API. Look up an order in your custom OMS, query your inventory system.
- A third-party API not in our integrations list. HubSpot, Intercom, Linear — anything with an HTTPS endpoint.
- A Zapier or Make webhook. Use the chatbot to fire workflows in tools we don’t directly integrate.
- Internal logic. Wrap your own business rule (
/api/eligible-for-discount) as an action.
If we have a built-in integration (Stripe, Shopify, Salesforce, Zendesk), use that — the templates handle authentication and edge cases for you.
Step 1: Open the Action Builder
On the chatbot detail page → Actions → New action. The Template Picker appears.
Screenshot: The action builder with form fields for endpoint, method, auth, schema, and prompt.
Step 2: Pick a starter template
The Template Picker has:
- HTTP GET — fetch a record by ID. Read-only, no confirmation by default.
- HTTP POST — create a record. Often confirmation-gated.
- Stripe presets — pre-configured for invoice and subscription operations. → Stripe presets.
- Shopify write-backs — pre-configured for order and inventory operations. → Shopify write-backs.
- From scratch — empty form for full control.
Pick the closest match. The Action Builder opens with that template’s fields pre-filled.
Step 3: Configure the fields
Walk through each field:
Name and description
- Name — what the bot sees. “Look up customer subscription tier” — narrate the verb + object.
- Description — when to call it. “Use this when the user asks about their plan, billing cycle, or membership level.” The clearer the description, the better the bot routes to it.
Endpoint and method
- Endpoint — the URL. Supports
{variable}placeholders for org-scoped values ({orgId},{chatbotId}) and conversation-scoped values ({userEmail}if the chat captured one). - Method —
GETfor reads,POST/PUT/PATCH/DELETEfor writes.
Authentication
- None — for public APIs.
- API key — paste the key once; it’s stored encrypted on Hilal’s backend.
- OAuth — for third-party APIs that require user-level auth. Configure the OAuth client ID, secret, and scopes; the bot triggers a one-time consent flow per user.
Headers
Add required headers like Content-Type: application/json or vendor-specific ones like Stripe-Version.
Body template
For POST/PUT/PATCH, write a JSON template:
{
"email": "{user.email}",
"subject": "{conversation.summary}",
"priority": "normal"
}Placeholders are filled at call time from the conversation context. Hilal Chatbot’s variable engine handles common ones like user.email, conversation.summary, chatbot.id.
Output mapping
Tell the bot how to interpret the response. For example, if the API returns { "data": { "id": "rec_123" } }, map responseId = data.id so the bot can reference it later.
For freeform replies (the bot just shows the response back to the user), no mapping needed.
Confirmation flag
Toggle Requires confirmation for any destructive action. → Confirmation flows.
Rate limit
Set rate_limit_per_minute. Default is conservative (10/min); raise for high-volume reads, lower for sensitive writes.
Step 4: Test
Click Test action in the Builder. You’ll get a test panel where you can plug in placeholder values and run the action manually. The response is shown raw.
If it succeeds, save. If not, check headers, auth, and endpoint.
Step 5: Save
Click Save. The action is now live for this chatbot. The bot will start considering it on the next message.
Tips
- Start with read-only actions. Get retrieval working before adding writes.
- Use idempotency keys when possible. If your backend respects the
Idempotency-Keyheader (Stripe, Shopify, etc.), the framework will send one automatically. - Test edge cases manually. What happens when the API returns 404? 500? Timeout? Document expected behavior in the action description so the bot handles it gracefully.
Troubleshooting
- Action never fires. Description may not match the user’s wording. Re-write to match common phrasings.
- Action fires too often. Description is too broad. Narrow it (“Use this only when the user explicitly asks about their billing”).
- Auth fails. OAuth scopes may be insufficient, or the API key may be wrong. Test the call with
curlfirst.