Development of Embedded Applications for Bitrix24
Embedded applications are not just "a window in an iframe." When a manager works inside a deal card and sees a tab with shipment history from your WMS — with the ability to create a new order right there — that is the result of a properly built embedded application. The difference from a regular widget is that an embedded application has two-way interaction with the Bitrix24 interface and can control its state.
What is an embedded application in Bitrix24 terminology
In the Bitrix24 documentation, embedded applications (Embedded Apps) are applications with type IFRAME that register placements and operate inside the portal interface. Unlike external (server) applications, they have direct access to the JS SDK BX24 and can:
- read and modify fields in an open CRM card in real time without a page reload
- call Bitrix24 dialogs, sliders, and notifications (
BX24.openPath,BX24.showMessagePopup) - subscribe to interface events via
BX24.placement.call('getInterface', ...)
Lifecycle and authorization
When a tab with an application is opened, Bitrix24 sends an iframe request to your handler URL with parameters:
GET https://your-app.com/handler?
DOMAIN=company.bitrix24.ru&
PROTOCOL=1&
AUTH_ID=abc123&
AUTH_EXPIRES=3600&
REFRESH_ID=xyz789&
member_id=a1b2c3&
PLACEMENT=CRM_DEAL_DETAIL_TAB&
PLACEMENT_OPTIONS={"ID":"42","SECTION":""}
AUTH_ID lives for 1 hour. For long-lived sessions (user left the tab open) a refresh is needed:
BX24.init(() => {
// Automatically refreshes the token if it has expired
BX24.getAuth((auth) => {
// auth.access_token — current token
fetch('/api/data', {
headers: { 'X-Bitrix-Auth': auth.access_token }
});
});
});
Verify the token on your server via:
GET https://company.bitrix24.ru/rest/profile?auth=ACCESS_TOKEN
Real-time interaction with a CRM card
The most valuable feature of embedded applications is reading and writing card fields without a page reload.
Subscribing to a field change in a card:
BX24.placement.call('bindEvent', {
event: 'onCrmBindEntityUpdated'
}, (eventData) => {
// Called when the user saves the card
const entityId = eventData.ENTITY_ID;
refreshWidgetData(entityId);
});
Programmatically changing a card field (without saving — visually only):
BX24.placement.call('setFieldValue', {
FIELD: 'UF_CRM_CUSTOM_STATUS',
VALUE: 'shipped'
}, () => {
console.log('Field updated in the interface');
});
The full list of placement events and methods depends on the card type (CRM_DEAL, CRM_LEAD, CRM_CONTACT, CRM_COMPANY) — each has its own documentation.
Embedded application project structure
Minimal structure:
/app
/public
index.html # Entry point (handler URL)
app.js # Client code with BX24 SDK
/src
/api
bitrix.js # Wrapper around BX24.callMethod
external.js # Requests to an external API
/components
DealTab.jsx # React/Vue/Vanilla — anything goes
server.js # Express/Fastify for OAuth callback and API proxy
Why a server component is needed even for a "client-side" application: the OAuth callback (/oauth/callback) must be handled on the server, client_secret must not be exposed in the browser, and proxying requests to external APIs avoids CORS issues.
Working with events via BX24.placement
Different placements provide different sets of methods. For CRM_DEAL_DETAIL_TAB:
// Get the interface of the current placement
BX24.placement.call('getInterface', {}, (interfaceData) => {
/*
interfaceData contains:
{
ID: "42", // Deal ID
ENTITY_TYPE: "CRM_TYPE_DEAL",
FIELDS: { ... }, // Current field values
BUTTONS: [ ... ] // Available buttons
}
*/
});
Publishing and installation
Embedded applications can be:
- Local — available on a single portal only, installed via developer settings
- Commercial — published in the Bitrix24 Market, go through moderation
For local installation it is enough to register the application in /devops/ and specify the handler URL. For a commercial release — SSL, a correct manifest.json, and passing Bitrix review are required.
Testing
The most common problem during development is debugging inside an iframe. Browser DevTools do not open in the Bitrix24 iframe context directly. Solutions:
- Open the handler URL directly in a browser with mock parameters for UI debugging
- Use
ngrokorlocaltunnelfor a local server with HTTPS (Bitrix24 requires HTTPS even in dev) - Log via
BX24.console.log()— messages will appear in the parent window console
Development timelines
| Scale | What is included | Timeline |
|---|---|---|
| MVP | 1 placement, CRM data reading, no external integrations | 3–5 days |
| Standard | 2–3 placements, CRM write, simple external integration | 1–2 weeks |
| Advanced | 5+ placements, two-way sync with an external system, OAuth | 3–6 weeks |
| Commercial Market application | Full cycle including moderation and documentation | 2–3 months |
A critical point: before starting development, agree with the client on the list of placements — adding a new placement after publishing a commercial application requires going through moderation again.







