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:

ToolHow it authorizesWhen to use
Inbound webhookSecret in the request URL, rights of the creating employeeA script or external system calls portal methods
Outbound webhookA token the portal passes in the application_token fieldAn external system reacts to events in the portal
Static appThe current employee's authorization via the JS SDKYou need an interface in the portal without your own server
Server-side app with UIOAuth 2.0 in the employee's contextYou need server processing, an interface and events
Server-side app without UIFull OAuth 2.0Background 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:

bash
claude mcp add --transport http b24-dev-mcp https://mcp-dev.bitrix24.com/mcp

Second: 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:

bash
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):

bash
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:

bash
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:

bash
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.

Get API keyDocumentation

api.zukko.pro · fetch_*

Vibe coding Bitrix24: apps and webhooks with an agent · Zukko