USB-PD 3.1 provides both a Get_Battery_Cap message, which asks the sink to tell the source the capacity of its battery) and a Get_Battery_Status message, which asks the sink to inform the source about the current charge of its battery.
Here's an example capture of an exchange between my MacBook Pro and iPad: https://imgur.com/a/8rZlN9X
The iPad responds to Get_Battery_Cap with Battery_Capabilities, which reports the total capacity in Wh:
USB Vendor ID: 0x05AC Product ID: 0x0000 Design capacity: 280 Last full-charge capacity: 280 Battery reference: valid
And then when the MBP asks for battery status, the iPad returns a Battery_Status message:
Battery is present. Present capacity: 14.2Wh Charging state: charging.
Later on, as the charging continues, the iPad will issue an Alert message:
Reported alerts: Battery status changed. Affected batteries: Fixed battery slots: 1
And then the MBP will send a Get_Battery_Status again, and so on. (Example capture here: https://imgur.com/a/TI5maV0
What's really cool is that this exchange happens both ways—the iPad also sends a Get_Battery_Cap message to the MBP, because it is also capable of acting as a source, and, if the laptop's battery drops sufficiently low, the source/sink roles may swap (using a DR_Swap message) so that the iPad ends up charging the MBP!