Automate Daily Backups and Cleanup in Home Assistant Using Supervisor API

Hello,

I searched the internet and this forum for a solution but couldn’t find anything that met my needs, so I decided to script it myself and share it here. So, others can use it :smiley:
You would expect a simpler solution is possible, but i didn’t find it.

I wanted to create an automation that makes a backup every day (to a remote filesystem) and deletes backups older than a specified number of days. I’d like to share this so it’s usable for anyone. As far as I know, deleting backups is only possible by utilizing the Supervisor API. So, this solution only works with these installations: Home Assistant OS and Home Assistant Supervised.

“Note: The Supervisor API (internal URL) is always http://supervisor and is by default not accessible outside the Home Assistant installation.”

To make this process easier, use these add-ons: Stude Code Server and the Terminal. Supervisor API Documentation.

Prerequisites:

In configuration.yaml , you have to activate the Supervisor API by adding:

api:

and here’s how to define the shell_command:

shell_command:
  manage_backups_api: '/config/scripts/manage_backups_api.sh'

Create the following folders in the config directories:

  • backups
  • scripts

Put the shell script in the scripts folder with the name: manage_backups_api.sh

Restart homeassistant

Remote file share

Be a smart guy and store your backup remotely by using a smb or nfs share.
settings → config → storage ‘add network storage’
settings → backup → (right top) change default backup location
Example to save them on a remote NAS

Automation Configuration

Add the following automation to your Home Assistant configuration:

alias: Manage Backups Using API
description: Create backup, Lists and cleans up old backups daily using the Supervisor API
trigger:
  - platform: time
    at: "04:00:00"
condition: []
action:
  - service: hassio.backup_full
    metadata: {}
    data:
      compressed: true
  - service: shell_command.manage_backups_api
    data: {}
mode: single

Shell Script: manage_backups_api.sh

Save the following script in scripts/manage_backups_api.sh :

#!/bin/bash

# Define a variable to control logging
LOGGING_ENABLED=true

# Define a variable to control the number of backups to keep
BACKUPS_TO_KEEP=7

# Log function to append messages to the log file
log_message() {
    if $LOGGING_ENABLED; then
        echo "$(date): $1" >> /config/backups/backup_script_api.log
    fi
}

# Log start time
log_message "Starting backup management"

# Define the Home Assistant URL and token
HASS_URL="http://supervisor"
HASS_TOKEN="$SUPERVISOR_TOKEN"
HEADERS=(
    "-H" "Authorization: Bearer $HASS_TOKEN"
    "-H" "Content-Type: application/json"
)

# Log the token being used (for debugging, you might want to remove this in production)
log_message "Using token: $HASS_TOKEN"

# List backups and save to a JSON file
response=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "${HEADERS[@]}" "$HASS_URL/backups")

# Extract the body and the HTTP status
http_body=$(echo "$response" | grep -v "HTTP_STATUS")
http_status=$(echo "$response" | grep "HTTP_STATUS" | cut -d':' -f2)

# Log the full response (for debugging)
log_message "API HTTP Status: $http_status"
log_message "API Response Body: $http_body"

# Check if the response contains "401 Unauthorized"
if [ "$http_status" -eq 401 ]; then
    log_message "Authorization failed: 401 Unauthorized"
    exit 1
fi

# Save the response to backups_api.json
echo "$http_body" > /config/backups/backups_api.json

# Check if backups.json was created and is not empty
if [ -s /config/backups/backups_api.json ]; then
    # Log successful backup list
    log_message "Backups listed successfully"

    # Parse backup slugs to delete old backups, keeping only the newest BACKUPS_TO_KEEP
    BACKUPS=$(jq -r --argjson num "$BACKUPS_TO_KEEP" '.data.backups | sort_by(.date) | .[:-$num] | .[].slug' /config/backups/backups_api.json)

    for SLUG in $BACKUPS; do
        delete_response=$(curl -s -w "\nHTTP_STATUS:%{http_code}" -X DELETE "${HEADERS[@]}" "${HASS_URL}/backups/${SLUG}")
        delete_status=$(echo "$delete_response" | grep "HTTP_STATUS" | cut -d':' -f2)

        if [ "$delete_status" -eq 200 ]; then
            log_message "Deleted backup: $SLUG"
        else
            log_message "Failed to delete backup: $SLUG"
            log_message "Delete Response: $delete_response"
        fi
    done
else
    # Log error if backups.json is empty
    log_message "Failed to list backups or backups.json is empty"
fi

# Log end time
log_message "Backup management completed"

Summary

This script will create a daily backup at 4 AM and then manage old backups by deleting any beyond the most recent seven. Make sure to configure your Home Assistant and Supervisor API as described to ensure everything works smoothly.

Enjoy a more automated and tidy backup process!

3 Likes

There are seven alternatives under option 5 here: https://www.home-assistant.io/common-tasks/os#copying-your-backups-to-another-location

Hello,

Thank you for your response. I have seen these options, but they didn’t fit my needs. The main problem I want to solve is the automatic deletion of backups. That’s why I built the script and posted it here so others can use it. As far as I could find, there isn’t a built-in solution for that.

The most used options, like the Samba backup addon and the Google drive addon, have extensive settings on how many backups to keep. I see no reason why that would not fit your needs and more.

Thanks for pointing that out, now i noticed the option in de YAML example, totaly looked over it… :upside_down_face: