Developing a custom REST application for Bitrix24 Marketplace

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages

Developing a Custom REST Application for Bitrix24 Marketplace

A REST application for the Bitrix24 marketplace is not a local application installed on a specific portal, but a multi-user product that can be installed on any portal from the marketplace catalog. This changes the architecture requirements: the application must be multi-tenant from day one, handle independent data streams from thousands of portals, and not crash with unusual behavior from any of them.

How REST Application Differs from Local

Local application is created in a specific portal's settings via "Applications" → "For Developers". It works only on that portal, tokens are tightly bound, multi-tenancy is not needed.

REST application for marketplace is registered via partner.bitrix24.ru, has single client_id and client_secret for all installations. Each portal that installs your application gets its own access_token / refresh_token. Your service must store tokens from all portals and work with each independently.

The key installation identifier is member_id (hash, unique for each portal). All data in your database is partitioned by member_id.

Application Infrastructure

Minimal production infrastructure for a marketplace application:

Components:

  • OAuth server — handles install, uninstall, login handlers
  • API service — takes requests from iframe, works with Bitrix24 REST API
  • Worker/queue — processes webhooks from portals asynchronously
  • Database — stores tokens, settings, application data partitioned by member_id
  • Cache (Redis) — cache access_token until TTL expires (3600 sec), infrequently changing data

Handlers that must be implemented:

POST /bitrix/install   → receive code, exchange for tokens, save to database
POST /bitrix/uninstall → invalidate tokens, clean up portal data (GDPR)
POST /bitrix/login     → SSO via Bitrix24 (optional, but convenient)
POST /bitrix/events    → receive webhook events from portal
GET  /bitrix/app       → main iframe application page

OAuth Flow: Implementation Details

When the application is installed, Bitrix24 sends POST to the handler URL (registered when registering the application):

POST /bitrix/install
Content-Type: application/x-www-form-urlencoded

event=ONAPPINSTALL&auth[access_token]=...&auth[refresh_token]=...
&auth[member_id]=abc123&auth[domain]=company.bitrix24.ru

Here tokens already come in the installation body — no code exchange needed. Save everything to database. Token table schema:

CREATE TABLE app_installations (
    id              SERIAL PRIMARY KEY,
    member_id       VARCHAR(64) UNIQUE NOT NULL,
    domain          VARCHAR(255) NOT NULL,
    access_token    TEXT NOT NULL,
    refresh_token   TEXT NOT NULL,
    expires_at      TIMESTAMP NOT NULL,
    scope           TEXT,
    installed_at    TIMESTAMP DEFAULT NOW(),
    uninstalled_at  TIMESTAMP
);
CREATE INDEX ON app_installations (member_id);

Token refresh: when expires_at arrives (or getting 401 from portal API), make a request to https://oauth.bitrix.info/oauth/token/ with grant_type=refresh_token. Important: refresh must be atomic (mutex by member_id), otherwise parallel requests from multiple workers might simultaneously refresh the token and one gets stale.

Working with Bitrix24 REST API from Your Service

After obtaining access_token all requests to a specific portal go to its domain:

POST https://{domain}/rest/{method}
Authorization: Bearer {access_token}
Content-Type: application/json

Or token is passed in the body: auth={access_token}.

Rate limiting. Bitrix24 limits applications: no more than 2 requests/second per portal (some sources say up to 5 RPS on cloud plans). If exceeded — response {"error":"QUERY_LIMIT_EXCEEDED"}. You need a queue with rate limiter per member_id.

Batch requests. The batch method lets you combine up to 50 methods in one HTTP request. Critical for performance — instead of 50 separate HTTP round-trips, we do one.

Pagination. All list methods return maximum 50 items. Response has next (offset for next request) and total. To get all records you need a loop. For large data volumes (thousands of records) — definitely use asynchronous page processing.

Working with Placements: Embedding in Interface

Registration of placement on install:

// Call when processing ONAPPINSTALL
BX24.callMethod('placement.bind', {
    PLACEMENT: 'CRM_DEAL_DETAIL_TAB',
    HANDLER: 'https://your-app.com/bitrix/app?placement=crm_deal',
    TITLE: 'Tab Name',
    DESCRIPTION: 'Tab Description'
});

In iframe your application receives context via JS SDK:

BX24.init(function() {
    BX24.placement.getInterface(function(data) {
        // data.ID — deal/lead/contact ID
        // data.ENTITY_TYPE — entity type
        fetchDataForEntity(data.ID, data.ENTITY_TYPE);
    });

    // Resize iframe to content
    BX24.fitWindow();
});

Cookies in iframe are inaccessible in Safari due to ITP. Session must be stored in localStorage or received via BX24.getAuth() on each open.

Handling Events (Webhooks)

Subscribe to events via event.bind on install:

POST /rest/event.bind
{
    "event": "ONCRMDEALUPDATE",
    "handler": "https://your-app.com/bitrix/events",
    "auth_type": 0
}

Critical requirement: handler must respond with HTTP 200 within 5 seconds. All heavy processing — in a queue. Handler scheme:

POST /bitrix/events → verify signature → put in queue → respond 200
Worker → take from queue → process → update data

Security

Verification of incoming requests from Bitrix24: headers or body contains auth[application_token] — this is the static token of your application from settings in partner.bitrix24.ru. Check it on every incoming request.

For webhooks from event.bind the body contains auth[application_token] — same thing.

Development Timeline

Volume Timeline
Basic iframe application, CRM data reading 3–5 weeks
Application with bidirectional sync and webhooks 7–11 weeks
Multi-feature application with multiple placements and custom UI 12–18 weeks
Ready for publication (testing, card design, moderation) +3–5 weeks to any option