JSON Request Examples per Endpoint
March 27, 2026 · View on GitHub
Request payloads extracted from thomluther's Python code (marked upstream-sourced) and supplemented with Blutter-decompiled parameters (marked inferred). Replace placeholder values (siteId, deviceSn, etc.) with actual IDs.
Note: "upstream-sourced" means the payload comes from thomluther/anker-solix-api's community-tested implementation, not that we independently tested it against the API.
Upstream-Sourced Requests (from thomluther/anker-solix-api, community-tested)
check_upgrade_record
check_upgrade_record
{"type": recordType} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["check_upgrade_record"]}_{recordType}.json"
compatible_process
compatible_process
{"solarbank_sn": solarbankSn} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["compatible_process"]}_{solarbankSn}.json"
get_ai_ems_status
ai_ems_status
{"site_id": siteId} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_ai_ems_status"]}_{siteId}.json"
get_co2_ranking
co2_ranking
{"site_id": siteId} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_co2_ranking"]}_{siteId}.json"
get_cutoff
power_cutoff
{"site_id": siteId, "device_sn": deviceSn} if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_cutoff"]}_modified_{deviceSn}.json"
get_device_attributes
device_attrs
{"site_id": siteId, "device_sn": deviceSn} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_device_fittings"]}_{deviceSn}.json"
get_device_charge_order_stats
charge_order_stats
{"site_id": siteId} if deviceSn: data.update({"device_sn": deviceSn})
get_device_fittings
device_fittings
{"site_id": siteId, "device_sn": deviceSn} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_device_fittings"]}_{deviceSn}.json"
get_device_load
device_load
{"site_id": siteId, "device_sn": deviceSn} if fromFile: # For file data, verify first if there is a modified schedule to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_device_load"]}_modified_{deviceSn}.json"
get_device_parm
device_parm
{"site_id": siteId, "param_type": paramType} if fromFile: # For file data, verify first if there is a modified schedule to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_device_parm"]}_{paramType}_modified_{siteId}.json"
get_device_pv_price
device_pv_price
{"sn": deviceSn} if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_device_pv_price"]}_modified_{deviceSn}.json"
get_device_pv_statistics
device_pv_statistics
{"site_id": siteId} if deviceSn: data.update({"device_sn": deviceSn})
get_device_pv_status
device_pv_status
{"sns": sns} if fromFile: # combine status of each device file into single response for multiple devices resp = {}
get_device_pv_total_statistics
device_pv_total_statistics
{"sn": deviceSn} if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_device_pv_total_statistics"]}_modified_{deviceSn}.json"
get_dynamic_price_details
dynamic_price_details
{"site_id": str(siteId)} if decimals is not None: data["accuracy"] = decimals if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_site_price"]}_modified_{siteId}.json"
get_dynamic_price_providers
dynamic_price_providers
{"device_pn": model} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_dynamic_price_providers"]}_{model}.json"
get_ota_batch
ota_batch
{"site_id": siteId} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["wifi_list"]}_{siteId}.json"
get_ota_info
ota_info
{"solar_bank_sn": solarbankSn, "solar_sn": inverterSn} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_ota_info"]}_{solarbankSn or inverterSn}.json"
get_ota_update
ota_update
{"device_sn": deviceSn, "insert_sn": insertSn} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_ota_update"]}_{deviceSn}.json"
get_site_power_limit
power_limit
{"site_id": siteId} if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_site_power_limit"]}_modified_{siteId}.json"
get_site_price
price
{"site_id": str(siteId)} if decimals is not None: data["accuracy"] = decimals if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_site_price"]}_modified_{siteId}.json"
get_upgrade_record
upgrade_record
{"type": recordType} if fromFile: resp = await self.apisession.loadFromFile( Path( self.testDir() / f"{API_FILEPREFIXES["get_upgrade_record"]}_{recordType}_{deviceSn or siteId or recordType}.json"
home_load_chart
power_service/v1/site/get_home_load_chart
{"site_id": siteId} if deviceSn: data.update({"device_sn": deviceSn})
scene_info
scene
{"site_id": siteId} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["scene_info"]}_{siteId}.json"
set_auto_upgrade
power_service/v1/app/set_auto_upgrade
{"site_id": siteId} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["scene_info"]}_{siteId}.json"
set_cutoff
power_service/v1/app/compatible/set_power_cutoff
{"site_id": siteId, "device_sn": deviceSn} if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_cutoff"]}_modified_{deviceSn}.json"
set_device_load
power_service/v1/app/device/set_device_home_load
{} # get all SB1 in system that may share same schedule with device and update their schedule for sn in [ sn for sn, sb in self.devices.items() if sb.get("site_id") == siteId and sb.get("type") == SolixDeviceType.SOLARBANK.value and (sb.get("generation") or 0) <= 1 ]: self._update_dev(
set_device_parm
power_service/v1/site/set_site_device_param
{} # get all solarbanks that may share same schedule or are managed by a station dev_serials = { sn for sn, sb in self.devices.items() if sb.get("site_id") == siteId and sb.get("type") == SolixDeviceType.SOLARBANK.value and (sb.get("generation") or 0) >= 2 }
set_device_pv_price
charging_pv_svc/updateUserTieredElecPrice
{"sn": deviceSn} if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_device_pv_price"]}_modified_{deviceSn}.json"
site_detail
site_detail
{"site_id": siteId} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["site_detail"]}_{siteId}.json"
solar_info
solar_info
{"solarbank_sn": solarbankSn} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["solar_info"]}_{solarbankSn}.json"
update_site_price
power_service/v1/site/update_site_price
{"site_id": str(siteId)} if decimals is not None: data["accuracy"] = decimals if fromFile: # For file data, verify first if there is a modified file to be used for testing if not ( resp := await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["get_site_price"]}_modified_{siteId}.json"
wifi_list
wifi_list
{"site_id": siteId} if fromFile: resp = await self.apisession.loadFromFile( Path(self.testDir()) / f"{API_FILEPREFIXES["wifi_list"]}_{siteId}.json"
Inferred Requests (from Blutter decompilation)
These are parameter names found near API call sites. The actual JSON structure may differ. Field values are placeholders.
add_charging_mode
Function: addCustomChargeMode
{"device_sn": "...", "name": "...", "number": "...", "total_power": "...", "max_total_power": "...", "auto_exit": "...", "has_charge_protocol": "...", "power_settings": "..."}
add_feedback
Function: postFeedback
{"attachment_key_prefixs": "...", "device_name": "...", "product_number": "...", "device_sn": "...", "user_name": "...", "user_email": "...", "message_content": "...", "type": "..."}
add_manual_clock_screensavers
Function: addA2345CustomClockScreenSavers
{"sn": "...", "img_url": "...", "hash_code": "..."}
adjust_station_price_unit
Function: changePriceUnit
{"station_id": "...", "price_unit": "..."}
banners
Function: getBanners
{"region": "..."}
check_function
Function: checkFunction
{"station_id": "..."}
check_third_sn
Function: checkThirdSN
{"device_model": "...", "device_sn": "...", "brand_id": "..."}
confirm_permissions_settings
Function: getConfirmPermissionsSettingsApi
{"device_model": "...", "confirm_type": "..."}
create_site
Function: createSiteRequest
{"site_name": "...", "site_img": "...", "solar_list": "...", "pps_list": "...", "solarbank_list": "...", "home_backup_system_list": "...", "powerpanel_list": "...", "grid_list": "..."}
deal_share_data
Function: agreeOrRefuseVppDisclaimer
{"sn": "...", "action": "..."}
delete_charging_mode
Function: deleteCustomChargeMode
{"id": "..."}
delete_manual_clock_screensavers
Function: deleteA2345CustomClockScreenSavers
{"id": "..."}
device_command
Function: sendDeviceCommand
{"station_id": "...", "main_sn": "...", "time": "...", "electricity_strategy": "...", "add_diesel": "...", "screen_setting": "...", "utility_rate_plan": "...", "ack_peak_valley": "..."}
dst
Function: getDaylightSavingTime
{"city": "..."}
getPvStatus
Function: getPvStatus
{"sns": "..."}
get_addable_site_list
Function: getAddableSiteList
{"device_sn": "...", "device_model": "...", "device_model": "..."}
get_auto_disaster_prepare_detail
Function: getAutoDisasterPrepareDetail
{"station_id": "...", "unix": "...", "near_field": "..."}
get_auto_disaster_prepare_status
Function: getAutoDisasterPrepareStatus
{"station_id": "..."}
get_charging_device_identity_new_status
Function: getA2687StandardChargingDeviceModelIdentityStatus
{"device_sn": "...", "charging_device_identity_new_status": "..."}
get_charging_device_identity_status_default_true
Function: getA2345DeviceIdentityStatus
{"device_sn": "...", "status": "..."}
get_charging_mode_list
Function: getCustomChargeModeList
{"device_sn": "..."}
get_clock_screensavers
Function: getScreenSaversByCategory
{"product_code": "..."}
get_comb_addable_sites
Function: getDeviceJoinSiteList
{"devices": "..."}
get_compatible_process
Function: checkSolarForceUpdateState
{"solar_sn": "...", "solarbank_sn": "..."}
get_configs
Function: getSiteConfigs
{"station_id": "...", "param_types": "..."}
get_confirm_permissions
Function: getConfirmPermissionsApi
{"device_model": "..."}
get_day_power_data
Function: getDayPowerData
{"device_model": "...", "device_sn": "...", "date": "..."}
get_device_attrs
Function: getDeviceAttrs
{"device_sn": "...", "attributes": "...", "enable_0w_v2": "..."}
get_device_command
Function: getDeviceCommand
{"station_id": "...", "accuracy": "..."}
get_device_home_load
Function: getDeviceHomeLoadPort
{"device_sn": "..."}
get_device_income
Function: getTOUChartStatistics
{"device_sn": "...", "type": "...", "start_time": "..."}
get_device_infos
Function: getDeviceInfos
{"sns": "..."}
get_device_setting
Function: getCustomChargeModeSetting
{"device_sn": "...", "charging_mode_status": "...", "compatibility_status": "...", "charging_device_identity_status": "..."}
get_easter_egg_trigger_list
Function: getEasterEggRecord — hidden gamification feature on charger devices (details omitted)
{"device_sn": "..."}
get_error_infos
Function: getErrorInfos
{"sn_errors": "..."}
get_heat_pump_plan_json
Function: getHeatPumpTimePlan
{"heat_pump_plan": "..."}
get_installation
Function: getInstallationApi
{"solarbank_sn": "...", "site_id": "..."}
get_installation_inspection
Function: getInstallation
{"sn": "..."}
get_invited_list
Function: getInviteMember
{"site_id": "...", "status": "..."}
get_list
Function: getCurrencyGetList
{"counrty": "..."}
get_manual_clock_screensavers
Function: getA2345CustomClockScreenSavers
{"sn": "..."}
get_mes_device_info
Function: getDeviceLaserSn
{"device_sn": "..."}
get_message
Function: getMessage
{"last_time": "...", "device_sns": "...", "limit": "...", "message_type": "...", "last_msg_id": "..."}
get_ota_info
Function: getThirdOtaInfo
{"solar_bank_sn": "...", "solar_sn": "..."}
get_ota_update
Function: getThirdOtaStatus
{"device_sn": "...", "insert_sn": "..."}
get_popup
Function: queryA17Y0Popup
{"site_id": "..."}
get_port_remarks
Function: getPortRemarks
{"device_sn": "..."}
get_power_limit
Function: getSitePowerLimit
{"site_id": "..."}
get_power_range_support_protocols
Function: getPowerSupportProtocols
{"device_model": "..."}
get_protocol_status
Function: getA2687ProtocolAgreementStatus
{"device_sn": "..."}
get_relate_belong
Function: getDeviceBindInfo
{"device_sn": "..."}
get_relate_device_fittings
Function: getRelateAccessory
{"device_sn": "..."}
get_rom_versions
Function: checkFirmwareWifi
{"main_sn": "...", "device_rom_versions": "..."}
get_scen_info
Function: querySceneInfo
{"site_id": "..."}
get_schedule
Function: getSiteSchedule
{"site_id": "..."}
get_site_detail
Function: getStationDetail
{"site_id": "..."}
get_site_device_param
Function: getSafetySocParams
{"site_id": "...", "param_type": "..."}
get_site_price
Function: getSitePriceRequest
{"site_id": "...", "accuracy": "..."}
get_station_config_and_status
Function: getA5101StationConfigDetail
{"station_id": "..."}
get_status
Function: getAiModeStatusRequest
{"site_id": "..."}
New Findings: Additional Parameters from Blutter
These parameters were found in the decompiled Dart code but are not documented in
thomluther's apitypes.py. Each entry shows what is currently known vs what Blutter adds.
get_device_attributes
power_service/v1/app/device/get_device_attrs
Currently documented: {"device_sn": "...", "attributes": ["rssi", "pv_power_limit", "legal_power_limit", "power_limit_option", "power_limit_option_real", "switch_0w"]}
Blutter reveals an additional parameter:
{"device_sn": "...", "attributes": [...], "enable_0w_v2": true}
Function: getDeviceAttrs — the enable_0w_v2 flag likely enables the v2 version of the 0W output feature.
get_device_income
power_service/v1/app/device/get_device_income
Currently documented: {"device_sn": "...", "start_time": "..."}
Blutter reveals additional parameters:
{"device_sn": "...", "start_time": "...", "type": "..."}
Function: getTOUChartStatistics — the type parameter likely selects the chart data type (daily/weekly/monthly).
charger_get_device_setting
mini_power/v1/app/setting/get_device_setting
Currently documented: {"device_sn": "..."}
Blutter reveals the expected response contains:
{"charging_mode_status": "...", "compatibility_status": "...", "charging_device_identity_status": "..."}
Function: getCustomChargeModeSetting — these fields indicate available charger modes and compatibility state.
set_device_attributes — Upstream-confirmed nesting pattern
The set_device_attrs endpoint (power_service/v1/app/device/set_device_attrs) is used by 9 different functions in the app. Upstream's community-tested code confirms that all additional fields go inside the attributes dict:
Set power options
{"device_sn": "...", "attributes": {"power_limit": 800, "ac_power_limit": 1200, "pv_power_limit": 3600}}
Function: setDevicePowerOptionsReq
Set TOU electricity attributes
{"device_sn": "...", "attributes": {"pps_use_time": "..."}}
Function: setTouElectricAttrs
Set currency
{"device_sn": "...", "attributes": {"currency": "EUR"}}
Function: getCurrencySetDeviceAttrs
Set solar panel names
{"device_sn": "...", "device_pn": "...", "attributes": {"pv1_name": "...", "pv2_name": "..."}}
Function: setSolarName / setPpsSolarName
Set 0W feed-in grid switch
{"device_sn": "...", "attributes": {"switch_0w": 0}}
Function: setDeviceFeedGridSwitch — 0=allow grid export, 1=block
Set PV power limit
{"device_sn": "...", "attributes": {"pv_power_limit": 800}}
Function: setDevicePvPowerOptionsReq
Set location tag
{"device_sn": "...", "attributes": {"tag": "outdoor"}}
Function: setLocationTag
Set game/demo status
{"device_sn": "...", "attributes": {"init_status": "1"}}
Function: setDeviceGameStatus
get_configs (charging_energy_service)
Blutter reveals the station_id parameter name (thomluther documents it as siteId):
{"station_id": "...", "param_types": [...]}
Function: getSiteConfigs — note: station_id vs siteId may be interchangeable.
Constants and Enum Values (from APK)
Peak/Valley Price Types
{"peak": 1, "normal": 2, "valley": 3, "super_valley": 4}
Usage Mode Types
self_consumption, manual_backup, peak_shaving, custom_mode,
time_of_use, use_time, smart, dynamic, fixed
Day Types
weekday, weekend, everyday
Schedule/Rate Plan Names
ai_ems, blend_plan, custom_rate_plan, manual_backup,
peak_sessions, peak_valley_prices, use_time
Device Type Categories
solar_bank, solarbank, pps, hes, micro_inverter, ev_charger, generator
All Known Product Codes (53 models)
A1340, A1341, A1722, A1723, A1725, A1726, A1727, A1728, A1729,
A1753, A1754, A1755, A1761, A1762, A1763, A1765,
A1770, A1771, A1772, A1780, A1780P, A1781, A1782, A1783, A1785,
A1790, A1790A, A1790B, A1790P, A1903,
A2345, A2687, A2693, A2693E1, A2693E2,
A5101, A5102, A5103, A5140, A5141, A5143, A5150, A5190, A5191, A5220, A5341, A5450,
A7320, AE100, AE1R0, AX170, AX1C0, AX1S0
EV Charger Schedule Defaults (A5190)
{
"weekdayStartTime": "08:00",
"weekdayEndTime": "22:00",
"weekendStartTime": "08:00",
"weekendEndTime": "22:00",
"everyDaySwitch": false,
"isSwitchOn": false,
"chargingMode": "...",
"regularCharge": "...",
"smartChargeList": []
}
Range Extender Strategy (A7320)
{
"strategySwitchOn": true,
"strategyType": "bysoc|bytime",
"bysocData": {"startSoc": 20, "targetSoc": 80},
"bytimeData": {"startTime": "08:00", "targetSoc": 80},
"unableExcuteStrategyReason": "...",
"lastTaskResult": "...",
"lastTaskExecusionTime": "...",
"lastTaskFailReason": "..."
}
EV Charger Control (A5190 prop_write_evcharger)
{
"rechargingPowerOutage": false,
"plugAndChargeSwitch": false,
"carChargerLockStatus": 0,
"maximumCurrentLimit": 16,
"delayStartSwitch": false,
"lightBrightness": 100,
"ledSwitch": true,
"ledCloseStartTime": "22:00",
"ledCloseEndTime": "06:00"
}
Device Bind Request
/app/devicerelation/relate_device
{
"device_sn": "...",
"product_code": "A17C0",
"device_name": "Solarbank E1600",
"bt_ble_id": "...",
"bt_ble_mac": "...",
"firmware_version": "...",
"wifi_name": "...",
"parent_device_sn": "...",
"parent_device_pn": "..."
}
Dynamic Price Response Fields
/power_service/v1/dynamic_price/price_detail
{
"release_time": "...",
"today_avg_price": 0.15,
"tomorrow_avg_price": 0.12,
"today_price_trend": "...",
"tomorrow_price_trend": "...",
"batteryReserve": 10,
"value": [...]
}
akiot.cloud_api Bridge Format
The native AKIoT SDK uses this format to proxy cloud API calls through BLE/MQTT:
{
"method": "POST",
"path": "/power_service/v1/site/get_site_device_param",
"param": {"site_id": "...", "param_type": "18"}
}
Transport: akiot.cloud_api via akiot.device.invoke_action
SceneInfo Key Feature Flags
From get_scen_info response — these boolean/status fields control UI behavior:
{
"manual_backup_mode": false,
"exceed_power": "0",
"peak_valley_mode": false,
"heating": false,
"shelly_meter": false,
"support_p1_meter": false,
"enable_parallel": false,
"plug_switch_report": false,
"show_third_party_pv_panel": false,
"meter_self_testing": false,
"power_limit_status": 0,
"power_saving_mode": false,
"third_party_pv_enable": false,
"enable_aiems_v2": false,
"grid_to_ev": false
}