Developing an API for a mobile application based on 1C-Bitrix

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
    1175
  • 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
    747
  • 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

Mobile Application API Development on 1C-Bitrix

1C-Bitrix does not provide a ready-made REST API for an arbitrary mobile application. The built-in REST module (rest) is oriented toward Bitrix24 and CRM webhooks — it is not suitable for a public API covering the catalog, cart, and orders. Building an API for a mobile app means writing custom controllers on top of the 1C-Bitrix core with proper authentication, versioning, and response format.

API architecture

The optimal entry point is a single /api/v1/index.php file that routes requests through a router. Either the 1C-Bitrix routing component is used, or a minimal router is implemented from scratch.

URL structure:

GET    /api/v1/catalog/sections         — section list
GET    /api/v1/catalog/products         — products with filtering and pagination
GET    /api/v1/catalog/products/{id}    — product card
POST   /api/v1/cart/add                 — add to cart
GET    /api/v1/cart                     — cart state
POST   /api/v1/order/create             — place order
POST   /api/v1/auth/login               — authentication
POST   /api/v1/auth/refresh             — token refresh

JWT authentication

Session-based 1C-Bitrix authentication is not suitable for a mobile application — tokens are required. JWT is implemented:

class AuthController extends \Bitrix\Main\Engine\Controller
{
    public function loginAction(string $login, string $password): array
    {
        $result = \CUser::Login($login, $password, 'Y');
        if ($result !== true) {
            return ['error' => 'Invalid credentials'];
        }

        $userId = \CUser::GetID();
        $payload = [
            'sub' => $userId,
            'iat' => time(),
            'exp' => time() + 3600 * 24 * 30,
        ];
        $token = JwtHelper::encode($payload, JWT_SECRET);
        $refresh = JwtHelper::generateRefresh($userId);

        return ['access_token' => $token, 'refresh_token' => $refresh];
    }
}

Refresh tokens are stored in the bl_api_tokens table with fields user_id, token_hash, expires_at, device_id.

In the middleware of each request: decode the JWT from the Authorization: Bearer ... header, get the user_id, authorize the user via \CUser::SetOnStartSession() for the current request only.

Catalog and products

Catalog controller with filter and pagination support:

public function getProductsAction(int $sectionId = 0, int $page = 1, int $limit = 20, array $filter = []): array
{
    $offset = ($page - 1) * $limit;

    $bitrixFilter = [
        'IBLOCK_ID' => CATALOG_IBLOCK_ID,
        'ACTIVE' => 'Y',
        'ACTIVE_DATE' => 'Y',
    ];
    if ($sectionId > 0) {
        $bitrixFilter['SECTION_ID'] = $sectionId;
        $bitrixFilter['INCLUDE_SUBSECTIONS'] = 'Y';
    }
    // apply user filters

    $items = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
        'filter' => $bitrixFilter,
        'limit' => $limit,
        'offset' => $offset,
        'select' => ['ID', 'NAME', 'DETAIL_PICTURE', 'PREVIEW_TEXT'],
    ]);

    return ['items' => $this->formatProducts($items), 'page' => $page, 'limit' => $limit];
}

Prices are retrieved via \Bitrix\Catalog\PriceTable::getList() taking the user's price group into account.

Cart and orders

The cart is stored in the standard b_sale_basket table via \Bitrix\Sale\Basket. For unauthenticated users, the cart is bound to FUSER_ID passed in the request header (X-Fuser-Id). On authentication, the cart migrates to USER_ID.

Order placement — \Bitrix\Sale\Order::create() with the shipping address, payment method, and delivery method passed. The API returns order_id and a payment link.

Response format and errors

Uniform JSON envelope:

{
  "success": true,
  "data": { ... },
  "meta": { "page": 1, "total": 142 }
}

On error:

{
  "success": false,
  "error": { "code": "PRODUCT_NOT_FOUND", "message": "Product not found" }
}

HTTP status codes: 200 OK, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error.

Case study: mobile app for a dealer network

Task: iOS/Android application for 200 dealers — catalog browsing, stock checking, order placement.

Notable requirements:

  • Individual prices by customer groups (b_catalog_price, group from b_user)
  • Stock from b_catalog_store_product — multiple warehouses, aggregated stock needed
  • Push notifications via FCM on order status change
  • Catalog response caching for 5 minutes via Bitrix Cache (\Bitrix\Main\Data\Cache)

Result: 200 active users, average API response time 120 ms, peak load 50 RPS.

Endpoint Average time
GET /catalog/products 80–120 ms
GET /catalog/products/{id} 40–60 ms
POST /cart/add 60–90 ms
POST /order/create 200–400 ms

What is included in development

  • Router and controller structure for /api/v1/
  • JWT authentication with refresh tokens and multi-device support
  • Catalog endpoints with filtering, pagination, and group-based pricing
  • Cart and order placement via \Bitrix\Sale
  • Standardized response format and error codes
  • Catalog response caching, OpenAPI documentation