Vibe coding for Bitrix24: apps and handlers built with an agent
How to hand an agent a Bitrix24 app or handler without getting invented methods: project rules, webhooks, pagination, tests and a session cost.
6 min · · агенты · автоматизация
Vibe coding for Bitrix24 sounds appealing: describe the task in words, the agent writes a handler, and managers get a task for every new deal. In practice such code breaks in three places: the agent invents nonexistent REST methods, writes to the live portal without checking, and ignores limits. Below is a way of working with an agent that avoids these problems, from choosing the integration type to tests and a session cost estimate. (In Russian the query is "вайб кодинг битрикс24".)
The Bitrix24 facts come from the official documentation at apidocs.bitrix24.com as of October 18, 2026. Interface names there are English; in the Russian portal check them against the real ones. What vibe coding is in general and what an hour of agent work costs, we covered in Vibe coding: what it is and what it costs.
First choose the integration type
You need to tell the agent what exactly to build. The Bitrix24 docs compare the tools for local solutions; here is the gist:
| Tool | How it authorizes | When to use |
|---|---|---|
| Inbound webhook | Secret in the request URL, rights of the creating employee | A script or external system calls portal methods |
| Outbound webhook | A token the portal passes in the application_token field | An external system reacts to events in the portal |
| Static app | The current employee's authorization via the JS SDK | You need an interface in the portal without your own server |
| Server-side app with UI | OAuth 2.0 in the employee's context | You need server processing, an interface and events |
| Server-side app without UI | Full OAuth 2.0 | Background sync and automation |
Most "I want a task created on every new deal" cases are solved by a pair of an outbound and an inbound webhook: the event arrives at your handler, and the handler calls REST. An app is needed when the solution has an interface or serves different users. The docs also include a caveat: some methods are unavailable through webhooks (interface embedding, telephony events, some chatbot events), and those need a local app.
Vibe coding Bitrix24: prepare the agent
First: give the agent the documentation. Bitrix24 has an official documentation MCP server (https://mcp-dev.bitrix24.com/mcp, no authorization), which helps the model find real methods and fields. It only serves documentation and does not see portal data. In Claude Code the connection is:
claude mcp add --transport http b24-dev-mcp https://mcp-dev.bitrix24.com/mcpSecond: put a rules file in the project root (CLAUDE.md for Claude Code, AGENTS.md for opencode and Codex). No more than ten lines, but each prevents a class of errors:
Project rules: Bitrix24 integration
- Before calling a REST method, look up its description via the b24-dev-mcp MCP. Do not invent methods or fields.
- Read the webhook URL only from the B24_WEBHOOK variable. Never write it into code, logs or commits.
- Run write methods (add, update, delete) only against the test portal (B24_ENV=test).
- Read lists page by page with a 0.5 s pause between requests. At most 50 records per call.
- For every function that calls REST, write a test with HTTP mocked.Third: set up a test portal or at least a separate pipeline, and create the webhook as a user with a limited role. Webhook requests run with the rights of the employee who created it, so an administrator's webhook gives the agent administrator rights. How to create a webhook and connect a neural network to the portal is covered in our article on integrating a neural network into Bitrix24; the one thing to remember here is that the webhook secret must not be shown or embedded in public code.
Example: a handler for "new deal"
An outbound webhook sends the event to your URL. The events documentation has two limitations the agent must know. Load is not regulated: if a thousand deals change at once, the handler gets a thousand calls. There are no retries: if your server does not respond or returns an error, Bitrix24 logs the failure and does not resend the event. For critical cases there are offline events, which you pull from the queue manually, but according to the documentation they are available only to an application (subscribed with event.bind), not to an outbound webhook. Also, authorization tokens are not always passed, so the contents of the auth key should be checked in code.
A FastAPI handler (needs the python-multipart package to parse the form):
import os
from fastapi import FastAPI, Request, HTTPException, BackgroundTasks
app = FastAPI()
APP_TOKEN = os.environ["B24_APP_TOKEN"]
def make_task(deal_id: str) -> None:
... # call tasks.task.add through the inbound webhook here
@app.post("/b24/events")
async def events(request: Request, background: BackgroundTasks):
form = await request.form()
token = form.get("auth[application_token]") or form.get("application_token")
if token != APP_TOKEN:
raise HTTPException(status_code=403)
if form.get("event") == "ONCRMDEALADD":
background.add_task(make_task, form.get("data[FIELDS][ID]"))
return {"ok": True}Check the form field names and token shape against the first real request: log the form keys (without token values) and compare with the events section of the docs. The principle is to answer 200 quickly and process in the background, so the queue does not build up and events are not lost.
For a server-side app the handler must be reachable over HTTPS, so for local development you need a tunnel to your machine or a test server. Pick a specific tool yourself; that is outside Bitrix24.
Reading big lists and limits
*.list methods return 50 records and give next in the response. For an agent writing an export, this is the core pattern:
import time
import requests
def iter_deals(webhook: str, pause: float = 0.5):
start = 0
while start is not None:
r = requests.post(
f"{webhook}/crm.deal.list.json",
json={"select": ["ID", "TITLE", "STAGE_ID"], "start": start},
timeout=30,
)
r.raise_for_status()
data = r.json()
yield from data["result"]
start = data.get("next")
if start is not None:
time.sleep(pause)The pause is not arbitrary. The cloud version limits request rate on a "leaky bucket" principle: per the docs, on plans other than Enterprise it is 2 requests per second with a threshold of 50, and exceeding it returns 503 with the code QUERY_LIMIT_EXCEEDED. One request must finish within 60 seconds. To cut the number of HTTP requests the docs suggest the batch method, which accepts up to 50 calls.
Verification: a test with HTTP mocked
Ask the agent to write tests alongside the code. For the function above:
import b24
class FakeResponse:
def __init__(self, data):
self.data = data
def raise_for_status(self):
pass
def json(self):
return self.data
def test_pagination(monkeypatch):
pages = [{"result": [{"ID": "1"}], "next": 50}, {"result": [{"ID": "2"}]}]
monkeypatch.setattr(b24.requests, "post", lambda url, json, timeout: FakeResponse(pages.pop(0)))
ids = [d["ID"] for d in b24.iter_deals("https://x/rest/1/code", pause=0)]
assert ids == ["1", "2"]The test does not replace a run on the test portal, but it catches the most common mistake: the agent forgets the second page. Before a live run, read the diff yourself and make sure it has no delete methods and no webhook URL.
If you want to skip your own code and hosting altogether, the Bitrix24 docs mention a service called Alaio Vibecode that deploys the app itself. Check its terms and capabilities with them; we did not verify them.
Model and session cost
Say the app takes a session of 1.5M input tokens and 150K output tokens. Zukko prices on October 18, 2026, $ per 1M tokens.
claude-sonnet-5-5(0.4 / 2), no cache: 1.5 × 0.4 + 0.15 × 2 = 0.6 + 0.3 = $0.90.- The same in Claude Code with cache (Anthropic format): 0.2M fresh input, 1.2M cache read, 0.1M cache write, 0.15M output. 0.2 × 0.4 + 1.2 × 0.05 + 0.1 × 0.5 + 0.15 × 2 = 0.08 + 0.06 + 0.05 + 0.3 = $0.49.
gpt-6.1-sol(0.27 / 1.32), no cache: 1.5 × 0.27 + 0.15 × 1.32 = 0.405 + 0.198 ≈ $0.60.deepseek-v4.1-flash(0.013 / 0.038), no cache: 1.5 × 0.013 + 0.15 × 0.038 = 0.0195 + 0.0057 ≈ $0.03.
The cache split is illustrative; yours will differ. Which model is more careful with REST, test on a small task. Claude Code connects with the variables ANTHROPIC_BASE_URL=https://api.zukko.pro and ANTHROPIC_AUTH_TOKEN=fetch_...; see the documentation. Create the key on the API keys page and set a daily limit.
FAQ
Can I trust the agent to write to the live portal?
Only after a run on a test portal and with a limited-role user. It is best not to generate delete methods at all.
How is a webhook different from an app?
A webhook works on behalf of one employee and suits internal scenarios. An app is needed if the solution has an interface or serves different users.
Why does the agent invent Bitrix24 methods?
Without documentation at hand the model relies on memory. Connect the documentation MCP server and require in the project rules that it be consulted.
What if the handler did not receive an event?
Bitrix24 does not retry. For critical data use offline events (this requires an application rather than an outbound webhook) or a periodic reconciliation through *.list.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- An AI agent for job hunting: a résumé tailored to the job and cover lettersWe build a small tool: you give a vacancy text and a file with your real experience, and get a tailored résumé, a letter and a list of gaps. No invented skills.
- Skills in Codex: what they are and how to write your ownA Codex skill is a folder with SKILL.md that the agent loads by description or on your call. Structure, a pytest example, and how it differs from plugins and hooks.
- MCP in Open WebUI: giving models access to external toolsOpen WebUI can connect MCP servers and hand their tools to models. We cover step-by-step setup, the limits, and what it does to token usage when you work through a gateway.
- MCP in opencode: connecting local and remote serversStep by step MCP setup for opencode: the mcp block in config, headers and OAuth, disabling servers for specific agents, and what extra tools cost.