FlipFlip Energy API

Battery Modes

When Flip dispatches a command to a device, the battery_commands.mode field tells the device what operating mode to enter. This page describes each mode's intent, what the device should do, and how modes map to common inverter work modes.

Command payload recap

Every command webhook includes a battery_commands object:

{
  "mode": "DISCHARGE",
  "power_mode": "SETPOINT",
  "setpoint_w": 5000,
  "backup_reserve_percentage": 10,
  "enable_grid_import": false
}
FieldTypeDescription
modestringRequired. One of CHARGE, DISCHARGE, STANDBY, BACKUP, SELF_CONSUMPTION, SAVINGS.
power_modestring | nullSETPOINT or FOLLOW_LOAD. Present only for CHARGE and DISCHARGE.
setpoint_winteger | nullTarget power in watts (always positive). Only used when power_mode is SETPOINT.
backup_reserve_percentageintegerMinimum state of charge (0-100) the battery should retain.
enable_grid_importboolean | nullWhether the device may charge from the grid.

Mode Reference

DISCHARGE

Intent: Export energy from the battery to serve the home load and/or the grid.

What the device should do:

  • Discharge the battery at the specified power level.
  • If power_mode is SETPOINT, discharge at exactly setpoint_w watts. If FOLLOW_LOAD, discharge only enough to cover the home load (no grid export). Supporting FOLLOW_LOAD is optional.
  • Stop discharging when SOC reaches backup_reserve_percentage.
  • Solar production should continue to serve the home and charge the battery as normal alongside the discharge.

Common inverter mapping: This typically maps to a "Forced Discharge" or "Feed-In Priority" work mode. Inverters that use scheduled time slots should write the command's start/end window into a forced-discharge slot with the appropriate power cutoff. Inverters that accept a direct dispatch command should set the discharge action with the target power. The setpoint_w value is in watts -- convert to the inverter's native unit (amps, percentage of max power, kW) as needed.

When it's used: Demand response events where the utility needs the battery to inject power into the grid (peak shaving, grid support). This is the most common event mode.

Typical command example:

{
  "mode": "DISCHARGE",
  "power_mode": "SETPOINT",
  "setpoint_w": 5000,
  "backup_reserve_percentage": 20,
  "enable_grid_import": false
}

CHARGE

Intent: Charge the battery, typically from the grid and/or solar, to build up stored energy before a discharge event.

What the device should do:

  • Charge the battery at the specified power level.
  • If power_mode is SETPOINT, charge at exactly setpoint_w watts. If FOLLOW_LOAD, charge from excess solar only.
  • If enable_grid_import is true, the battery may draw from the grid to charge. If false, charge only from solar PV.

Common inverter mapping: This typically maps to a "Forced Charge" work mode. Inverters that use scheduled time slots should write the command window into a forced-charge slot. Inverters that accept a direct dispatch should set the charge action with the target power. If enable_grid_import is true, ensure grid charging is enabled on the inverter. Convert setpoint_w (watts) to the inverter's native unit as needed.

When it's used: Preparatory commands before a discharge event (pre-charging), or time-of-use optimization where charging during off-peak hours is beneficial. CHARGE commands often appear as the first segment in a multi-step event schedule with is_preparatory_action: true.

Typical command example:

{
  "mode": "CHARGE",
  "power_mode": "SETPOINT",
  "setpoint_w": 3000,
  "backup_reserve_percentage": 0,
  "enable_grid_import": true
}

STANDBY

Intent: Prevent the battery from charging or discharging. Hold current state.

What the device should do:

  • Do not charge or discharge the battery.
  • Solar PV should continue to serve the home load and export to the grid as normal, but should not charge the battery.
  • Maintain current SOC.

Common inverter mapping: If the inverter has a native "Standby" or "Idle" mode, use it directly. Otherwise, this can be achieved by enabling a self-use / time-of-use mode with empty charge and discharge schedules, or by setting charge and discharge power limits to zero.

When it's used: Monitoring periods where the utility wants to observe site behavior without battery activity, or transitional holds between event segments.

Typical command example:

{
  "mode": "STANDBY",
  "backup_reserve_percentage": 20,
  "enable_grid_import": false
}

BACKUP

Intent: Maximize the battery's readiness for a potential grid outage. Prioritize charging and retaining energy.

What the device should do:

  • Charge the battery to 100% SOC.
  • Do not discharge the battery for any reason other than grid outage / backup power.
  • If enable_grid_import is true, charge from the grid. Otherwise charge from solar PV only.
  • If a grid outage occurs, the battery should power the home (standard backup behavior).

Common inverter mapping: This typically maps to a "Full Backup", "Battery First", or "Emergency" work mode. The inverter should prioritize charging to 100% and avoid discharging unless there is a grid outage. If no native backup mode exists, use a forced-charge mode with reserve set to 100%.

