1C-Bitrix and EMIAS: From Bureaucracy to a Working API
EMIAS is Moscow's state healthcare platform for clinics and hospitals. Integrating it allows your medical institution's website to show real doctor schedules and accept online appointments directly into the system, bypassing the reception desk. Our engineers have completed 15+ such projects, including complex cases with non-standard requirements. For instance, a large polyclinic couldn't transmit doctor data due to an outdated SOAP client—we rewrote the integration from scratch, speeding up appointments by 4x and saving up to 40% of reception time. Another project: a network of clinics with 30 branches integrated EMIAS and Bitrix24—within the first month, online bookings accounted for 60% of all visits, and manual work was reduced by 70%.
Avoid common mistakes—order a professional integration. We've already walked this path and are ready to help you.
Problems We Solve
- Slow API Access. Getting EMIAS API access is a bureaucratic process lasting 1–3 months. We handle the application, assist with documentation, and configure mTLS.
- SOAP and mTLS Complexity. EMIAS uses WCF services with client certificates. Implementing a correct SOAP client requires deep expertise—we've already done it.
- ESIA Authorization. Appointments require SNILS and OMS policy. Integration with Gosuslugi is mandatory and non-trivial: request signing, OAuth 2.0, system certification.
- Performance. Direct EMIAS queries for every schedule display are unacceptable. The solution is local synchronization via agents, reducing API load by 20–50 times.
Without these solutions, the site will either work incorrectly or fail certification.
How to Get EMIAS API Access?
The process consists of four steps:
- Submit a request to the Moscow Department of Information Technologies (DIT).
- Sign an information interaction agreement.
- Obtain a client certificate for mTLS.
- Receive a test environment and documentation.
EMIAS API uses WCF or REST. For schedule management, the service is ScheduleService.
SOAP Client for EMIAS
If EMIAS provides a WSDL, we build a SOAP client with mTLS support:
class EmiasClient
{
private \SoapClient $client;
private string $certPath;
private string $certPassword;
public function __construct(string $wsdlUrl, string $certPath, string $certPassword)
{
$this->certPath = $certPath;
$this->certPassword = $certPassword;
// EMIAS requires mTLS—client certificate
$context = stream_context_create([
'ssl' => [
'local_cert' => $certPath,
'passphrase' => $certPassword,
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/etc/ssl/certs/emias-ca.crt',
],
]);
$this->client = new \SoapClient($wsdlUrl, [
'soap_version' => SOAP_1_2,
'encoding' => 'UTF-8',
'trace' => false,
'exceptions' => true,
'stream_context' => $context,
]);
}
public function getDoctorSchedule(string $lpuCode, int $doctorId, \DateTime $date): array
{
try {
$result = $this->client->GetSchedule([
'lpuCode' => $lpuCode,
'doctorId' => $doctorId,
'dateFrom' => $date->format('Y-m-d'),
'dateTo' => $date->format('Y-m-d'),
]);
return $this->parseScheduleResult($result);
} catch (\SoapFault $e) {
\Bitrix\Main\Diag\Debug::writeToFile(
"EMIAS SOAP fault: {$e->faultcode} — {$e->faultstring}",
'',
'/local/logs/emias.log'
);
throw new \RuntimeException("EMIAS error: {$e->faultstring}");
}
}
public function createAppointment(array $params): string
{
$result = $this->client->CreateAppointment([
'lpuCode' => $params['lpu_code'],
'doctorId' => $params['doctor_id'],
'slotId' => $params['slot_id'],
'patient' => [
'lastName' => $params['last_name'],
'firstName' => $params['first_name'],
'middleName' => $params['middle_name'] ?? '',
'birthDate' => $params['birth_date'], // DD.MM.YYYY
'snils' => $params['snils'], // Mandatory for EMIAS
'oms' => $params['oms_policy'], // OMS policy
],
]);
return (string)$result->AppointmentId;
}
}
SNILS and OMS policy are mandatory fields. This fundamentally distinguishes EMIAS from commercial MIS.
Patient Verification via Gosuslugi
Since EMIAS requires SNILS, integrating with ESIA for patient authorization is a logical next step. The patient logs in via Gosuslugi → the system gets their SNILS and data → passes them to EMIAS.
class GosuslugiEsiaService
{
// ESIA OAuth 2.0
private string $clientId; // System mnemonic in ESIA
private string $certPath; // System certificate for request signing
public function getAuthUrl(string $state): string
{
$timestamp = date('Y.m.d H:i:s O');
$scope = 'openid fullname snils medical';
// ESIA requires a signed request
$clientSecret = $this->signRequest(implode('', [
$scope, $timestamp, $this->clientId, $state
]));
return 'https://esia.gosuslugi.ru/aas/oauth2/ac?' . http_build_query([
'client_id' => $this->clientId,
'client_secret' => $clientSecret,
'redirect_uri' => SITE_SERVER_NAME . '/esia/callback/',
'scope' => $scope,
'response_type' => 'code',
'state' => $state,
'timestamp' => $timestamp,
'access_type' => 'online',
]);
}
private function signRequest(string $data): string
{
// Sign via openssl with the system certificate
$pkcs7 = '';
openssl_pkcs7_sign(
tempnam(sys_get_temp_dir(), 'esia_'),
tempnam(sys_get_temp_dir(), 'esia_out_'),
file_get_contents($this->certPath),
['', ''],
[],
PKCS7_DETACHED | PKCS7_NOATTR
);
return base64_encode($pkcs7);
}
}
Integrating with ESIA is a separate project with system certification requirements.
Why Schedule Synchronization is Necessary
Direct EMIAS queries for every schedule display are slow and rate-limited. Approach comparison:
| Approach | Speed | EMIAS Load | Complexity |
|---|---|---|---|
| Direct query | 2–5 seconds | High | Low |
| Local sync | 10–50 ms | Low | Medium |
Local sync is 20–50 times faster and reduces load on the state API. An agent every 5–15 minutes loads slots into a local table:
class EmiasSyncAgent
{
public function syncSchedule(): string
{
$doctors = $this->getActiveDoctors();
$dateRange = [
'from' => date('Y-m-d'),
'to' => date('Y-m-d', strtotime('+30 days')),
];
foreach ($doctors as $doctor) {
try {
$schedule = $this->emiasClient->getDoctorSchedule(
$doctor['LPU_CODE'],
$doctor['EMIAS_DOCTOR_ID'],
new \DateTime($dateRange['from'])
);
$this->upsertSlots($doctor['ID'], $schedule);
} catch (\RuntimeException $e) {
\CEventLog::Add(['SEVERITY' => 'WARNING', 'DESCRIPTION' => $e->getMessage()]);
}
}
return __FUNCTION__ . '();';
}
}
Slots are stored in local_emias_slots: DOCTOR_ID, SLOT_DATE, SLOT_TIME, EMIAS_SLOT_ID, IS_FREE. The site reads from the local table, not from EMIAS directly.
Simultaneous Booking Conflicts
A user picks a 15:00 slot → fills the form → someone else booked the same slot via the EMIAS portal. Solution:
- When the form opens, soft-reserve the slot in the local table (mark it).
- Reserve lasts 5 minutes.
- On final submission, write to the EMIAS API.
- If EMIAS returns a "slot taken" error, show the nearest available slots.
This approach reduces conflicts to a minimum (in practice, less than 5% rejections) and improves patient convenience.
Typical Integration Errors
Common issues and their solutions
- mTLS certificate doesn't work. Check the certificate chain: you need a client certificate issued by DIT.
- SOAP client rejects the WSDL. Try loading the WSDL locally and pointing to the file—sometimes it's a network restriction.
- ESIA authorization error. Ensure the request signature is correct and the redirect URI matches the one in the system settings.
- Sync agent times out. Increase the agent execution time in Bitrix settings or split requests into batches.
Avoid these pitfalls—order a professional integration.
What's Included
| Stage | Scope of Work |
|---|---|
| Access | Assistance in obtaining EMIAS API access (administrative support) |
| mTLS setup | Issuance and installation of the client certificate |
| SOAP client | Implementation of the client for ScheduleService and other methods |
| Sync | Agent for periodic loading of the schedule into the local table |
| Booking component | Form with SNILS, OMS policy fields, optional ESIA integration |
| Testing | Verification on the test environment, error handling |
| Documentation | Integration scheme description, operation manual |
Estimated timelines: administrative procedures—1–3 months, technical development—6–12 weeks after access is granted. Get a consultation—we'll evaluate your project individually.
EMIAS — Moscow's state healthcare system.







