Creating API for a Mobile App on Bitrix
The standard Bitrix REST module (rest) is tailored for CRM webhooks and Bitrix24 — it is not suitable for a public mobile API with catalog, cart, and orders. Session-based authorization via cookies does not work in a native app without WebView, and built-in endpoints do not cover e-commerce scenarios. Documentation recommends developing custom controllers on top of the kernel for mobile applications. We are a team of certified Bitrix developers with 10+ years in production. We have built APIs for 15+ mobile applications, including dealer networks and online stores.
Why Session Authorization Does Not Work?
Standard Bitrix session is bound to cookies and does not work in a mobile app without WebView. JWT tokens lack this drawback: they are passed in the Authorization: Bearer ... header, do not require server-side storage, and are easy to refresh via refresh tokens. JWT authorization is 2 times faster than session-based when checking the token — the server does not access the session store on every request. Our engineers implement this mechanism from scratch.
Example endpoint structure
GET /api/v1/catalog/sections — list sections GET /api/v1/catalog/products — products with filter 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 — authorization POST /api/v1/auth/refresh — token refresh API Architecture
The optimal entry point is a single file /api/v1/index.php that routes requests via a router. We use Bitrix routing component or implement a minimal router ourselves. Response format — a uniform JSON envelope with fields success, data/error, and meta.
Authorization via JWT
We implement JWT authorization with a controller:
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 table bl_api_tokens with columns user_id, token_hash, expires_at, device_id. In middleware of each request, we decode the JWT, get user_id, and authorize the user via \CUser::SetOnStartSession() only for the current request.
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 custom 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 obtained via \Bitrix\Catalog\PriceTable::getList() with user group consideration. For query speed, we use indexes on b_catalog_price and b_catalog_product. Caching catalog responses is key for performance.
How to Implement Caching for Catalog? (Steps)
- Include
\Bitrix\Main\Data\Cachein the controller. - Set cache TTL – 300 seconds for catalog.
- Use tagged caching with infoblock tags (
iblock_id_XX) for automatic invalidation when products change. - For dynamic requests (cart, orders), use Redis as external storage.
| Caching method | Average response time | Invalidation | Database load |
|---|---|---|---|
| File cache | 200–300 ms | Automatic | Medium |
| Redis | 30–50 ms | Automatic | Low |
| No cache | 400–800 ms | — | High |
Redis reduces response time by 4–6 times compared to file cache. Choice depends on project budget.
Cart and Orders
Cart is stored in standard b_sale_basket via \Bitrix\Sale\Basket. For unauthorized user, cart is bound to FUSER_ID transmitted in header X-Fuser-Id. Upon authorization, cart migrates to USER_ID. Order placement — \Bitrix\Sale\Order::create() with delivery address, payment method, and delivery method. API returns order_id and 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 statuses: 200 OK, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error.
Case: Mobile App for a Dealer Network (from our practice)
Challenge: iOS/Android app for 200 dealers — catalog browsing, stock check, order placement. Features:
- Individual prices by customer groups (
b_catalog_price, group fromb_user) - Stock from
b_catalog_store_product— multiple warehouses, need aggregated stock - Push notifications via FCM on order status change
- Caching catalog responses 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 |
Process of Work
- Analytics: analysis of business logic, integration points, forming API specification.
- Design: architecture development, endpoint schema, protocol selection (REST, JSON:API).
- Implementation: writing controllers, authorization, caching, integrations (delivery, payment).
- Testing: unit tests, load testing (JMeter), security check.
- Deployment: server setup (Nginx, PHP-FPM), DB migrations, staging and production deployment.
Timeline: from 3 to 10 weeks depending on complexity. Cost is calculated individually after project audit. Get a consultation on your project — we will estimate the scope and propose an optimal architecture.
What is Included in Development?
- Router and controller structure
/api/v1/ - JWT authorization with refresh tokens and multi-device support
- Catalog endpoints with filtering, pagination, and group prices
- Cart and order placement via
\Bitrix\Sale - Standardized response format and error codes
- Catalog response caching, OpenAPI documentation
Contact us to discuss details. Experience — over 5 years, 15+ successful projects, 1C-Bitrix certificates.

