Build Your Own Addon¶
Everything on the Addons page is a service that told the platform what it can do. You can write one too β and connect it to your own instance without involving us.
When it is worth it¶
A custom addon makes sense when a plain API integration is not enough:
- Your own system, your own rules. The logic lives in your code β an ERP lookup, a scoring model, a pricing engine β and you want the flow designer to get one clean node for it instead of five integration steps.
- Reusable building blocks. Ship the same module to every instance you run, and update it centrally.
- Your own settings screen. Credentials, mappings or feature switches configured by the customer, in a UI you designed, embedded in the instance admin.
- Data that must not leave your infrastructure. The addon runs on your servers; the platform only calls it.
An addon is an ordinary HTTP service. It describes itself in a manifest, and the platform calls it while the bot is talking to a customer.
Start from the template¶
The starter template is public and MIT-licensed:
github.com/Daktela/daktela-ai-addon-template
It is a working addon with example modules, an example integration, a dynamic list, an optional configuration page, tests, Docker images and a full developer guide in its docs/ folder.
It builds two ways:
basic |
full |
|
|---|---|---|
| Modules, integrations, dynamic lists | β | β |
| Own configuration page (React) | β | β |
| Needs Node.js to build | no | yes |
Start with basic unless the customer has something to configure.
Clone it and run it β Python 3.13+ and uv are all you need:
git clone https://github.com/Daktela/daktela-ai-addon-template.git
cd daktela-ai-addon-template
uv sync --all-extras
uv run uvicorn server.main:app --reload
The service is now on http://localhost:8000 and http://localhost:8000/manifest shows what it offers.
Prefer to run it the way it ships? docker compose -f docker/compose.yaml up --build addon builds and starts the full image on port 8000, and addon-basic does the same for the modules-only image on port 8001. The edit-and-reload loop is slower than uvicorn --reload, but this is the same image you will eventually deploy.
Warning
While developing, a tunnelling service (ngrok, Cloudflare Tunnel, Tailscale Funnel and similar) can expose your local port at a public URL so your instance can reach it. These are development tools only. A production addon must run on a server with a stable public URL β your instance calls it on every conversation, so a laptop behind a tunnel is not an option. Both Docker images are ready for that; see docs/13-deployment.md in the repository.
Register it with your instance¶
Open Addons and click Add Custom Addon.

Fill in the addon's base URL and, if it expects one, an authentication header. Click Test β the platform fetches the manifest and tells you whether it could read it, so you find out before saving. Then click Save.

Info
The screenshot shows a local address because it was taken while developing against a tunnel. In production, enter the addon's real public URL.
The addon now has a card on the Addons page. Click Activate. An addon without a configuration page activates straight away; one with a configuration page usually wants to be configured first.

Whenever you change the addon's manifest β a new module, a new input, a new version β click Sync Addons to pull the change in.
Check that it works¶
Open Dialogs, edit a flow, and find your modules in the module selection, grouped under the name your manifest declared. Drop one in, connect its output ports, and run a test conversation from Test in the top toolbar.
Then open the interaction in Discussions and look at its events. Every module execution writes an event there, with the source shown as <module>::<addon code>, the message your module returned and how long it took β which is how you tell "the addon was never called" apart from "the addon was called and answered that".

Let an LLM write it for you¶
The template is designed to be handed to a coding assistant (Claude Code, Cursor, Copilot and the like) together with your requirements. Clone the repository first, open it in the assistant, and use prompts along these lines.
1 β Scaffold the addon for your domain
I have cloned the Daktela AI addon template. Read
README.mdanddocs/01-quickstart.mdto learn how this project is structured, then adapt it for my company.The addon is called <name> and it works with <the system you are integrating β e.g. our warehouse system>. Set the addon identity in
server/identity.py(code, name, description, author, icon, colour).Remove the example modules I do not need and keep the project running and its tests green. Explain what you changed and how to start the service.
2 β Add a module that calls your API
Following the pattern in
server/modules/catalog/exchange_rate.pyand the guide indocs/07-calling-external-apis.md, add a new module called <Module name>.It should call
GET https://api.example.com/orders/{order_id}with a bearer token, whereorder_idis an input attribute the flow designer fills in.Give it three output ports β success, not found and error β plus a timeout attribute wired to the timeout port. Write the order status into the conversation context so the next node can use it, and write a debug event with the raw response. Add unit tests like the existing ones.
3 β Add a settings page for credentials
Switch this addon to the
fullprofile and add a configuration page where an operator enters the API base URL and the API token, followingdocs/10-configuration-page.mdanddocs/11-persistence.md.Store the values with the existing settings store, read them in my modules instead of hard-coded constants, and make sure the addon reports itself as not configured until both values are filled in.
4 β Get it production-ready
Review this addon against
docs/13-deployment.md. Build both Docker images, check that no secrets ended up in the build, and tell me what I still need to do before I can run this on a public URL for a customer.
Tip
Point the assistant at the template's own guide rather than describing the platform to it. docs/ in the repository covers modules, output ports, integrations, dynamic lists, streaming responses, persistence, testing and deployment, and it is what keeps the generated code on the rails.
Read next¶
- The template's developer guide:
docs/in the repository - Addons overview
- API Integrations β the simpler option when you only need to call one endpoint