REST API for 1C-Bitrix: Design, Implementation, Documentation

Bitrix has a built-in REST API for Bitrix24, but for a site on "1C-Bitrix: Site Management" there is no native REST — it must be built. The task comes up regularly: a mobile app needs catalog data, a third-party service wants to receive orders, a React or Vue frontend needs data without page reload.

Our competencies:

Frequently Asked Questions

Bitrix has a built-in REST API for Bitrix24, but for a site on "1C-Bitrix: Site Management" there is no native REST — it must be built. The task comes up regularly: a mobile app needs catalog data, a third-party service wants to receive orders, a React or Vue frontend needs data without page reload. Typical pain: with each new integrator you have to write workarounds using COption::GetOptionString and output JSON via echo json_encode(), and in a month the code turns into spaghetti.

We have 10+ years of Bitrix development experience and over 50 implemented API integrations handling up to 10,000 RPS. We know all the pitfalls: from infoblock caching issues to serialization errors in the ORM. We guarantee stable operation under load and provide Swagger documentation for each endpoint. Average time savings on integration with external services is 40%.

How to Build REST API on D7?

The API foundation is controllers based on \Bitrix\Main\Engine\Controller. Each controller handles one resource. Comparison with custom solutions: D7 controllers automatically handle errors, serialize responses to JSON, and support prefilters. This reduces code volume by 2-3 times compared to manual processing via $APPLICATION->RestartBuffer().

  1. Create a module in /local/modules/ with structure my.api. Define install/index.php with InstallDB() and UnInstallDB() methods for creating tables.
  2. Register controllers in routes.php (since kernel 20.0). Map URLs to classes, e.g., 'api/v1/products' => 'MyApi\Controllers\ProductController'.
  3. Implement action methods. Each method returns an array — the kernel serializes it to JSON. Add prefilters for authentication and HTTP method restrictions.
  4. Connect a service layer — move query and processing logic to separate classes like ProductService, OrderService, etc. This simplifies unit testing.
  5. Document endpoints via Swagger (OpenAPI 3.0). Generate spec from annotations or manually. Place Swagger UI in /local/swagger/.
/local/modules/my.api/lib/ ├── Controllers/ │ ├── ProductController.php → GET /api/v1/products │ ├── OrderController.php → GET/POST /api/v1/orders │ ├── CategoryController.php → GET /api/v1/categories │ └── AuthController.php → POST /api/v1/auth/token ├── Services/ │ ├── ProductService.php │ └── OrderService.php ├── Transformers/ │ ├── ProductTransformer.php → response formatting │ └── OrderTransformer.php └── Middleware/ ├── AuthMiddleware.php └── RateLimitMiddleware.php 

Example controller: listAction method accepts pagination parameters and returns data with meta information. Code is short, without extra checks — everything is built into D7.

namespace MyApi\Controllers; use Bitrix\Main\Engine\Controller; use Bitrix\Main\Engine\ActionFilter; use MyApi\Services\ProductService; use MyApi\Middleware\AuthMiddleware; class ProductController extends Controller { public function configureActions(): array { return [ 'list' => ['prefilters' => [new AuthMiddleware()]], 'detail' => ['prefilters' => [new AuthMiddleware()]], 'create' => ['prefilters' => [new AuthMiddleware(), new ActionFilter\HttpMethod(['POST'])]], ]; } public function listAction(int $page = 1, int $perPage = 20, string $category = ''): array { $service = new ProductService(); $result = $service->getList($page, $perPage, $category); return [ 'data' => $result['items'], 'meta' => [ 'total' => $result['total'], 'page' => $page, 'per_page' => $perPage, 'pages' => ceil($result['total'] / $perPage), ], ]; } public function detailAction(int $id): array { $service = new ProductService(); $product = $service->getById($id); if (!$product) { $this->addError(new \Bitrix\Main\Error('Product not found', 404)); return []; } return ['data' => $product]; } } 

How to Ensure REST API Security?

Authentication is common source of problems. For server-to-server we use API keys: simple header X-Api-Key. For user requests (mobile app, SPA) — JWT. The firebase/php-jwt library is installed via Composer. Refresh tokens are stored in a custom ORM table bound to the user. This is more reliable than storing sessions in files.

More about JWT: JSON Web Token (Wikipedia).

Response format — consistency matters. We follow a unified template: status, data, meta for success, errors for errors. D7 controller generates response automatically, but we override processAfterAction for full control.

protected function processAfterAction(Action $action, $result) { $response = \Bitrix\Main\Application::getInstance()->getContext()->getResponse(); $response->addHeader('Content-Type', 'application/json; charset=utf-8'); if ($this->getErrors()) { echo json_encode([ 'status' => 'error', 'errors' => array_map(fn($e) => [ 'code' => $e->getCode(), 'message' => $e->getMessage(), ], $this->getErrors()), ], JSON_UNESCAPED_UNICODE); } else { echo json_encode([ 'status' => 'ok', 'data' => $result, ], JSON_UNESCAPED_UNICODE); } exit; } 

CORS — if the API is called from a different domain, we must add headers and handle OPTIONS requests. Otherwise the browser blocks requests.

Rate limiting — protection from overload. We use Redis or, for low load, b_option. For example, 1000 requests per hour per key.

Authentication method Application Implementation ease Security
API key Server-to-server High Medium (key in header)
JWT User-to-server (mobile, SPA) Medium High (with refresh tokens)
Basic Auth Legacy systems High Low (password sent)

How to Test the API?

Write integration tests with PHPUnit. Use SQLite instead of MySQL for isolation. Check not only successful scenarios but also edge cases: invalid parameters, missing resources, exceeding limits. Example test for listAction:

public function testListReturnsPaginationMeta(): void { $controller = new ProductController(); $result = $controller->listAction(1, 10); $this->assertArrayHasKey('meta', $result); $this->assertArrayHasKey('total', $result['meta']); } 

What's Included

We don't just write code. Each project includes:

  • Technical specification with endpoint prototypes.
  • Architectural module diagram.
  • Implementation of controllers, services, transformers.
  • OpenAPI 3.0 documentation (Swagger).
  • Rate limiting and CORS configuration.
  • Deployment instructions and one month of support.

Estimated Timelines

Task Timeline
Basic REST API (3-5 resources, API key, JSON responses) 1.5-2 weeks
API with JWT authentication, user permissions, documentation 3-5 weeks
Full API with versioning, rate limiting, tests, CI 6-10 weeks

REST API on Bitrix is built from standard blocks — controllers, ORM, cache. The complexity is not in technology but in design: correct endpoints, consistent response formats, handling edge cases. If you need a reliable REST API for your Bitrix site, contact us — we'll evaluate your project in one day. Order REST API development and get ready-made Swagger documentation included.

Official Bitrix D7 documentation