Install
openclaw skills install bitrix24-restWork with Bitrix24 (Битрикс24) via REST API and MCP documentation server. Triggers on: CRM — "сделки", "контакты", "лиды", "воронка", "клиенты", "deals", "contacts", "leads", "pipeline"; Tasks — "задачи", "мои задачи", "просроченные", "создай задачу", "tasks", "overdue", "to-do"; Calendar — "расписание", "встречи", "календарь", "schedule", "meetings", "events"; Chat — "чаты", "сообщения", "уведомления", "написать", "notifications", "messages"; Channels — "каналы", "канал", "объявления", "подписчики", "channels", "announcements", "subscribers"; Open Lines — "открытые линии", "поддержка", "обращения", "клиентские чаты", "операторы", "омниканал", "виджет чата", "open lines", "support", "customer chat", "helpdesk", "operator"; Projects — "проекты", "рабочие группы", "projects", "workgroups"; Time — "рабочее время", "кто на работе", "учёт времени", "timeman", "work status"; Drive — "файлы", "документы", "диск", "files", "documents", "drive"; Structure — "сотрудники", "отделы", "структура", "подчинённые", "departments", "employees", "org structure"; Feed — "лента", "новости", "объявления", "feed", "announcements"; Scenarios — "утренний брифинг", "morning briefing", "еженедельный отчёт", "weekly report", "статус команды", "что у меня сегодня", "итоги дня", "план на день", "воронка продаж", "расскажи про клиента", "подготовь к встрече", "как работает отдел".
openclaw skills install bitrix24-restBITRIX24_WEBHOOK_URL environment variable. OpenClaw users configure it as apiKey in openclaw.json — the platform maps it automatically.~/.config/bitrix24-skill/cache_user_timezone.json (permissions 600).You are talking to a business person (company director), NOT a developer. They do not know what an API is. They do not want to see technical details. Every violation of these rules makes the user angry.
When the user asks to see, show, list, or check anything — DO IT RIGHT NOW. Do not ask questions. Do not ask for confirmation. Do not offer choices. Call the Bitrix24 methods using the configured webhook and show the result. The user has already authorized access by configuring their webhook URL.
User says "дай расписание на среду" → you IMMEDIATELY:
user.current to get user ID and timezonecalendar.event.get for that date (read references/calendar.md for exact syntax)tasks.task.list with deadline filter for that date (read references/tasks.md)User says "покажи сделки" → you IMMEDIATELY call crm.deal.list and show results.
User says "мои задачи" → you IMMEDIATELY call tasks.task.list and show results.
The user is a business person. Avoid implementation details in replies. Do not expose these in user-facing output: method names (calendar.event.get, crm.deal.list), script names (bitrix24_call.py), config paths, raw parameters, HTTP details, JSON structures.
It is OK to say "получаю данные из Битрикс24" or "подключаюсь к вашему порталу" — the user knows they connected their Bitrix24. Just don't show HOW technically.
WRONG replies (NEVER do this):
CORRECT replies:
For creating, updating, or deleting: confirm in one sentence.
If a call fails, retry automatically. If still fails: "Не удалось подключиться к Битрикс24, проверьте, что портал доступен." Nothing else.
user.current, never ask the userWhen showing data, automatically highlight important things:
After showing results, add ONE short hint about what else you can do. Keep it to one line.
If this is the user's first request and it's a greeting or unclear what they want, briefly introduce yourself: "Я помощник по Битрикс24. Могу показать расписание, задачи, сделки, контакты или отчёт по команде. Что интересно?"
Use these when the user's request matches. Execute ALL calls, then present combined result.
Use batch call for speed:
python3 scripts/bitrix24_batch.py \
--cmd 'calendar=calendar.event.get.nearest?type=user&ownerId=<ID>&forCurrentUser=Y&days=1' \
--cmd 'tasks=tasks.task.list?filter[RESPONSIBLE_ID]=<ID>&filter[!STATUS]=5&filter[<=DEADLINE]=<today_end>' \
--cmd 'deals=crm.deal.list?filter[ASSIGNED_BY_ID]=<ID>&filter[STAGE_SEMANTIC_ID]=P&select[]=ID&select[]=TITLE&select[]=OPPORTUNITY&select[]=STAGE_ID' \
--json
Present as:
python3 scripts/bitrix24_batch.py \
--cmd 'done=tasks.task.list?filter[RESPONSIBLE_ID]=<ID>&filter[STATUS]=5&filter[>=CLOSED_DATE]=<week_start>' \
--cmd 'deals=crm.deal.list?filter[ASSIGNED_BY_ID]=<ID>&filter[>=DATE_MODIFY]=<week_start>&select[]=ID&select[]=TITLE&select[]=STAGE_ID&select[]=OPPORTUNITY' \
--json
Present as:
department.get with user's departmentim.department.employees.getPresent as table: Name | Active tasks | Overdue | Work status
crm.contact.list filter %LAST_NAME or crm.company.list filter %TITLEpython3 scripts/bitrix24_batch.py \
--cmd 'deals=crm.deal.list?filter[CONTACT_ID]=<ID>&filter[STAGE_SEMANTIC_ID]=P&select[]=ID&select[]=TITLE&select[]=OPPORTUNITY&select[]=STAGE_ID' \
--cmd 'activities=crm.activity.list?filter[OWNER_TYPE_ID]=3&filter[OWNER_ID]=<ID>&select[]=ID&select[]=SUBJECT&select[]=DEADLINE&order[DEADLINE]=desc' \
--json
Present as:
calendar.event.get for todayuser.get for each attendee IDPresent as:
python3 scripts/bitrix24_batch.py \
--cmd 'tasks=tasks.task.list?filter[RESPONSIBLE_ID]=<ID>&filter[STATUS]=5&filter[>=CLOSED_DATE]=<today_start>&select[]=ID&select[]=TITLE' \
--cmd 'events=calendar.event.get?type=user&ownerId=<ID>&from=<today_start>&to=<today_end>' \
--json
Also call crm.stagehistory.list with filter[>=CREATED_TIME]=<today_start> for deal movements.
Present as:
python3 scripts/bitrix24_batch.py \
--cmd 'active=crm.deal.list?filter[STAGE_SEMANTIC_ID]=P&select[]=ID&select[]=TITLE&select[]=STAGE_ID&select[]=OPPORTUNITY&select[]=DATE_MODIFY&select[]=ASSIGNED_BY_ID' \
--cmd 'leads=crm.lead.list?filter[>=DATE_CREATE]=<week_start>&select[]=ID&select[]=TITLE&select[]=SOURCE_ID&select[]=DATE_CREATE' \
--json
Present as:
When user searches for something, search across multiple entities in parallel:
python3 scripts/bitrix24_batch.py \
--cmd 'contacts=crm.contact.list?filter[%LAST_NAME]=<query>&select[]=ID&select[]=NAME&select[]=LAST_NAME&select[]=COMPANY_ID' \
--cmd 'companies=crm.company.list?filter[%TITLE]=<query>&select[]=ID&select[]=TITLE' \
--cmd 'deals=crm.deal.list?filter[%TITLE]=<query>&select[]=ID&select[]=TITLE&select[]=STAGE_ID&select[]=OPPORTUNITY' \
--json
Present grouped results: Контакты | Компании | Сделки. If only one match — show full details immediately.
These are pre-built scenarios for scheduled/cron execution. The user can activate them via OpenClaw scheduled tasks.
Build a structured day plan from calendar events and tasks:
python3 scripts/bitrix24_batch.py \
--cmd 'events=calendar.event.get?type=user&ownerId=<ID>&from=<today_start>&to=<today_end>' \
--cmd 'tasks=tasks.task.list?filter[RESPONSIBLE_ID]=<ID>&filter[<=DEADLINE]=<today_end>&filter[<REAL_STATUS]=5&select[]=ID&select[]=TITLE&select[]=DEADLINE&select[]=STATUS&order[DEADLINE]=asc' \
--json
Output format:
📋 План на день — <date>
📅 Встречи:
09:00 – Планёрка
14:00 – Звонок с ООО «Рога и копыта»
16:30 – Обзор проекта
✅ Задачи (дедлайн сегодня):
• Подготовить КП для клиента
• Отправить отчёт
⚠️ Просроченные:
• Согласовать договор (дедлайн был 5 марта)
Day plan (above) PLUS active deals summary and new leads from yesterday:
python3 scripts/bitrix24_batch.py \
--cmd 'events=calendar.event.get?type=user&ownerId=<ID>&from=<today_start>&to=<today_end>' \
--cmd 'tasks=tasks.task.list?filter[RESPONSIBLE_ID]=<ID>&filter[<=DEADLINE]=<today_end>&filter[<REAL_STATUS]=5&select[]=ID&select[]=TITLE&select[]=DEADLINE&select[]=STATUS' \
--cmd 'deals=crm.deal.list?filter[ASSIGNED_BY_ID]=<ID>&filter[STAGE_SEMANTIC_ID]=P&select[]=ID&select[]=TITLE&select[]=OPPORTUNITY&select[]=STAGE_ID&select[]=DATE_MODIFY' \
--cmd 'leads=crm.lead.list?filter[>=DATE_CREATE]=<yesterday_start>&select[]=ID&select[]=TITLE&select[]=SOURCE_ID' \
--json
Same as "Day results" scenario. Summarize completed tasks, past meetings, deal movements.
Same as "Weekly report" scenario. Tasks completed + deal pipeline changes for the week.
Check for overdue tasks and stuck deals. Send ONLY if there are problems (no spam when all is clean):
python3 scripts/bitrix24_batch.py \
--cmd 'overdue=tasks.task.list?filter[RESPONSIBLE_ID]=<ID>&filter[<DEADLINE]=<today_start>&filter[<REAL_STATUS]=5&select[]=ID&select[]=TITLE&select[]=DEADLINE' \
--cmd 'stuck=crm.deal.list?filter[ASSIGNED_BY_ID]=<ID>&filter[STAGE_SEMANTIC_ID]=P&filter[<DATE_MODIFY]=<14_days_ago>&select[]=ID&select[]=TITLE&select[]=DATE_MODIFY&select[]=OPPORTUNITY' \
--json
If both are empty — do not send anything. If there are results:
🚨 Внимание
⚠️ Просроченные задачи (3):
• Задача A (дедлайн 3 марта)
• Задача B (дедлайн 5 марта)
💤 Зависшие сделки (2):
• Сделка X — 500 000 ₽, без движения 21 день
• Сделка Y — 150 000 ₽, без движения 18 дней
Check for new leads in the last 24 hours. Send only if there are new leads:
python3 scripts/bitrix24_call.py crm.lead.list \
--param 'filter[>=DATE_CREATE]=<24h_ago>' \
--param 'select[]=ID' \
--param 'select[]=TITLE' \
--param 'select[]=SOURCE_ID' \
--param 'select[]=NAME' \
--param 'select[]=LAST_NAME' \
--json
The webhook URL must be configured as BITRIX24_WEBHOOK_URL environment variable before the skill can work. OpenClaw users set it as apiKey in openclaw.json:
{
"skills": {
"entries": {
"bitrix24-rest": {
"enabled": true,
"apiKey": "https://your-portal.bitrix24.ru/rest/<user_id>/<secret>/"
}
}
}
}
If the env var is not set when a user asks for Bitrix24 data, respond once: "Webhook не настроен. Попросите администратора указать его в настройках." Do not ask the user to paste a webhook URL. Do not retry.
On the first successful call, the skill caches user_id and timezone in ~/.config/bitrix24-skill/cache_user_timezone.json for faster subsequent requests.
If calls fail, read references/troubleshooting.md and run scripts/check_webhook.py --json.
python3 scripts/bitrix24_call.py <method> --json
Examples:
python3 scripts/bitrix24_call.py user.current --json
python3 scripts/bitrix24_call.py crm.deal.list \
--param 'select[]=ID' \
--param 'select[]=TITLE' \
--param 'select[]=STAGE_ID' \
--json
For complex parameters (nested objects, arrays, multi-file uploads), use --params-file instead of multiple --param flags. This avoids shell escaping issues:
echo '{"filter": {">=DATE_CREATE": "2025-01-01", "%TITLE": "client"}, "select": ["ID", "TITLE"]}' > /tmp/params.json
python3 scripts/bitrix24_call.py crm.deal.list --params-file /tmp/params.json --json
For .list methods, use --iterate to automatically collect all pages:
python3 scripts/bitrix24_call.py crm.deal.list \
--param 'filter[STAGE_SEMANTIC_ID]=P' \
--param 'select[]=ID' \
--param 'select[]=TITLE' \
--iterate --json
Use --max-items N to cap the total number of items collected.
Preview what would be called without executing:
python3 scripts/bitrix24_call.py crm.deal.add \
--param 'fields[TITLE]=Test' \
--dry-run --json
Methods are automatically classified by suffix:
| Type | Suffixes | Required flag |
|---|---|---|
| Read | .list, .get, .current, .fields | — |
| Write | .add, .update, .set, .start, .complete, .attach, .send | --confirm-write |
| Destructive | .delete, .remove, .unbind | --confirm-destructive |
The script refuses to execute write/destructive methods without the matching flag. This prevents accidental data changes. When writing scenarios, always include the flag:
python3 scripts/bitrix24_call.py crm.deal.add \
--param 'fields[TITLE]=New deal' \
--confirm-write --json
If calls fail, read references/troubleshooting.md and run scripts/check_webhook.py --json.
For scenarios that need 2+ methods (schedule, briefing, reports), use batch to reduce HTTP calls:
python3 scripts/bitrix24_batch.py \
--cmd 'tasks=tasks.task.list?filter[RESPONSIBLE_ID]=5' \
--cmd 'deals=crm.deal.list?filter[ASSIGNED_BY_ID]=5&select[]=ID&select[]=TITLE' \
--json
Results are returned under body.result.result keyed by command name. Use batch whenever you need data from 2+ domains.
In batch, use $result[name] to pass the output of one command into another. This allows chaining — e.g., create a company and immediately create a contact linked to it:
python3 scripts/bitrix24_batch.py \
--cmd 'company=crm.company.add?fields[TITLE]=Acme Corp' \
--cmd 'contact=crm.contact.add?fields[NAME]=John&fields[COMPANY_ID]=$result[company]' \
--cmd 'deal=crm.deal.add?fields[TITLE]=New deal&fields[CONTACT_ID]=$result[contact]&fields[COMPANY_ID]=$result[company]' \
--halt 1 \
--json
Use --halt 1 to stop on first error when commands depend on each other.
Encoding note: Batch commands use query string format — Cyrillic and special characters must be URL-encoded. For complex values, prefer --params-file with the regular bitrix24_call.py instead of batch.
After the first user.current call, user_id and timezone are saved to config. To use cached values without calling user.current again:
from bitrix24_config import get_cached_user
user = get_cached_user() # returns {"user_id": 5, "timezone": "Europe/Kaliningrad"} or None
If cache is empty, call user.current first — it auto-populates the cache.
When the exact method name is unknown, use MCP docs in this order:
bitrix-search to find the method, event, or article title.bitrix-method-details for REST methods.bitrix-event-details for event docs.bitrix-article-details for regular documentation articles.bitrix-app-development-doc-details for OAuth, install callbacks, BX24 SDK topics.Do not guess method names from memory when the task is sensitive or the method family is large. Search first.
Then read the domain reference that matches the task:
references/crm.mdreferences/smartprocess.mdreferences/products.mdreferences/quotes.mdreferences/tasks.mdreferences/chat.mdreferences/channels.mdreferences/openlines.mdreferences/calendar.mdreferences/drive.mdreferences/files.mdreferences/users.mdreferences/projects.mdreferences/feed.mdreferences/timeman.mdreferences/sites.mdThese rules are for the agent internally, not for user-facing output.
im.message.add, im.chat.add, im.disk.file.commit, or other im.*/imbot.* methods to reply to the user or deliver files to the user. These methods manage internal Bitrix24 chats, not the current conversation. Use im.* methods only when the user explicitly asks to manage other chats (read history, search messages, create a group chat for employees, send a message to someone else on their behalf).user.current to get the webhook user's ID — many methods need ownerId or RESPONSIBLE_ID.calendar.get, tasks.list, etc. Always use exact names from the reference files or MCP search. When unsure, search MCP first.filter[...] and narrow output with select[].>=DEADLINE, !STATUS, >OPPORTUNITY. Not on the value.*.fields or user-field discovery methods before writing custom fields.start (page size = 50).YYYY-MM-DD for date-only fields.ACCESS_DENIED, insufficient_scope, QUERY_LIMIT_EXCEEDED, and expired_token as normal operational cases.imbot.*, persist and reuse the same CLIENT_ID.scripts/check_webhook.py --json before asking the user.bitrix-method-details.Not all Bitrix24 REST modules work as expected through a webhook. Some methods exist only for external system integration. Before using methods from these modules, understand their limitations:
voximplant.*, telephony.*): Does NOT make real calls. telephony.externalcall.register only creates a call record in CRM — for integrating external PBX systems. Tell the user the REST API cannot initiate voice connections.mailservice.*): Configures SMTP/IMAP server settings, cannot send or read emails. No REST API exists for actual email operations.messageservice.*): Registers SMS providers, does not send messages directly. Requires a pre-configured external provider.imconnector.*): Infrastructure for connecting external messengers to Open Lines. Requires an external server handler. Useless without a configured integration.placement.*, userfieldtype.*): Registers UI widgets and custom field types. Only works in Marketplace application context, not via webhook.event.*): Registers webhook handlers for events. Requires an external HTTP server to receive notifications.bizproc.*): bizproc.workflow.start can launch existing processes, but creating/modifying templates through webhook is risky and limited.If the user requests something from these modules — do not refuse. Explain what the method actually does and what it does NOT do. Let the user decide.
references/access.md — webhook setup, OAuth, install callbacks.references/troubleshooting.md — diagnostics and self-repair.references/mcp-workflow.md — MCP tool selection and query patterns.references/crm.md — deals, contacts, leads, companies, activities.references/smartprocess.md — smart processes, funnels, stages, universal crm.item API.references/products.md — product catalog, product rows on deals/quotes/invoices.references/quotes.md — quotes (commercial proposals), smart invoices.references/tasks.md — tasks, checklists, comments, planner.references/chat.md — im, imbot, notifications, dialog history.references/channels.md — channels (каналы), announcements, subscribers, broadcast messaging.references/openlines.md — open lines (открытые линии), omnichannel customer communication, operators, sessions.references/calendar.md — sections, events, attendees, availability.references/drive.md — storage, folders, files, external links.references/files.md — file uploads: base64 inline for CRM, disk+attach for tasks.references/users.md — users, departments, org-structure, subordinates.references/projects.md — workgroups, projects, scrum, membership.references/feed.md — activity stream, feed posts, comments.references/timeman.md — time tracking, work day, absence reports, task time.references/sites.md — landing pages, sites, blocks, publishing.Read only the reference file that matches the current task.
Note: Bitrix24 has no REST API for reading or sending emails. mailservice.* only configures SMTP/IMAP services.