When it's used: Storm mode, severe weather alerts, or any situation where grid reliability is uncertain and the battery should be fully charged and ready.

Typical command example:

{
  "mode": "BACKUP",
  "backup_reserve_percentage": 100,
  "enable_grid_import": true
}

SELF_CONSUMPTION

Intent: Use battery and solar to minimize grid imports. The battery serves the home load but does not export to the grid.

What the device should do:

  • Solar PV charges the battery and serves the home load.
  • Battery discharges only to serve the home load (no grid export).
  • Maintain SOC above backup_reserve_percentage.
  • Grid import is used only when solar + battery cannot cover the home load.

Common inverter mapping: This maps directly to the "Self-Consumption", "Self-Use", "Self-Power", or "Load First" work mode found on most inverters. This is typically the inverter's default operating mode.

When it's used: Default/idle operating mode for many VPP programs. Also used as the restore-to mode after an event ends.

Typical command example:

{
  "mode": "SELF_CONSUMPTION",
  "backup_reserve_percentage": 20,
  "enable_grid_import": false
}

SAVINGS (optional)

Intent: Optimize battery usage for time-of-use rate arbitrage. Charge during cheap periods, discharge during expensive periods.

What the device should do:

  • Follow a time-of-use schedule to minimize the homeowner's electricity bill.
  • Charge the battery during off-peak / low-rate periods.
  • Discharge during on-peak / high-rate periods to offset grid imports.
  • Specific TOU schedules are typically configured per-site via the tariff rather than in the command payload.

Common inverter mapping: This would map to an "Economical", "TOU", or "Savings" work mode if available. The inverter follows a tariff-based schedule to optimize battery usage for cost savings.

When it's used: Programs focused on bill optimization rather than grid services. Supporting this mode is optional and not a common requirement for VPP programs. Most OEM integrations do not implement it today.

Typical command example:

{
  "mode": "SAVINGS",
  "backup_reserve_percentage": 20,
  "enable_grid_import": true
}

power_mode Detail

The power_mode field (present only for CHARGE and DISCHARGE) controls how aggressively the battery acts:

SETPOINT

The battery should charge or discharge at exactly setpoint_w watts, regardless of home load or solar production. This is the mode used for grid services where a specific power contribution is required.

  • Excess discharge beyond home load is exported to the grid.
  • Excess charge beyond solar production is drawn from the grid (if enable_grid_import is true).

FOLLOW_LOAD

The battery should charge or discharge only enough to match the home load. No grid export from the battery.

  • During DISCHARGE + FOLLOW_LOAD: battery covers home load to minimize grid import, but does not export.
  • During CHARGE + FOLLOW_LOAD: battery absorbs only excess solar production (no grid draw).

Command Lifecycle

Commands follow a webhook lifecycle that determines when to apply and remove settings:

WebhookAction
command.createdCommand is scheduled. Optionally pre-configure if your system supports future scheduling.
command.startedApply the battery mode now. Save the device's current settings so they can be restored later.
command.endedRestore the device to its previous settings. The event window is over.
command.canceledRevert any applied settings. The command was canceled before or during execution.
command.updatedThe command parameters or status changed. Re-read and re-apply if already active.

Settings backup and restore

Most inverters have a homeowner-configured default mode (usually Self-Consumption with a reserve). When a command starts, your integration should:

  1. Read the device's current inverter settings.
  2. Save them (database, cache, etc.).
  3. Apply the new settings from the Flip command.
  4. On command end, restore the saved settings.

This ensures the homeowner's preferred configuration is preserved across events.

Acknowledging commands

After applying (or failing to apply) a command, update its device_status via PATCH /v1/command/{commandId}:

StatusMeaning
OKCommand was successfully applied to the device.
FAILED_OFFLINEDevice is unreachable. Flip will retry.
FAILED_FAULTDevice has an active fault. Flip will not retry.
FAILED_PENDING_ACTIVATIONDevice is still being onboarded. Flip will retry.

Implementation Checklist

When implementing command handling for a new OEM integration:

  • Map each BatteryMode to the inverter's native operating mode
  • Handle power_mode (SETPOINT vs FOLLOW_LOAD) for CHARGE and DISCHARGE
  • Convert setpoint_w (watts) to the inverter's native unit (amps, percentage, kW)
  • Respect backup_reserve_percentage as a SOC floor (clamp to hardware limits if needed)
  • Respect enable_grid_import for CHARGE and BACKUP modes
  • Save and restore inverter settings around command start/end
  • Acknowledge each command via PATCH /v1/command/{commandId} with appropriate device_status
  • Handle command.canceled and command.updated webhooks
  • Throw a clear error for unsupported modes (e.g., SAVINGS) rather than silently ignoring
  • Use device-local DST-aware time when the inverter uses wall-clock scheduling