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 fromb_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







