Site Configuration Endpoint
Version V1
The Site Configuration Endpoint allows partners to register and configure downstream devices on a MOS350 gateway. Partners can pair devices such as inverters, relays, or other DER components by sending a configuration payload to the Molecule API. The Molecule API handles all communication with the gateway — this is fully encapsulated from the partner.
Production: https://api.moleculesystems.com/
Development: https://api-dev.moleculesystems.com/
Authentication
All API requests require a Bearer token obtained from the Molecule identity server.
Refer to the API Authentication guide.
Workflow Overview
The partner sends a device configuration payload to the Molecule API. The Molecule API communicates with the gateway and returns the result synchronously, all gateway interaction is fully encapsulated.
Configure Devices
Send a device configuration payload to the Molecule API to register and configure devices on a MOS350 gateway.
PUT https://api-dev.moleculesystems.com/gatewayservice/admin/device/configure?organizationId=<Organization ID>&moleculeId=<Molecule ID>
Replace <Organization ID> with your organization's UUID and <Molecule ID> with the
unique identifier for the MOS350 gateway.
Query Parameters
| Parameter | Description |
|---|---|
| organizationId | Your organization's UUID |
| moleculeId | The unique identifier for the Molecule site or gateway |
Request Headers
| Header | Value |
|---|---|
| Authorization | Bearer <your-token> |
| Content-Type | application/json |
Sample Request
curl -X PUT \
"https://api-dev.moleculesystems.com/gatewayservice/admin/device/configure?organizationId=00000000-0000-0000-0000-000000000001&moleculeId=fecdd83addd9334a" \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json" \
-d '{
"devices": [
{
"device_id": "20000",
"device_type": "modbus",
"device_name": "Inverter",
"device_integration": "00000000-0000-0000-0000-000000000001/Cesar_5b5ce76d",
"mb_type": 1,
"mb_device_type": 3,
"mb_slave_id": 1,
"mb_baud": 9600,
"mb_rtu_no": 1,
"inv_max_power": 5000,
"inv_charge_charge": 99,
"inv_min_discharge": 20,
"device_data_map": "0000002300000000000000",
"mb_check_write": [
{ "reg_cmd_id": 1, "reg_fun": 6, "reg_reg": 10, "reg_value": 40 },
{ "reg_cmd_id": 2, "reg_fun": 6, "reg_reg": 12, "reg_value": 90 }
]
}
]
}'
Sample Response
{
"devices": [
{
"device_id": "20000",
"status": "accepted",
"message": "Device paired and configured successfully."
}
]
}
Device Configuration Fields
Top-Level Fields
| Field | Type | Description |
|---|---|---|
| devices | array | List of device configuration objects to pair. |
Device Fields (devices[])
| Field | Type | Description |
|---|---|---|
| device_id | string | Unique identifier for the downstream device (e.g., inverter ID, relay ID). |
| device_type | string | Protocol type for the device. Allowed value: modbus. |
| device_name | string | Friendly name given to the device. |
| device_integration | string | Device integration identifier: <organization id>/<integration internal name>. |
| mb_type | integer | Modbus communication mode. 1=RTU, 2=TCP/IP. |
| mb_device_type | integer | Device category. 1=Meter, 2=PV Inverter, 3=Storage Inverter, 99=Others. |
| mb_slave_id | integer | Modbus slave ID for the device on the RS-485 bus. |
| mb_baud | integer | Baud rate for Modbus RTU communication (e.g., 9600). RTU only. |
| mb_rtu_no | integer | RTU port number the device is physically connected to. RTU only. |
| mb_ip | string | IP address for Modbus TCP/IP communication (e.g., 192.168.1.80). TCP only. |
| mb_port | integer | IP port for Modbus TCP/IP communication (e.g., 502). TCP only. |
| device_data_map | string | Hex string defining which energy measurements the device reports. See Data Map below. |
| mb_check_write | array (optional) | List of register write commands to verify device configuration after pairing. |
Device Setup Parameters — Type 1 (Meter)
| Field | Type | Description |
|---|---|---|
| met_legs | integer | Number of legs to be configured in the meter. |
Device Setup Parameters — Type 2 (PV Inverter)
| Field | Type | Description |
|---|---|---|
| inv_max_power | integer | Max power rating of the inverter in watts. |
Device Setup Parameters — Type 3 (Storage Inverter)
| Field | Type | Description |
|---|---|---|
| inv_max_power | integer | Max power rating of the inverter in watts. |
| inv_charge_charge | integer | Maximum allowed charge limit of the battery in percentage. (0-100) |
| inv_min_discharge | integer | Minimum allowed discharge limit of the battery in percentage. (0-100) |
Register Write Fields (mb_check_write[])
| Field | Type | Description |
|---|---|---|
| reg_cmd_id | integer | Unique identifier for this register write command. |
| reg_fun | integer | Modbus function code (e.g., 6 = Write Single Register). |
| reg_reg | integer | Modbus register address. |
| reg_value | integer | Value to write to the target register. |
mb_check_write is used to verify and write Modbus registers to the device once a
successful pairing is established. It can be omitted if register verification is not needed.
Device Data Map
The device_data_map field is a hex string that tells the Molecule gateway which energy
measurements a device is responsible for reporting.
Structure
The string is parsed as a sequence of byte pairs (2 hex chars = 1 byte). It has two sections:
Bytes 0–3 — 32-bit measurement bitmap
Each bit in this 32-bit value enables a specific energy measurement. Byte 0 holds the most significant bits (bits 31–24), byte 3 holds the least significant bits (bits 7–0).
| Byte | Bits |
|---|---|
| Byte 0 (chars 1–2) | bits 31–24 |
| Byte 1 (chars 3–4) | bits 23–16 |
| Byte 2 (chars 5–6) | bits 15–8 |
| Byte 3 (chars 7–8) | bits 7–0 |
The measurement bits are defined in byte 3:
| Bit | Measurement | Description |
|---|---|---|
| 0 | Grid Usage | Active power consumed from the grid |
| 1 | Grid Export | Active power exported to the grid |
| 2 | Generation | Active power generated (e.g. solar) |
| 3 | Battery Charge | Energy charged into the battery |
| 4 | Battery Discharge | Energy discharged from the battery |
| 5 | Battery SOC | State of charge of the battery |
Bytes 4 onward — leg configuration
Each subsequent byte defines which Modbus register leg to read for the corresponding measurement, in the same order as the bits above (byte 4 = leg for Usage, byte 5 = leg for Export, and so on).
Full string layout
Pos: 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22
[ byte0 ][ byte1 ][ byte2 ][ byte3 ][leg:0][leg:1][leg:2][leg:3][leg:4][leg:5]...
[ bitmap MSB ][ ][ ][bitmap LSB ][Usage][Exp ][Gen ][BChg ][BDis][SOC ]
Examples
No measurements mapped (default):
device_data_map: "0000000000000000000000"
Battery SOC only (bit 5 set in byte 3 → 0x20):
device_data_map: "0000002000000000000000"
Grid usage and export (bits 0 and 1 → 0x03):
device_data_map: "0000000300000000000000"
Grid usage, export and solar generation (bits 0, 1, 2 → 0x07):
device_data_map: "0000000700000000000000"
Storage inverter — usage, export, SOC (bits 0, 1, 5 → 0x23):
device_data_map: "0000002300000000000000"
Full storage inverter — all measurements (bits 0–5 → 0x3F):
device_data_map: "0000003F00000000000000"
If device_data_map is omitted or empty, the gateway defaults to a zeroed map with no
measurements assigned. For most devices at least one bit should be set so the gateway
knows what data to collect.
Error Responses
Device Pairing Failed
{
"devices": [
{
"device_id": "20000",
"status": "error",
"code": "PAIRING_FAILED",
"message": "Failed to pair device. The device did not respond."
}
]
}
Registry Write Failed
{
"devices": [
{
"device_id": "20000",
"status": "error",
"code": "REGISTRY_WRITE_FAILED",
"message": "Device paired but register write failed."
}
]
}
Partial Success
{
"devices": [
{
"device_id": "20000",
"status": "accepted",
"message": "Device paired and configured successfully."
},
{
"device_id": "21000",
"status": "error",
"code": "PAIRING_FAILED",
"message": "Failed to pair device. The device did not respond."
}
]
}
When pairing partially fails, retry only devices with "status": "error" — do not
resubmit devices that already returned "status": "accepted".
A REGISTRY_WRITE_FAILED result means the device paired successfully but is not fully
configured. Verify the register addresses and values in mb_check_write before retrying.
Best Practices
Idempotency
Reuse the same device_id when retrying a failed configuration. The endpoint treats
repeated calls with the same device_id as the same configuration and will not create
duplicate entries.
Generating a new device_id on every retry may result in duplicate device registrations.
Always reuse the original device_id when retrying.
Retry Logic
- Retry only on network or server errors
- Do not change
device_idbetween retries for the same device - When pairing partially fails, retry only devices with
"status": "error"— do not resubmit devices that already returned"status": "accepted"