Bitrix24 Server Application Development

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
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    745
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Development of Server Applications for Bitrix24

When the task is to automatically create deals in Bitrix24 when an order arrives from an external store, synchronize contacts with an email service, or run robots on a schedule — a server application is needed. It works without user involvement: no interface, no iframe, only the REST API and a properly configured OAuth.

How a server application differs from a webhook

Webhooks in Bitrix24 are incoming URLs where Bitrix24 sends events. They are convenient for simple scenarios, but have limitations: they are tied to a specific user, do not support OAuth, and cannot be commercial. A server application (type server) is a full OAuth client that:

  • Authorizes on behalf of the installing user with token storage
  • Can run in the background (daemon, task queue, cron)
  • Supports multi-portal operation (one application — many clients)
  • Has its own event handler via event.bind

OAuth 2.0 in the Bitrix24 context

Bitrix24 uses the standard Authorization Code Flow:

1. Redirect the user to:
   https://company.bitrix24.ru/oauth/authorize/
     ?client_id=YOUR_CLIENT_ID
     &response_type=code
     &state=RANDOM_STRING

2. After consent — redirect to redirect_uri with `code`

3. Exchange the code for tokens:
   POST https://oauth.bitrix.info/oauth/token/
     grant_type=authorization_code
     &client_id=YOUR_CLIENT_ID
     &client_secret=YOUR_SECRET
     &code=RECEIVED_CODE
     &redirect_uri=https://your-app.com/oauth/callback

4. Response:
{
  "access_token": "...",
  "expires_in": 3600,
  "token_type": "bearer",
  "scope": "crm,task,user",
  "refresh_token": "...",
  "member_id": "portal_hash"
}

Critical: store tokens in a secure storage (database, AWS Secrets Manager, Vault). member_id is the unique portal identifier — use it as a key in a multi-tenant architecture.

Token storage and refresh logic

In a production system, tokens are stored approximately like this:

CREATE TABLE bitrix_tokens (
    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  TIMESTAMPTZ NOT NULL,
    scope       TEXT,
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    updated_at  TIMESTAMPTZ DEFAULT NOW()
);

Refresh on token expiry:

def get_valid_token(member_id: str) -> str:
    token = db.get_token(member_id)
    if token.expires_at < datetime.now() + timedelta(minutes=5):
        response = requests.post(
            'https://oauth.bitrix.info/oauth/token/',
            data={
                'grant_type': 'refresh_token',
                'client_id': CLIENT_ID,
                'client_secret': CLIENT_SECRET,
                'refresh_token': token.refresh_token,
            }
        )
        new_token = response.json()
        db.update_token(member_id, new_token)
        return new_token['access_token']
    return token.access_token

Add a 5-minute buffer (timedelta(minutes=5)) — otherwise the token may expire between the check and the actual request.

Subscribing to portal events

A server application can subscribe to Bitrix24 events via REST:

POST /rest/event.bind
{
  "event": "ONCRMDEALADD",
  "handler": "https://your-app.com/webhooks/bitrix/deal-add",
  "auth_type": 0
}

When an event fires, Bitrix24 sends a POST to the handler with event data and a token. Supported CRM events: ONCRMDEALADD, ONCRMDEALUPDATE, ONCRMDEAIDELETED, ONCRM* — similarly for leads, contacts, and companies.

Important nuance: the handler must respond with 200 OK within 3 seconds. If your processing takes longer — immediately return 200 and put the task in a queue (RabbitMQ, Redis Streams, SQS):

@app.route('/webhooks/bitrix/deal-add', methods=['POST'])
def handle_deal_add():
    data = request.json
    task_queue.enqueue(process_new_deal, data)  # Async processing
    return jsonify({'status': 'accepted'}), 200

Working with batch requests

The Bitrix24 REST API has a limit of 2 requests per second per portal (50 requests per second for paid plans). For bulk operations use batching:

POST /rest/batch
{
  "halt": 0,
  "cmd": {
    "get_deal": "crm.deal.get?id=42",
    "get_contact": "crm.contact.get?id=17",
    "get_company": "crm.company.get?id=5"
  }
}

One batch request can contain up to 50 commands. With halt=1, execution stops on the first error.

Multi-portal architecture

If the application serves multiple portals, the structure must support data isolation:

/api/v1/{member_id}/sync   — portal data synchronization
/webhooks/{member_id}/event — receiving events from a specific portal

Using member_id in the URL is a convenient pattern, but make sure there are no IDOR vulnerabilities: validate the request signature or authorization before processing.

Development timelines

Server application type Timeline
Simple integration (one-way synchronization) 3–7 days
Two-way synchronization with one external system 2–4 weeks
Multi-portal application with Market 1–3 months
Enterprise integration (multiple systems, queues, monitoring) 2–6 months

The main complexity of server applications is not the REST API itself, but reliability: proper handling of duplicate requests (idempotency), retry logic when a portal is temporarily unavailable, monitoring of expired tokens. These aspects take up 40–60% of development time.