# Authentication Source: https://api-docs.bienport.com/api-reference/authentication Authentication guarantees privacy of API Services by authenticating users. Authentication requires users to log in before accessing Bienport API Services. This guide covers setup for each available handshake method. All authorized endpoints require `Authorization: Bearer ` header in request!
Otherwise API client will receive an error message with status `401 - Unauthorized`
Example Header: ```ini theme={null} Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ7XCJ1c2VyaWRcIjoyMDY0MSxcInNjcmVlbk5hbWVcIjpcImJpZW5wb3J0LmZsZXh5d2F0dFwiLFwicmVtZW1iZXJNZVwiOnRydWV9IiwiaWF0IjoxNzU2MTQwODE3LCJleHAiOjE3NjM5MTY4MTd9.Vg9gAG1dn8v8c8f0J6H08NW2Bomwsyqk8LfDnc7WZFlX2zZrhZMoC-ru3oZL0wg0TuYaqTJ2cr9Hky4ddsGR9A ``` # 1. Login Operation > Login Operations are Made With ScreenName And Password
> API Endpoint: `/auth/login` Example Request Payload: ```json theme={null} { "screenName": "905554447788", "password": "password", "rememberMe": true } ``` Example Success Response: ```json theme={null} { "token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ7XCJ1c2VyaWRcIjoyMDY0MSxcInNjcmVlbk5hbWVcIjpcImJpZW5wb3J0LmZsZXh5d2F0dFwiLFwicmVtZW1iZXJNZVwiOnRydWV9IiwiaWF0IjoxNzU2MTQwODE3LCJleHAiOjE3NjM5MTY4MTd9.Vg9gAG1dn8v8c8f0J6H08NW2Bomwsyqk8LfDnc7WZFlX2zZrhZMoC-ru3oZL0wg0TuYaqTJ2cr9Hky4ddsGR9A", "mqUser": "mqttuser", "mqPassword": "XFAYdhtDquax/rtofHjqCw==", "userId": 20641, "emailAddress": "demo@bienport.com", "screenName": "bienport.demo", "localeId": "tr_TR", "roles": [ { "roleId": 20166, "roleName": "User", "type": 1, "inherited": false, "typePK": 1 } ], "organizations": [ { "name": "Bimetri", "id": 20635 } ], "organizationIds": [ 20635 ], "resources": [ { "resourceId": 17305, "networkId": "26:AA:E0:23:23:5E", "resourceName": "Bimetri Demo Konsantratör", "enabled": false, "treePath": "/17305/", "orgId": 20635, "resourceType": "Gateway", "deviceSubType": "gateway" }, { "resourceId": 17354, "networkId": "26:AA:09:0B:6D:FB", "resourceName": "Bimetri Demo Pano", "enabled": true, "treePath": "/17354/", "orgId": 20635, "resourceType": "Gateway", "deviceSubType": "gateway" } ] } ``` Access Tokens are valid for only 3 hour when "Remember Me" is selected as 'false'. Ther are valid for 3 months when "Remember Me" is selected as 'true'. Possible Error Responses: ```json theme={null} { "statusCode": 401, "error": "AuthorizationException", "message": "Incorrect username or password. Username: bienport.demo", "path": "/auth/login" } ``` # Get Imou Cloud Sub-Account token Source: https://api-docs.bienport.com/api-reference/camera-api/get-imou-cloud-sub-account-token /open-api/api-docs.yml get /camera/imou/subaccount-token/{organizationId} # Get Live Stream Info Source: https://api-docs.bienport.com/api-reference/camera-api/get-live-stream-info /open-api/api-docs.yml post /camera/live # Get System Info Source: https://api-docs.bienport.com/api-reference/camera-api/get-system-info /open-api/api-docs.yml get /camera/imou/app-system-info # Add Emergency Contact Source: https://api-docs.bienport.com/api-reference/central-alarm-monitoring-api/add-emergency-contact /open-api/api-docs.yml post /alarm/ecl/ticket/add # Generate Alarm Method Source: https://api-docs.bienport.com/api-reference/central-alarm-monitoring-api/generate-alarm-method /open-api/api-docs.yml post /alarm/generate # Get Emergency Contact Source: https://api-docs.bienport.com/api-reference/central-alarm-monitoring-api/get-emergency-contact /open-api/api-docs.yml get /alarm/ecl/{subscriptionId} # Get Contents Source: https://api-docs.bienport.com/api-reference/content-api/get-contents /open-api/api-docs.yml get /cms/{folderId}/contents # Get Web Content Folders Source: https://api-docs.bienport.com/api-reference/content-api/get-web-content-folders /open-api/api-docs.yml get /cms/get-folders # Get All Controllers Source: https://api-docs.bienport.com/api-reference/controller-api/get-all-controllers /open-api/api-docs.yml get /controller/list # Get Controller Data Log Source: https://api-docs.bienport.com/api-reference/controller-log-api/get-controller-data-log /open-api/api-docs.yml get /activities/controller/{resourceControllerId} # Get Controller Data Log List Source: https://api-docs.bienport.com/api-reference/controller-log-api/get-controller-data-log-list /open-api/api-docs.yml get /activities/controller/list # Add Technical Service Ticket Source: https://api-docs.bienport.com/api-reference/crm-ticket-api/add-technical-service-ticket /open-api/api-docs.yml post /techservice/ticket/add # Adding Ticket Method Source: https://api-docs.bienport.com/api-reference/crm-ticket-api/adding-ticket-method /open-api/api-docs.yml post /crm/ticket/add # Get Ticket Method Source: https://api-docs.bienport.com/api-reference/crm-ticket-api/get-ticket-method /open-api/api-docs.yml post /crm/ticket/filter # List technic service tickets method Source: https://api-docs.bienport.com/api-reference/crm-ticket-api/list-technic-service-tickets-method /open-api/api-docs.yml post /techservice/ticket/filter # Find Customers By Phone Number Source: https://api-docs.bienport.com/api-reference/customer-api/find-customers-by-phone-number /open-api/api-docs.yml post /customer/phone # Get Customer By Organization Id Source: https://api-docs.bienport.com/api-reference/customer-api/get-customer-by-organization-id /open-api/api-docs.yml get /customer/{organizationId}/get-by-organization # Get Organization By Customer Id Source: https://api-docs.bienport.com/api-reference/customer-api/get-organization-by-customer-id /open-api/api-docs.yml get /customer/{customerId}/get # Add schedule task Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/add-schedule-task /open-api/api-docs.yml post /enterprise/schedule/tasks/add # Delete schedule task Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/delete-schedule-task /open-api/api-docs.yml post /enterprise/schedule/tasks/delete # Filter scheduled tasks Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/filter-scheduled-tasks /open-api/api-docs.yml post /enterprise/schedule/tasks/filter # Get Command Queue Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/get-command-queue /open-api/api-docs.yml get /enterprise/queue/command/filter # Get Command Queue Resources in operation Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/get-command-queue-resources-in-operation /open-api/api-docs.yml get /enterprise/queue/command/panels # Get Organization Users Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/get-organization-users /open-api/api-docs.yml get /enterprise/bulk/get-organization-users # Get Panel Users Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/get-panel-users /open-api/api-docs.yml get /enterprise/bulk/get-panel-user/{resourceId} # Get schedule task Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/get-schedule-task /open-api/api-docs.yml post /enterprise/schedule/tasks/get # Update schedule task Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/update-schedule-task /open-api/api-docs.yml post /enterprise/schedule/tasks/update # User Panel Pairing Source: https://api-docs.bienport.com/api-reference/enterprise-bulk-operations-api/user-panel-pairing /open-api/api-docs.yml post /enterprise/bulk/set-panel-user # Get Last Sensors Data Logs Source: https://api-docs.bienport.com/api-reference/external-power-and-battery-status-api/get-last-sensors-data-logs /open-api/api-docs.yml post /panel/{resourceId}/vsensor/values # API Security Source: https://api-docs.bienport.com/api-reference/introduction This page provides important information about the details you need to know before making API requests. # Secure API and Idempotency Mechanism ## Idempotency-Key Header ### What is it? The `Idempotency-Key` is a unique, cryptographically generated value added to each API request header.\ It ensures that **retries of the same request are not executed more than once** by the server.\ This is especially important for operations that create or modify resources (e.g., payments, transactions, device records), where duplicate processing could lead to inconsistent data or unintended side effects. ### Why is it used? * **Prevents duplicates:** If a client retries a request due to a timeout or network error, the server can detect the same `Idempotency-Key` and ignore duplicate executions. * **Ensures consistency:** Clients can safely retry requests without worrying about unintended multiple writes. * **Improves reliability:** Makes APIs more resilient against network instability. *** ### Example Postman Pre-request script for API clients ```javascript theme={null} // Use the body of the request as the payload. const {Url} = require('postman-collection'); let payloadString = pm.request.body.raw; if ( ! payloadString ) { let url = new Url(pm.environment.get("url") + pm.request.url.getPath()); payloadString = "/api" + url.getPath(); console.log( 'Payload: ' + payloadString ); } else { console.log( 'Payload: ' + JSON.stringify ( payloadString ) ); } // Load the CryptoJS library required for the SHA256 hash operation. eval(pm.globals.get("CryptoJS")); // Calculate the SHA256 hash of the payload. const hash = CryptoJS.SHA256(payloadString); // Obtain the hexadecimal equivalent of the hash value. const hashHex = hash.toString(CryptoJS.enc.Hex).toUpperCase(); console.log ( 'SHA256 Hash: ' + hashHex ); // Calculate the epoch millisecond of the current time. const currentTime = new Date().getTime(); const currentTimeString = currentTime.toString(); console.log ( 'Epoch ms: ' + currentTimeString ); // Pad the length of currentTimeString to a multiple of 8. const paddedCurrentTimeString = currentTimeString.padStart(Math.ceil(currentTimeString.length / 8) * 8, '0'); console.log( 'paddedCurrentTimeString: ' + paddedCurrentTimeString ); // Generate a 3DES encryption key and iv (initialization vector). const key = CryptoJS.enc.Hex.parse( hashHex ); // Extract the 3DES key here. const message = CryptoJS.enc.Utf8.parse(paddedCurrentTimeString); const encrypted = CryptoJS.TripleDES.encrypt( paddedCurrentTimeString, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); // Convert the result of the encryption to a Hex String. const hexString = encrypted.ciphertext.toString().toUpperCase(); console.log ( 'Idempotency-Key: ' + hexString ); // Assign the result of the cryptographic operation to the “Idempotency-Key” header of the request. pm.request.headers.add({ key: 'Idempotency-Key', value: hexString }); ``` ### How is it calculated in the Pre-request Script? The provided Postman pre-request script generates the `Idempotency-Key` as follows: 1. **Payload extraction** * Uses the raw request body as the payload. * If the body is empty, falls back to the request URL path. 2. **SHA256 hashing** * Computes a SHA256 hash of the payload string. * Converts the result into an uppercase hex string. * This ensures a deterministic and unique base for the key. 3. **Timestamp inclusion** * Takes the current epoch time in milliseconds. * Pads the string to make its length a multiple of 8. * This adds **uniqueness per request**, even if the payload is identical. 4. **TripleDES encryption** * Uses the SHA256 hash as the key for 3DES encryption. * Encrypts the padded timestamp in ECB mode without padding. * Produces an encrypted value as a hex string. 5. **Final header assignment** * The resulting encrypted hex string becomes the `Idempotency-Key`. * Added to the request headers automatically: ```js theme={null} pm.request.headers.add({ key: 'Idempotency-Key', value: hexString }); ``` *** ### Example Output (from console logs) ``` Payload: "{'screenName':'bienport.demo', 'password':'demo', 'rememberMe':true}" SHA256 Hash: 65179C12FE83D08F.... Epoch ms: 1756141928597 paddedCurrentTimeString: 0001756141928597 Idempotency-Key: 1F11611E2483A1C360CE711B791A0711 POST https://apigw.bienport.com/api/auth/login ``` *** ### Summary * **Purpose:** Guarantees safe retries by preventing duplicate request execution. * **Mechanism:** Combines request payload + timestamp + encryption to create a unique key. * **Usage:** Always included in the request header automatically when running an API client. # Add new lead with mobile. Source: https://api-docs.bienport.com/api-reference/lead-api/add-new-lead-with-mobile /open-api/api-docs.yml post /lead/add # Get lead with mobile code Source: https://api-docs.bienport.com/api-reference/lead-api/get-lead-with-mobile-code /open-api/api-docs.yml post /lead/page/{pageNo} customerId, phoneNumber and mobileAppId are optional. But there must be exist at least one of them. # Authenticate User Source: https://api-docs.bienport.com/api-reference/login-api/authenticate-user /open-api/api-docs.yml post /auth/login # Find Controllers By Panel Id Source: https://api-docs.bienport.com/api-reference/panel-controllers-api/find-controllers-by-panel-id /open-api/api-docs.yml get /panel/{resourceId}/controller/list # Update Controller Description by Panel Controller Id Source: https://api-docs.bienport.com/api-reference/panel-controllers-api/update-controller-description-by-panel-controller-id /open-api/api-docs.yml put /panel/controller/{resourceControllerId}/update-description # Find sensors by Panel Id Source: https://api-docs.bienport.com/api-reference/panel-sensors-api/find-sensors-by-panel-id /open-api/api-docs.yml get /panel/{resourceId}/sensor/list # Update Sensor Description by Panel Sensor Id Source: https://api-docs.bienport.com/api-reference/panel-sensors-api/update-sensor-description-by-panel-sensor-id /open-api/api-docs.yml put /panel/sensor/{resourceSensorId}/update-description # Get Controller Partition Numbers Source: https://api-docs.bienport.com/api-reference/partition-api/get-controller-partition-numbers /open-api/api-docs.yml get /partition/resource/get-controller/{resourceControllerId} # Get Partition By Resource id And Partition No Source: https://api-docs.bienport.com/api-reference/partition-api/get-partition-by-resource-id-and-partition-no /open-api/api-docs.yml get /partition/resource/{resourceId}/get-partition/{partitionNo} # Get Partitions By Resource Id Source: https://api-docs.bienport.com/api-reference/partition-api/get-partitions-by-resource-id /open-api/api-docs.yml get /partition/resource/{resourceId}/get # Get Sensor Partition Numbers Source: https://api-docs.bienport.com/api-reference/partition-api/get-sensor-partition-numbers /open-api/api-docs.yml get /partition/resource/get-sensor/{resourceSensorId} # Add bank card to wallet Source: https://api-docs.bienport.com/api-reference/payment-api/add-bank-card-to-wallet /open-api/api-docs.yml post /payment/wallet/addbankcard # Add payment via wallet Source: https://api-docs.bienport.com/api-reference/payment-api/add-payment-via-wallet /open-api/api-docs.yml post /payment/add/registeredcard # Add payment with bank card information Source: https://api-docs.bienport.com/api-reference/payment-api/add-payment-with-bank-card-information /open-api/api-docs.yml post /payment/add # Delete bank card from wallet Source: https://api-docs.bienport.com/api-reference/payment-api/delete-bank-card-from-wallet /open-api/api-docs.yml post /payment/wallet/delbankcard # Getting Bank Card List from Wallet. Source: https://api-docs.bienport.com/api-reference/payment-api/getting-bank-card-list-from-wallet /open-api/api-docs.yml get /payment/wallet/list/{subscriptionId} # Add or Update Device Token Source: https://api-docs.bienport.com/api-reference/push-notification-api/add-or-update-device-token /open-api/api-docs.yml post /devicetoken/addorupdate # Get Push Notification History Source: https://api-docs.bienport.com/api-reference/push-notification-history-api/get-push-notification-history /open-api/api-docs.yml post /resource/pushnotification/history # Get Event Groups Source: https://api-docs.bienport.com/api-reference/resource-activities-api/get-event-groups /open-api/api-docs.yml get /activities/eventgroups # Get Resource Activities Between Dates Source: https://api-docs.bienport.com/api-reference/resource-activities-api/get-resource-activities-between-dates /open-api/api-docs.yml post /activities # Add Camera Source: https://api-docs.bienport.com/api-reference/resource-api/add-camera /open-api/api-docs.yml post /camera/add # Get All Cameras By User Source: https://api-docs.bienport.com/api-reference/resource-api/get-all-cameras-by-user /open-api/api-docs.yml get /camera/list # Get All Panels By User Source: https://api-docs.bienport.com/api-reference/resource-api/get-all-panels-by-user /open-api/api-docs.yml get /panel/list # Get Resource Source: https://api-docs.bienport.com/api-reference/resource-api/get-resource /open-api/api-docs.yml delete /camera/{resourceId}/delete # Get Resource Source: https://api-docs.bienport.com/api-reference/resource-api/get-resource-1 /open-api/api-docs.yml get /resource/{resourceId}/get # Refresh Sensors and Controllers Source: https://api-docs.bienport.com/api-reference/resource-api/refresh-sensors-and-controllers /open-api/api-docs.yml post /panel/refresh Don't use this often. It takes around 10 seconds and request is blocked until response received from devices # Update Resource Source: https://api-docs.bienport.com/api-reference/resource-api/update-resource /open-api/api-docs.yml put /resource/{resourceId}/update # Add Resource Authorization Source: https://api-docs.bienport.com/api-reference/resource-user-authorization-api/add-resource-authorization /open-api/api-docs.yml post /resource/user/add # Delete Resource Authorization Source: https://api-docs.bienport.com/api-reference/resource-user-authorization-api/delete-resource-authorization /open-api/api-docs.yml delete /resource/user/delete # Add or Update User Privilege Groups And Resources Source: https://api-docs.bienport.com/api-reference/role-api/add-or-update-user-privilege-groups-and-resources /open-api/api-docs.yml post /user/privilege-groups-and-resources/add-or-update # Get Organization Roles Source: https://api-docs.bienport.com/api-reference/role-api/get-organization-roles /open-api/api-docs.yml get /role/organization-roles # Get Privileges Source: https://api-docs.bienport.com/api-reference/role-api/get-privileges /open-api/api-docs.yml get /role/privilege-groups # Get Role Privilege Groups By Role Id Source: https://api-docs.bienport.com/api-reference/role-api/get-role-privilege-groups-by-role-id /open-api/api-docs.yml get /role/{roleId}/privilege-groups # Get User Privilege Groups By User Id Source: https://api-docs.bienport.com/api-reference/role-api/get-user-privilege-groups-by-user-id /open-api/api-docs.yml get /role/user/{userId}/privilege-groups # Send Verification Code For Account Activation Source: https://api-docs.bienport.com/api-reference/sms-verification-code-send-api/send-verification-code-for-account-activation /open-api/api-docs.yml post /verification-sms/send-registration-code # Send Verification Code For Password Reset Source: https://api-docs.bienport.com/api-reference/sms-verification-code-send-api/send-verification-code-for-password-reset /open-api/api-docs.yml post /verification-sms/send-password-reset-code # Get all subscription by status and organization id Source: https://api-docs.bienport.com/api-reference/subscription-api/get-all-subscription-by-status-and-organization-id /open-api/api-docs.yml post /subscription/list # Get Payment Plan Informations Source: https://api-docs.bienport.com/api-reference/subscription-api/get-payment-plan-informations /open-api/api-docs.yml post /subscription/bill/information # Get Payment Plans Source: https://api-docs.bienport.com/api-reference/subscription-api/get-payment-plans /open-api/api-docs.yml post /subscription/bill # List available camera type of subscriptions Source: https://api-docs.bienport.com/api-reference/subscription-api/list-available-camera-type-of-subscriptions /open-api/api-docs.yml get /subscription/cam-list/{organizationId} list of subscriptions where resourceId = null, type = camera* # Add User Source: https://api-docs.bienport.com/api-reference/user-api/add-user /open-api/api-docs.yml post /user/add # Delete User By Id Source: https://api-docs.bienport.com/api-reference/user-api/delete-user-by-id /open-api/api-docs.yml delete /user/delete # Find User By Email Source: https://api-docs.bienport.com/api-reference/user-api/find-user-by-email /open-api/api-docs.yml get /user/email/{emailAddress} # Find User By Id Source: https://api-docs.bienport.com/api-reference/user-api/find-user-by-id /open-api/api-docs.yml get /user/{userId}/get # Find User By Screen Name Source: https://api-docs.bienport.com/api-reference/user-api/find-user-by-screen-name /open-api/api-docs.yml get /user/get-screen-name/{screenName} # Get Current User Source: https://api-docs.bienport.com/api-reference/user-api/get-current-user /open-api/api-docs.yml get /user/get-current-user # Get User Organizations Users Source: https://api-docs.bienport.com/api-reference/user-api/get-user-organizations-users /open-api/api-docs.yml get /user/{userId}/organization-users # Reset Password Source: https://api-docs.bienport.com/api-reference/user-api/reset-password /open-api/api-docs.yml put /user/reset-password # Update Password Source: https://api-docs.bienport.com/api-reference/user-api/update-password /open-api/api-docs.yml put /user/update-password # Update User Source: https://api-docs.bienport.com/api-reference/user-api/update-user /open-api/api-docs.yml put /user/update # User Invite Source: https://api-docs.bienport.com/api-reference/user-api/user-invite /open-api/api-docs.yml post /user/invite # User Logout Source: https://api-docs.bienport.com/api-reference/user-api/user-logout /open-api/api-docs.yml post /user/logout # Validate Verification Code Source: https://api-docs.bienport.com/api-reference/validate-verification-code-api/validate-verification-code /open-api/api-docs.yml post /verification-sms/validate-password-reset-code # Validate Verification Code For Register Source: https://api-docs.bienport.com/api-reference/validate-verification-code-api/validate-verification-code-for-register /open-api/api-docs.yml post /verification-sms/validate-registration-code # Mobile App → Alarm Panel Commands Source: https://api-docs.bienport.com/mqtt-reference/alarm-panel-commands This section describes how mobile applications can send commands to alarm panels over MQTT, and how responses are delivered back through subscribed topics. This is a public API! All command messages must be published to the queue `resource/commands` with a valid JWT token.
Responses are delivered on `secom/mobileapp/`. Use a unique `correlationId` to pair requests and responses.
**Transport:** MQTT (pub/sub). The alarm panel publishes commands to broker queues. ## Message Envelope (Common Schema) ### Command Request (Envelope) ```json theme={null} { "messageType": "commandMessage", "appId": "your-app-id", "brand": "EBS", "jwtToken": "jwt-token", "userId": 20199, "organizationId": "123456", "command": "", "correlationId": "", "parameters": { /* command-specific */ } } ``` * **Publish to:** `resource/commands` * **Security:** `jwtToken` must be valid; sensitive fields (e.g., `pinCode`) must be **AES‑256 encrypted** inside `parameters`. ### Command Response (Envelope) ```json theme={null} { "messageType": "commandResponse", "correlationId": "", "result": "", "reason": "", "data": { /* command-specific payload */ } } ``` * **Result codes** * `success` – command accepted and processed; see `data`. * `failed` – command delivered but panel or backend reported failure. * `not send` – validation/authz failed; command not sent to panel. * `send_no_ack` – published but no ACK from panel within timeout. * `unauthorized` – JWT invalid/expired or user lacks access. ### Error Response Templates (Examples) **Missing User / Access Check Skipped** ```json theme={null} { "messageType": "commandResponse", "correlationId": "", "result": "not send", "reason": "UserId is missing, could not check access authorization to resourceId!", "data": { "command": "", "resourceId": 34 } } ``` **Unauthorized** ```json theme={null} { "messageType": "commandResponse", "correlationId": "", "result": "unauthorized", "reason": "User not authorized to access alarm panel!", "data": { "command": "", "resourceId": 34 } } ``` **Panel Disabled** ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "not send", "reason": "Panel is disabled!", "data": { "command": "arm", "resourceId": 35, "userId": 20199 } } ``` **Panel Not Found** ```json theme={null} { "messageType": "commandResponse", "correlationId": "2", "result": "not send", "reason": "Panel not found!", "data": { "command": "arm", "resourceId": 35, "userId": 20199 } } ``` **Command Failed** ```json theme={null} { "messageType": "commandResponse", "correlationId": "2", "result": "failed", "reason": "Command not allowed", "data": { "command": "arm", "partition": 1, "resourceId": 34, "brand": "EBS", "model": "CPX-230NWB", "networkId": "654527" } } ``` **Command Not Permitted** ```json theme={null} { "messageType": "commandResponse", "correlationId": "2", "result": "unauthorized", "reason": "Command not permitted", "data": { "command": "arm", "partition": 1, "resourceId": 34, "brand": "EBS", "model": "CPX-230NWB", "networkId": "654527" } } ``` **Generic Error** ```json theme={null} { "messageType": "commandResponse", "correlationId": "2", "result": "unknown", "reason": "Exception-message-here", "data": { "command": "arm", "resourceId": 35, "userId": 20199 } } ``` **Command Not Found** ```json theme={null} { "messageType": "commandResponse", "correlationId": "3", "result": "failed", "reason": "Command not found!", "parameters": { "command": "panel-arm" } } ``` **Transmission Failed** ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "send_no_ack", "reason": "Command transmission failed, try again after a while" } ``` **Partition Not Found** ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "partitionNotFound", "reason": "The partition you want to change its status is not available", "data": { "command": "arm", "partition": 5, "resourceId": 486, "brand": "EBS", "model": "CPX-230NWB", "networkId": "702716" } } ``` **User Not Allowed** ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "notAuthorizedForPartition", "reason": "You do not have permission to perform operations in this partition.", "data": { "command": "arm", "partition": 1, "resourceId": 486, "brand": "EBS", "model": "CPX-230NWB", "networkId": "702716" } } ``` *** # Command - Response Pairs Below are **command-specific requests** and their **successful** responses. For failures, refer to the **Error Response Templates** above. *** ## 1. Arm > Arms the alarm panel for a given partition. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 20199, "organizationId": "123456", "command": "arm", "correlationId": "1", "parameters": { "resourceId": 34, "partition": 1, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "data": { "command": "arm", "partition": 1, "resourceId": 34, "brand": "EBS", "model": "CPX-230NWB", "networkId": "654527" } } ``` *** ## 2. Stay Arm > Arms the alarm panel in **Stay/Indoor** mode. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 20199, "organizationId": "123456", "command": "armStay", "correlationId": "2", "parameters": { "resourceId": 35, "partition": 1, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "3", "result": "success", "data": { "command": "armStay", "partition": 1, "resourceId": 35, "brand": "EBS", "model": "CPX-300W", "networkId": "1065885" } } ``` *** ## 3. Sleep Arm > Arms the alarm panel in **Sleep/Night** mode. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 20199, "organizationId": "123456", "command": "armSleep", "correlationId": "1", "parameters": { "resourceId": 35, "partition": 1, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "2", "result": "success", "data": { "command": "armSleep", "partition": 1, "resourceId": 35, "brand": "EBS", "model": "CPX-300W", "networkId": "1065885" } } ``` *** ## 4. Disarm > Disarms the alarm panel for a given partition. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 20199, "organizationId": "123456", "command": "disarm", "correlationId": "1", "parameters": { "resourceId": 34, "partition": 1, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "data": { "command": "disarm", "partition": 1, "resourceId": 34, "brand": "EBS", "model": "CPX-230NWB", "networkId": "654527" } } ``` *** ## 5. Arm Zone > Arms a specific zone. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 20199, "organizationId": "123456", "command": "armZone", "correlationId": "5", "parameters": { "resourceId": 34, "partition": 1, "zone": 12, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "data": { "command": "armZone", "zone": 12, "resourceId": 50, "brand": "EBS", "model": "CPX-300W", "networkId": "1065885" } } ``` ### Spesific Error Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "5", "result": "not send", "reason": "No sensors assigned to alarm panel", "data": { "resourceId": 34, "partition": 1, "zone": 12 } } ``` *** ## 6. Disarm Zone > Disarms a specific zone. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 20199, "command": "disarmZone", "organizationId": "123456", "correlationId": "2", "parameters": { "resourceId": 34, "partition": 1, "zone": 12, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "3", "result": "success", "data": { "command": "disarmZone", "partition": 1, "resourceId": 50, "brand": "EBS", "model": "CPX-300W", "networkId": "1065885" } } ``` ### Spesific Error Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "2", "result": "not send", "reason": "No sensors assigned to alarm panel", "data": { "resourceId": 34, "partition": 1, "zone": 12 } } ``` *** ## 7. Zone Bypass > Bypasses (ignores) a zone. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 146011, "organizationId": "123456", "command": "zonesBypass", "correlationId": "1", "parameters": { "resourceId": 178, "zones": [10,11,12], "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "data": { "command": "zonesBypass", "resourceId": 178, "zones": [10,11,12], "brand": "EBS", "model": "CPX230", "networkId": "1065885" } } ``` *** ## 8. Zone Unbypass > Removes bypass state from a zone. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 146011, "organizationId": "123456", "command": "zonesUnbypass", "correlationId": "1", "parameters": { "resourceId": 178, "zones": [10,11,12], "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "data": { "command": "zonesUnbypass", "zones": [10,11,12], "resourceId": 178, "brand": "EBS", "model": "CPX230", "networkId": "1065885" } } ``` *** ## 9. Set Output > Controls panel outputs (e.g., relays, DOs). ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 146011, "organizationId": "123456", "command": "setOutput", "correlationId": "1", "parameters": { "resourceId": 178, "output": 1, "status": 1, "duration": 5, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "data": { "command": "setOutput", "resourceId": 178, "brand": "EBS", "model": "CPX230", "networkId": "1065885" } } ``` *** ## 10. Get Status > Retrieves the status of the alarm panel. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 146011, "organizationId": "123456", "command": "getStatus", "correlationId": "1", "parameters": { "resourceId": 178, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response 1 All properties don’t have any true value ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "data": { "command": "getStatus", "isReadyForArm": false, "currentPartitionAlarms": [], "zoneAlarmHistory": [], "remoteControllerAlarm": false, "tamperKeypad": [], "zoneTampers": [], "keypadTampers": [], "alarmingZones": [], "lockedZones": [], "armedPartitions": [], "alarmingOutputs": [], "batteryVoltage": 10.657, "powerSupplyVoltage": 17.028, "silentAlarmHistory": [], "zonesComFailures": [], "zonesPowerFailures": [], "partitionsStayAway": [], "partitionsNight": [], "resourceId": 178, "brand": "EBS", "model": "CPX230", "networkId": "1065885" } } ``` ### Success Response 2 All properties have at least one true value ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "data": { "command": "getStatus", "isReadyForArm": true, "currentPartitionAlarms": [ { "partition": 2, "value": true } ], "zoneAlarmHistory": [ { "zone": 1, "value": true } ], "remoteControllerAlarm": false, "tamperKeypad": [ { "keypad": 1, "value": true } ], "zoneTampers": [ { "zoneTamper": 1, "value": true } ], "keypadTampers": [ { "keypadTamper": 1, "value": true } ], "alarmingZones": [ { "zone": 1, "value": true } ], "lockedZones": [ { "zone": 1, "value": true } ], "armedPartitions": [ { "partition": 2, "value": true } ], "alarmingOutputs": [ { "output": 1, "value": true } ], "batteryVoltage": 13.889, "powerSupplyVoltage": 20.747, "silentAlarmHistory": [ { "zone": 1, "value": true } ], "zonesComFailures": [ { "zone": 1, "value": true } ], "zonesPowerFailures": [ { "zone": 1, "value": true } ], "partitionsStayAway": [ { "partition": 2, "value": true } ], "partitionsNight": [ { "partition": 2, "value": true } ], "resourceId": 178, "brand": "EBS", "model": "CPX230", "networkId": "1065885" } } ``` *** ## 11. Get Failures > Retrieves active failures reported by the panel. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "jwtToken": "replace-with-your-token", "userId": 146011, "organizationId": "123456", "command": "getFailures", "correlationId": "1", "parameters": { "resourceId": 178, "pinCode": "AES-256 encrypted pin code" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "reason": "send", "data": { "command": "getFailures", "outFailures": [ { "outNumber": 2, "value": true } ], "powerOutFailures": [ { "powerOut": 1, "outName": "KPOUT", "value": true }, { "powerOut": 2, "outName": "AUX1", "value": true }, { "powerOut": 3, "outName": "AUX2", "value": true } ], "powerInFailures": [ { "powerIn": 1, "inName": "MAINS", "value": true }, { "powerIn": 2, "inName": "BATTERY", "value": true } ], "keypadCommFailures": [ { "keypadNo": 1, "value": true }, { "keypadNo": 2, "value": true } ], "keypadPowerFailures": [ { "keypadNo": 1, "value": true }, { "keypadNo": 2, "value": true } ], "otherFailures": [ { "type": 1, "name": "CLOCK_NOT_SYNC", "value": true }, { "type": 2, "name": "CONF_MEM_FAIL", "value": true } ], "resourceId": 638, "brand": "EBS", "model": "CPX-300W", "networkId": "1065885" } } ``` *** ## 12. Initiate Connection > Instructs the panel to initiate a fresh connection. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "DSC", "jwtToken": "replace-with-your-token", "userId": 146011, "organizationId": "123456", "command": "initiateConnection", "correlationId": "1", "parameters": { "resourceId": 178 } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "reason": "Kick-start SMS sent to alarm panel", "data": { "command": "initiateConnection", "resourceId": 178, "brand": "DSC", "model": "NEO-2032", "networkId": "123456" } } ``` ### Spesific Error Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "not sent", "reason": "No GSM line number (MSISDN) defined for alarm panel", "data": { "command": "initiateConnection", "resourceId": 178, "userId": 20199 } } ``` *** ## 13. Set Pin Code > Updates the pin code for future operations. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "DSC", "jwtToken": "", "userId": 50678, "organizationId": "50164", "command": "setPinCode", "correlationId": "1", "parameters": { "resourceId": 786, "partition": 0, "userType": "master/installer/regular", "userIndex": 1, "currentPinCode": "83T47L2ueJdAs0Rl80pdUQ==", "newPinCode": "83T47L2ueJdAs0Rl80pdUQ==" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "reason": "send", "data": { "command": "setPinCode", "resourceId": 786, "partitionNo": 0, "userType": "master/installer/regular" } } ``` Keep error handling DRY: implement a shared mapper from `result` + `reason` to user‑facing messages. # (Internal) API Gateway ↔ Communication Backend Source: https://api-docs.bienport.com/mqtt-reference/apigw-backend-commands AMQP-based internal command/response flows between the Api Gateway and Communication Backend service. This is a private API and works internally! **Scope:** This section documents the **internal** AMQP exchanges used by the Api Gateway to query/maintain system state and enrich external MQTT command flows. These messages are **not** exposed to mobile/web clients directly. ## Transport & Routing * **Protocol:** AMQP * **Request Queue (gateway → backend):** `resource.commands` * **Response Queue (backend → gateway):** `bimetri.apiservice.` * **Correlation:** `correlationId` is mandatory. Gateway sets it; backend mirrors it in replies. * **Delivery:** at‑least‑once; consumers must be idempotent. * **Delivered via routing key:** `bimetri.apiservice.` Internal payloads may include identifiers not present in external APIs (e.g., `resourceId`, `sensorId`, `controllerId`). Treat them as **opaque** outside the backend boundary. Note: Keys in requests are unique to each request and are used to queue requests. # Commands Below are common internal commands the Api Gateway uses to hydrate caches, resolve routing, and enrich MQTT command/notification paths. ## 1) Get Sensors Command > Returns the list of sensors discovered on the panel (zone → sensor mapping, with metadata). ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "command": "getSensors", "correlationId": "1", "parameters": { "resourceId": 50, "key": "random-UUID" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "reason": "send", "data": { "command": "getSensors", "resourceId": 50, "key": "random-UUID", "sensors": [ { "zone": "10", "hardwareSerial": "350001938", "sensorId": 40, "sensorName": "PIRCAM-30 Kameralı Wifi Hareket Sensörü", "sensorType": "Digital" }, { "zone": "12", "hardwareSerial": "340004502", "sensorId": 39, "sensorName": "PIR-30 Kablosuz Hareket Dedektörü", "sensorType": "Digital" } { "zone": "9", "hardwareSerial": "830002331", "sensorName": "Not defined or not a sensor", "sensorType": "Unknown" } ] } } ``` ## 2) Get Controllers Command > Returns output controllers per partition (e.g., relays / DOs) that can be driven by the platform. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "command": "getControllers", "correlationId": "1", "parameters": { "resourceId": 50, "pinCode": "AES-256 encrypted pin code", "key": "random-UUID" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "344", "result": "success", "reason": "send", "data": { "command": "getControllers", "resourceId": 370, "key": "1105a80d-df06-4dc0-8970-ff4c6c766dc7", "partitionControllers": [ { "partitionNo": 1, "controllers": [ { "controllerId": 34, "outputPort": 1, "controllerName": "Röle", "controllerType": "Digital" } ] }, { "partitionNo": 2, "controllers": [ { "controllerId": 34, "outputPort": 2, "controllerName": "Röle", "controllerType": "Digital" } ] } ] } } ``` ## 3) Get Partition Zone Command > Returns zones (sensors) grouped by partition. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "command": "getPartitionZone", "correlationId": "1", "parameters": { "resourceId": 1, "pinCode": "AES-256 encrypted pin code", "key": "random-UUID" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "346", "result": "success", "reason": "send", "data": { "resourceId": 370, "command": "getPartitionZone", "key": "1105a80d-df06-4dc0-8970-ff4c6c766dc7", "partitionSensors": [ { "partitionNo": 1, "zones": [ { "sensorId": 114, "zoneNumber": 1, "sensorName": "Kablolu Sensör", "sensorType": "Dijital" } ] }, { "partitionNo": 2, "zones": [ { "sensorId": 114, "zoneNumber": 2, "sensorName": "Kablolu Sensör", "sensorType": "Dijital" } ] } ] } } ``` ## 4) Get Partition Name Command > Returns the human-friendly name for a given partition number. ### Request ```json theme={null} { "messageType": "commandMessage", "appId": "replace-with-your-app’s-unique-id", "brand": "EBS", "command": "getPartitionName", "correlationId": "1", "parameters": { "resourceId": 195, "partitionNo": 1, "key": "random-UUID" } } ``` ### Success Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "1", "result": "success", "reason": "send", "data": { "partitionNo": "1", "partitionName": "Partition 1", "resourceId": 195, "key": "random-UUID", } } ``` # Backend → Mobile App Notifications Source: https://api-docs.bienport.com/mqtt-reference/backend-mobileapp-notifications AMQP notifications published by Backend for Mobile App clients; consumed via app-specific topics. This is a public API! Transport: AMQP (pub/sub via broker).
Subscribed Topic (all events): secom/mobileapp/\
Envelope: Each message is a JSON object with messageType = "notification" and an event-specific notificationType.
## Message Envelope (Common) ```json theme={null} { "messageType": "notification", "appId": "", "correlationId": "", "notificationType": "", "reason": "", "parameters": { /* event-specific fields */ } } ``` Unless otherwise stated, notifications are delivered to secom/mobileapp/\. # 1) Arm / ArmStay / ArmSleep Notification > Emitted when the panel is armed (including Stay/Indoor and Sleep/Night modes). ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "app-unique-id", "correlationId": "1", "notificationType": "armNotification", "reason": "Partition 1 Armed", "parameters": { "partition": 1, "resourceId": 169, "brand": "EBS", "model": "CPX-230NWB", "networkId": "654527" }} ``` The reason text may reflect the specific arming mode and partition number. *** # 2) Disarm Notification > Emitted when the panel is disarmed. ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "app-unique-id", "correlationId": "1", "notificationType": "disarmNotification", "reason": "Partition 1 Disarmed", "parameters": { "partition": 1, "resourceId": 169, "brand": "EBS", "model": "CPX-230NWB", "networkId": "654527" } } ``` *** # 3) Zone Alarm Notification > Emitted when a zone alarm is triggered. ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "", "notificationType": "zoneAlarmNotification", "reason": "Zone 12 Open", "parameters": { "resourceId": 1346, "model": "CPX-300W", "networkId": "1065885" } } ``` *** # 4) Keypad or Keyfob Alarm Notification > Emitted when a keypad or keyfob alarm is triggered. ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "replace-with-your-app’s-unique-id", "notificationType": "keypadKeyfobAlarmNotification", "reason": "Silent Alarm with Keyfob", "parameters": { "resourceId": 1346, "model": "CPX-300W", "networkId": "1065885" } } ``` *** # 5) Panic Alarm Notification > Emitted when a mobile panic alarm is triggered. ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "replace-with-your-app’s-unique-id", "notificationType": "panicAlarmNotification", "reason": "Mobile Panic Alarm", "parameters": { "resourceId": 175, "model": "CPX-300W", "networkId": "1065885" } } ``` *** # 6) Ambulance (Medical) Alarm Notification > Emitted when a mobile medical/ambulance alarm is triggered. ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "replace-with-your-app’s-unique-id", "notificationType": "ambulanceAlarmNotification", "reason": "Mobile Medical Alarm", "parameters": { "resourceId": 175, "model": "CPX-300W", "networkId": "1065885" } } ``` *** # 7) Resource Disconnect Notification > Emitted when the alarm panel (resource) connection is lost. ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "replace-with-your-app’s-unique-id", "notificationType": "resourceDisconnectNotification", "reason": "Device Disconnected", "parameters": { "resourceId": 1346, "model": "CPX-300W", "networkId": "1065885" } } ``` *** # 8) Resource Connected Notification > Emitted when the alarm panel (resource) connection is established. ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "app-unique-id", "correlationId": "1", "notificationType": "connectionInitiated", "reason": "Panel connected by request", "parameters": { "resourceId": 169, "brand": "DSC", "model": "NEO-2032", "networkId": "123456", "msisdn": "905wwxxxyyzz" } } ``` *** # 9) Panel Connection Initiated (by Request) > Emitted when the panel starts a command-channel connection by request (DSC panels only). ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "app-unique-id", "correlationId": "1", "notificationType": "connectionInitiated", "reason": "Panel connected by request", "parameters": { "resourceId": 169, "brand": "DSC", "model": "NEO-2032", "networkId": "123456", "msisdn": "905wwxxxyyzz" } } ``` *** # 10) Panel Connection Not Initiated (by Request) > Emitted when the panel could not initiate the command-channel connection by request (DSC panels only). ### Success Payload ```json theme={null} { "messageType": "notification", "appId": "app-unique-id", "correlationId": "1", "notificationType": "connectionNotInitiated", "reason": "Panel is not able to connect by request", "parameters": { "resourceId": 169, "brand": "DSC", "model": "NEO-2032", "networkId": "123456", "msisdn": "905wwxxxyyzz" } } ``` reason is localized in messages regarding to locale settings of user. Treat unknown properties under parameters as forward‑compatible extensions. # ERP → API Gateway Push Notifications Source: https://api-docs.bienport.com/mqtt-reference/erp-apigw-push-notifications Domain events pushed from ERP to the Api Gateway via AMQP for customer or subscription information change This is a private API and requires secure connection with ERP software! **Transport:** AMQP (pub/sub). The platform publishes notifications to broker queues. ## Message Envelope (Common) Notifications are published as **domain payloads** (no extra wrapper) to the queues listed below. * **Content-Type:** `application/json` * **Delivery:** at-least-once (consumer should ack after successful processing) * **Idempotency hint:** use the top-level `id` and event-specific keys to de‑duplicate if your consumer is retried. *** # 1) Customer Change Push Notification > Emitted when a customer is created/updated/deactivated in ERP. **Queue:** `secom-customer-queue` ### Notes * `id` corresponds to **customerId** in the ERP. * `status` can be `Active` or `Passive`. ### Example Payload (with address/contact fields) ```json theme={null} { "id": "134719", "status": "Active", "name": "Customer Name Here", "contactMedium": [ { "characteristic": { "city": "İSTANBUL(Anadolu)", "country": "Türkiye", "phoneNumber": "5xxxxxxxxx", "socialNetworkId": "11111111111", "street1": "içerenköy" } } ] } ``` The object MAY include additional customer attributes and arrays (e.g., addresses, contacts) depending on ERP mapping. Treat unknown properties as forward‑compatible. *** # 2) Subscription Change Push Notification > Emitted when a subscription/agreement changes state or details in ERP. **Queue:** `secom-subscriptions-queue` ### Notes * `id` corresponds to **subscriptionId** in the ERP. * `engagedParty` corresponds to `customerId` in the ERP. ### Example Payload (with ERP property bag) ```json theme={null} { "id":"123462", "agreementType":"Kiralama", "documentNumber":"108999", "name":"RAMAZAN ÖZEKİNCİ", "status":"Active", "characteristic":[ { "name":"CAMPAIGN", "valueType":"String", "value":"24 AY TAAHHÜTLÜ" }, { "name":"MONTAGEADRESS", "valueType":"String", "value":"PINAR MAH. ONDOKUZ MAYIS BLV. AK TOWERS NO:42 İÇ KAPI NO:84" }, { "name":"MONTAGECOUNTY", "valueType":"String", "value":"ESENYURT" }, { "name":"MONTAGECITY", "valueType":"String", "value":"İSTANBUL(Avrupa)" }, { "name":"MONTAGE_DATE", "valueType":"Date", "value":"2021-08-16" }, { "name":"TOTAL_PAST_DUE_INSTALMENT", "valueType":"Float", "value":"0.0" }, { "name":"PANELBRAND", "valueType":"String", "value":"EBS" }, { "name":"PANELMODEL", "valueType":"String", "value":"CPX-300W" }, { "name":"PANELNO", "valueType":"String", "value":"1065885" }, { "name":"SALESEMP","valueType":"String","value":"ÜMİT" }, { "name":"STAGE","valueType":"String","value":"6 - Sinyal Alımı Gerçekleşti" } ], "completionDate":{"endDateTime":"2023-08-16","startDateTime":"2021-08-13"}, "engagedParty":[ { "id" : "134719" } ] } ``` **Schema variance:** The ERP may send additional key/value tuples inside `properties` (triplets of `name`, `valueType`, `value`). Consumers should parse this bag defensively. *** ## Consumer Guidance * **Ack/Nack:** use your AMQP client’s normal ack flow; only ack after persisting/processing. * **Retries:** if your app crashes before ack, the message will be re‑delivered. Make handlers idempotent. * **Ordering:** do not rely on strict global ordering across queues. Client libraries: any AMQP 0‑9‑1 compatible client, or STOMP‑over‑WebSocket (e.g., `/topic/secom-customer-queue`) / MQTT bridge topics as configured in your broker. # Introduction Source: https://api-docs.bienport.com/mqtt-reference/mqtt-commands-index This API provides a secure, event-driven way for apps to interact with IoT devices over MQTT and AMQP. 🔐 It enables reliable two-way communication, supporting commands, while also streaming real-time notifications. 📡 In short: developers can both **send structured commands** and **receive live updates** to keep apps synchronized with device status, all with strong authentication, traceability, and encrypted sensitive data. Here you’ll find a practical, event-driven API that lets external apps talk to IoT devices in real time over MQTT, while the platform fans out reliable notifications over AMQP to a pub/sub broker, which external applications can subscribe to using STOMP over WebSocket or MQTT protocols. 🚀 At a glance, clients publish commands to well-defined queues/topics (e.g., `resource/commands`) with standard envelopes (`messageType`, `appId`, `jwtToken`, `correlationId`) and receive structured responses on per-app topics. This makes actions like arming, disarming, or reading device status both predictable and traceable end-to-end. What can you do with it? Plenty. 🔧 Core command families include arming modes (Arm, Stay/Indoor, Sleep/Night), Disarm, zone-scoped operations (Arm/Disarm Zone, Zone Bypass/Unbypass), output control (`setOutput` for relays/DOs), system introspection (`getStatus`, `getFailures`), and panel-level operations like `initiateConnection` and `setPinCode`. Each returns a normalized `commandResponse` with `result` (e.g., `success`, `failed`, `not send`, `send_no_ack`, `unauthorized`) and a clear `reason`, so your app can guide users with actionable feedback. 🔁 Beyond commands, the platform streams rich notifications to keep UIs in sync without polling. 📣 Expect push events for arm/disarm transitions, zone alarms, keypad/keyfob actions, panic/medical events, connectivity changes (resource connected/disconnected), and connection-initiation outcomes. Each notification carries the essentials (model, brand, network/device IDs, partition/zone context) so you can surface precise, human-readable messages instantly. 📲 Under the hood, security and operability are first-class. 🔐 JWTs authenticate requests, correlation IDs make workflows observable, and sensitive fields such as PIN codes are transmitted as AES-256–encrypted payloads. On the backend side, internal AMQP commands expose inventory and topology data—sensors, controllers, partitions, and names—so you can build dynamic UIs that reflect the live device configuration. In the detailed sections that follow, you’ll see per-command schemas, sample publish/subscribe frames, success/error variants, and notes to help you implement quickly and safely. ✅ * Mqtt server host 1: `platform.bienport.com` * Mqtt server host 2: `sebeketakip.com` * Port: `1883` (8883-mqtts port is not yet supported!) * In the login operation response of the REST API, the payload contains the user and password information (`mqUser`, `mqPassword`). * Password decryption must be required before logging in Mqtt server. Password is encrypted with AES-256 algorithm. Ask us for AES Algorithm, Initialization Vector and Private Key to successful decode encrypted contents (such as mqPassword and pinCode). Below an example Java source code given to decode the encrpted content: ```java theme={null} public class AESUtilTest { private static final String privateKey = "********************************"; private static final String iv = "****************"; private static final String algorithm = "AES/***/************"; public static void main(String...args) { try { String input = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; System.out.println("original: " + input); // SecretKey key = AESUtil.generateKey( 256 ); SecretKey key = AESUtil.getKeySpec(privateKey); System.out.println("256-bit key (String): " + privateKey); assert key != null; System.out.println("256-bit key (Hex): 0x" + HexUtil.toHex(key.getEncoded())); System.out.println("256-bit key (Base64): " + Base64.getEncoder().encodeToString(key.getEncoded())); // IvParameterSpec ivParameterSpec = AESUtil.generateIv(); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)); System.out.println("IV (string): " + new String(ivParameterSpec.getIV())); System.out.println("IV (Hex): 0x" + HexUtil.toHex(ivParameterSpec.getIV())); System.out.println("IV (Base64): " + Base64.getEncoder().encodeToString(ivParameterSpec.getIV())); System.out.println("Algorithm: " + algorithm); String cipherText = AESUtil.encrypt(algorithm, input, key, ivParameterSpec, true); System.out.println("Encrypted (Base64): " + cipherText); cipherText = AESUtil.encrypt(algorithm, input, key, ivParameterSpec, false); System.out.println("Encrypted (Hex): 0x" + cipherText); String plainText = AESUtil.decrypt(algorithm, cipherText, key, ivParameterSpec, false); System.out.println("Decrypted: " + plainText); assertEquals(input, plainText); } catch (Exception e) { logger.error("Error:", e); } } } ``` # Third Party Application → Resource Commands Source: https://api-docs.bienport.com/mqtt-reference/third-party-commands How external apps control device outputs via MQTT and receive confirmations/notifications. This is a public API! A third‑party app sends control commands to field devices and receives both an immediate command acknowledgement and an eventual state‑change notification. ## Transport & Topics * **Publish commands to:** resource/commands\ QoS: 2 (exactly‑once delivery negotiated by MQTT) * **Subscribe for responses & notifications:** application/third-party/appName/instanceId Always include a unique correlationId in requests and verify the same value in responses/notifications. JWT must be valid; otherwise the gateway returns an error response. Allways subscribe to topic `application/third-party/appName/instanceId` where `appId` value is `appName.instanceId`in request payload! *** ## Message Envelopes (Common) ### Command Request ```json theme={null} { "messageType": "commandMessage", "appId": "appName.instanceId", "brand": "Bimetri", "jwtToken": "replace-with-your-token", "userId": 12345, "organizationId": 23456, "command": "", "correlationId": "", "parameters": { /* command-specific */ } } ``` ### Command Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "", "result": "", "reason": "", "data": { /* command-specific echo & device info */ } } ``` ### Notification (Async) ```json theme={null} { "messageType": "notification", "appId": "appName.instanceId", "correlationId": "", "command": "", "notificationType": "", "userName": "", "userId": 12345, "parameters": { /* event-specific payload */ } } ``` Responses typically acknowledge queuing (e.g., result = "sent"), while notifications carry the final device state. Treat notifications as the source of truth for UI state. *** # 1) setExtDO Command Set an external digital output (relay/DO) to on/off. ## Request ```json theme={null} { "messageType": "commandMessage", "appId": "flexyWattApp.1", "brand": "Bimetri", "jwtToken": "replace-with-your-token", "userId": 12345, "organizationId": 23456, "command": "setExtDO", "correlationId": "100", "parameters": { "resourceId": 101, "output": 4, "status": 0 } } ``` ### Parameters * resourceId (number) – Target device identifier. * output (number) – Output index/port (1‑based unless otherwise provisioned). * status (number) – Desired state: 1 (on/closed), 0 (off/open). Some deployments may validate output ranges per model; invalid ports will yield an error response. *** For this example (due to `"appId": "flexyWattApp.1"`); subscribe to topic `application/third-party/flexyWattApp/1` or `application/third-party/flexyWattApp/#` (for all instances) to receive responses and async notifications. ## Immediate Response ```json theme={null} { "messageType": "commandResponse", "correlationId": "100", "result": "sent", "reason": "Command Queued", "data": { "command": "setExtDO", "resourceId": 101, "brand": "Bimetri", "model": "BMM620", "networkId": "26:AA:E0:23:23:5E" } } ``` ### Error Response (Example) ```json theme={null} { "messageType": "commandResponse", "correlationId": "100", "result": "not_send", "reason": "The user does not have access rights to the resource!", "data": { "command": "setExtDO", "resourceId": 101, "userId": 12345 } } ```
  • not\_send – AuthN/AuthZ failed or validation error (missing fields, invalid output index).
  • send\_no\_ack – Command published but no device acknowledgement within timeout.
  • failed – Delivery ok but device/backend reported failure.
  • unauthorized – JWT invalid/expired.
*** ## State‑Change Notification Emitted when the device confirms the output’s actual state. ```json theme={null} { "messageType": "notification", "appId": "flexyWattApp.1", "correlationId": "100", "command": "setExtDO", "notificationType": "extDOStateChanged", "userName": "Flexywatt User", "userId": 12345, "parameters": { "resourceId": 101, "brand": "Bimetri", "model": "BMM620", "networkId": "26:AA:E0:23:23:5E", "organizationId": 23456, "output": 4, "status": 1 } } ``` Use the pair (resourceId, output) plus correlationId to de‑duplicate and to reconcile UI state after reconnects. *** ## Consumer Guidance * **QoS & retries:** Expect duplicate deliveries at QoS 1. Make handlers idempotent. * **Timeouts:** If no notification arrives, surface the queued state and allow users to retry. * **Security:** Store tokens securely; rotate when expired; never log full JWTs. * **Tracing:** Log correlationId on both publish and receive paths for observability.