Skip to content

Repository files navigation

Amber Electric API Wrapper

A Python client for interacting with the Amber Electric API, providing REST endpoints for GraphQL queries and scheduled tasks.

Important: Use Responsibly

This wrapper provides programmatic access to your Amber Electric account. Please use it responsibly:

  • Don't overload Amber's servers - The wrapper includes caching and retry logic to minimize requests, but avoid creating excessive scheduled tasks that poll the API frequently
  • Respect the API - This is shared infrastructure; aggressive usage could impact performance for other users
  • Use appropriate intervals - For scheduling, prefer longer intervals (e.g., hourly) unless you specifically need frequent updates
  • Monitor your usage - Check the logs periodically to ensure your scheduled tasks are behaving as expected

While this project doesn't intentionally hit Amber's backend too hard, excessive or abusive usage patterns could lead to rate limiting or account restrictions from Amber's side.

Limitations

This project provides basic scheduling functionality only. If you need advanced automation logic (e.g., dynamic scheduling based on weather forecasts, complex battery management strategies, or multi-site coordination), you should build your own automation logic elsewhere (e.g., in Home Assistant, Python scripts, or a CI/CD pipeline) and use this project's REST API to execute the actions.

Additionally, the author only has one site and one inverter. The APIs have not been tested with multiple sites or multiple inverters, so behavior in those scenarios is unknown.

Features

  • Authentication: AWS Cognito-based JWT token authentication with automatic refresh
  • GraphQL Client: Support for the Amber GraphQL calls used by this wrapper
  • REST API: FastAPI-based HTTP endpoints
  • Scheduled Tasks: Cron-style task scheduling (e.g., "add override at 6pm daily")
  • Auto-retry: Adaptive retry logic for pricing queries
  • Caching: Built-in caching for site IDs and pricing data

Security

Auth Token Authentication Required

All API endpoints (except /api/amber/health) require a valid auth token in the X-Auth-Token header.

What is the Auth Token?

The auth token is a secret string you generate that acts as a password for this wrapper's REST API. It is completely separate from your Amber Electric account credentials.

Where it's configured:

  • AUTH_TOKEN - Admin access (full control)
  • READ_ONLY_AUTH_TOKEN - Read-only access (view only)

Where it's used:

  • Sent as X-Auth-Token header with every protected API request
  • Must be at least 32 characters long

What it protects:

  • Battery control (override creation/cancellation)
  • SmartShift optimization settings
  • Price data and system metrics

Important Security Warning

Do NOT expose this service directly to the internet - The REST API has no built-in rate limiting, IP whitelisting, or HTTPS. Exposing it without protection could allow someone to control your battery system.

Always use TLS/HTTPS outside a trusted local network - Run this service behind a reverse proxy (Caddy, Nginx, Traefik) with TLS when exposing it beyond your own trusted LAN. The auth token only proves the caller knows the secret; it does not encrypt the connection. Over plain HTTP, anyone who can observe the traffic can intercept the token and reuse it.

Important: This is NOT the Amber API Key

The auth token required by this wrapper is separate from your Amber Electric account credentials. It's a local security mechanism to protect access to this wrapper's REST API.

  • Amber credentials (AMBER_USERNAME / AMBER_PASSWORD): Used to authenticate with Amber Electric's servers
  • Auth token (AUTH_TOKEN / READ_ONLY_AUTH_TOKEN): Used to authenticate with this wrapper's REST API

The REST service authenticates to Amber on startup using AMBER_USERNAME and AMBER_PASSWORD, then automatically refreshes its Amber token when needed. REST callers should not need to call /api/amber/authenticate during normal operation.

Generating an Auth Token

Generate a secure auth token using Docker:

docker run --rm ghcr.io/d1scolor/amber-api-wrapper:latest python -m amber_api_wrapper generate-key

This outputs:

Generated Auth Token: xK9mP2qR7vL5nM8wQ3eY6tU1zA4sD0fG
Add this to your .env file as AUTH_TOKEN
Minimum length: 32 characters

Security Note: This is NOT your Amber API key.
   It's a local security mechanism to protect this wrapper's REST API.

Setting the Auth Token

Add the generated token to your .env file:

AUTH_TOKEN=xK9mP2qR7vL5nM8wQ3eY6tU1zA4sD0fG

Optionally, you can set a separate read-only token for dashboards:

READ_ONLY_AUTH_TOKEN=your-read-only-token-here

Read-only tokens can only access the read endpoints, such as price, site, battery state, and SmartShift settings reads. Battery control, manual re-authentication, SmartShift optimization changes, and raw GraphQL require the admin AUTH_TOKEN.

Auth Token Requirements

  • Minimum length: 32 characters
  • Format: Any string at least 32 characters long
  • Header: X-Auth-Token: <your-token>

Important Security Recommendations

  1. Do NOT expose this service directly to the internet - The REST API has no built-in rate limiting, IP whitelisting, or HTTPS. Exposing it could allow someone to control your battery system.
  2. Use TLS/HTTPS outside a trusted local network - Always run behind a reverse proxy (Caddy, Nginx, Traefik) with TLS when exposing to external networks. The auth token alone does not protect plain HTTP traffic; without TLS, the token can be intercepted and reused.
  3. Never commit .env files to version control
  4. Use different tokens for different environments (dev, staging, prod)
  5. Keep the auth token secret - Anyone with your token can control your battery

Security Architecture

Auth Token Authentication

All API endpoints (except /api/amber/health) require a valid auth token in the X-Auth-Token header. The token must be at least 32 characters long.

Where the Auth Token is Used:

  • AUTH_TOKEN environment variable (admin access)
  • READ_ONLY_AUTH_TOKEN environment variable (read-only access)
  • X-Auth-Token HTTP header (sent with each protected request)

What the Auth Token Protects:

  • Battery override creation/cancellation
  • SmartShift optimization settings
  • Price data and metrics
  • All REST API endpoints except /api/amber/health

What the Auth Token is NOT:

  • Not your Amber Electric account password
  • Not related to your Amber API credentials
  • Not a JWT or bearer token from Amber

Example: Secure Docker Deployment with Caddy

services:
  amber-api:
    build: .
    container_name: amber-api-wrapper
    restart: unless-stopped
    # Only bind to localhost - not exposed to network
    ports:
      - "127.0.0.1:8000:8000"
    env_file:
      - .env

  caddy:
    image: caddy:2
    ports:
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - amber-data:/data
    depends_on:
      - amber-api

volumes:
  amber-data:
amber.example.com {
    reverse_proxy amber-api:8000
}

Installation

Using uv (recommended)

uv sync

Using pip

pip install -e .

Usage

Python Client

import asyncio
from amber_api_wrapper import AmberClient

async def main():
    # Reads AMBER_USERNAME and AMBER_PASSWORD from the environment and
    # automatically refreshes the Amber token when needed.
    client = AmberClient()

    # Get current prices
    pricing = await client.get_current_prices()
    general_5min = pricing.get_general_window_5min()
    if general_5min:
        print(f"Current import price: {general_5min.current_price}c/kWh")
    
    # Get battery overrides
    overrides = await client.get_battery_overrides()
    print(f"Active override: {overrides.active_action}")
    
    # Get live metrics (four separate endpoints for better granularity)
    site_power = await client.get_site_power()
    solar_power = await client.get_solar_power()
    battery_power = await client.get_battery_power()
    battery_soc = await client.get_state_of_charge()
    print(f"Battery: {battery_soc}%")
    print(f"Site power: {site_power}W")
    print(f"Solar power: {solar_power}W")
    print(f"Battery power: {battery_power}W")

asyncio.run(main())

REST API

Start the FastAPI server:

uvicorn api.main:app --reload

Set AMBER_USERNAME, AMBER_PASSWORD, and AUTH_TOKEN first, either in your environment or in .env.

API endpoints:

Method Endpoint Description
GET /api/amber/health Health check
POST /api/amber/authenticate Manually re-authenticate with Amber API (admin token only)
GET /api/amber/site-ids Get site/config IDs
GET /api/amber/smartshift-settings Get SmartShift settings
GET /api/amber/current-prices Get current prices
GET /api/amber/price-forecasts Get current prices and available five-minute/SmartShift forecasts
GET /api/amber/battery-overrides Get battery overrides
GET /api/amber/site-power Get site power in watts
GET /api/amber/solar-power Get solar power in watts
GET /api/amber/battery-power Get battery power in watts
GET /api/amber/battery-soc Get battery state of charge %
POST /api/amber/battery-override/add Add battery override
POST /api/amber/battery-override/cancel Cancel override
POST /api/amber/smartshift-optimization Toggle optimization

The service authenticates to Amber automatically on startup and refreshes the Amber token on demand. The /api/amber/authenticate endpoint is for manual admin re-authentication only. The raw GraphQL endpoint is disabled by default; to expose it, set ENABLE_RAW_QUERY=true; it still requires the admin AUTH_TOKEN.

The import_5min and export_5min objects returned by /api/amber/price-forecasts contain the active period in their existing fields and an ordered forecast_periods array for Amber's available future five-minute periods. The first array item is the next period; the active period is not repeated in the array. Amber may return fewer periods when its short-horizon forecast is incomplete.

Raw GraphQL Query

The raw GraphQL endpoint is intended for debugging and exploratory use. It is disabled unless ENABLE_RAW_QUERY=true is set before startup, and it never accepts READ_ONLY_AUTH_TOKEN.

When enabled, call it with the admin token and pass the GraphQL query as the query parameter. Optional GraphQL variables can be supplied as a JSON object in the variables parameter.

curl -X POST -H "X-Auth-Token: your-admin-auth-token" \
  --data-urlencode 'query=query { smartshiftBatteryStrategyConfig { siteId configId } }' \
  http://localhost:8000/api/amber/raw-query

This endpoint forwards your query to Amber using the service's Amber session, so only enable it when you understand the query being sent.

Example API Requests

# Get current prices
curl -H "X-Auth-Token: your-auth-token" http://localhost:8000/api/amber/current-prices

# Get battery state of charge
curl -H "X-Auth-Token: your-auth-token" http://localhost:8000/api/amber/battery-soc

# Add a battery override
curl -X POST -H "X-Auth-Token: your-auth-token" \
  -H "Content-Type: application/json" \
  -d '{"action": "discharge", "duration_minutes": 120}' \
  http://localhost:8000/api/amber/battery-override/add

Scheduled Tasks

Configure tasks in .env using cron syntax. All environment variables starting with SCHEDULE_ are loaded - you can create as many as you need.

Schedules are evaluated in the configured local timezone. In Docker, set TZ=Australia/Sydney in .env if you want schedules such as 0 18 * * * to run at 6:00 PM Sydney time. The scheduler detects TZ, /etc/localtime, or /etc/timezone; if timezone detection fails, it falls back to Australia/Sydney.

For example, at 2026-04-13T08:00:00+10:00 in Sydney, a schedule of 2 8 * * * should log the next run as 2026-04-13T08:02:00+10:00. If it logs +00:00, the container is using UTC and the task will run at the UTC time instead.

Australian timezone examples:

Timezone Typical use
Australia/Sydney NSW, ACT
Australia/Melbourne Victoria
Australia/Brisbane Queensland
Australia/Adelaide South Australia
Australia/Perth Western Australia
Australia/Hobart Tasmania
Australia/Darwin Northern Territory
Australia/Broken_Hill Broken Hill / Yancowinna
Australia/Eucla Eucla
Australia/Lord_Howe Lord Howe Island
Australia/Lindeman Lindeman Island
Australia/Currie King Island

Need help generating cron expressions? Use crontab.guru - this project uses the standard 5-field cron format which is fully compatible.

# Add sell override at 6 PM daily for 2 hours
SCHEDULE_SELL=0 18 * * *|add_override|action=discharge,duration_hours=2

# Add charge override at 11 PM daily for 2 hours (preserve charge)
SCHEDULE_CHARGE=0 23 * * *|add_override|action=preserve-charge,duration_hours=2

# Disable SmartShift optimization at 7 AM daily
SCHEDULE_OPTIMIZE=0 7 * * *|toggle_optimization|enabled=false

Cron Syntax Reference

Field Allowed Values Example
Minute 0-59 0, */5, 30
Hour 0-23 0, 18, *
Day of month 1-31 1, *
Month 1-12 1, *
Day of week 0-6 (0=Sun) 1-5, *

Common Schedules

Cron Expression Description
0 * * * * Every hour at minute 0
0 18 * * * Every day at 6:00 PM
*/5 * * * * Every 5 minutes
0 9 * * 1-5 Weekdays at 9:00 AM
0 0 * * * Every day at midnight
0 0 1 * * First of every month

Action Arguments

Action Arguments Notes
add_override action=charge|discharge|preserve-charge|self-consume, duration_hours=0.5|1|1.5|2 Duration must be 0.5, 1, 1.5, or 2 hours
cancel_override override_id=override_id|all Use all to cancel all active overrides
toggle_optimization enabled=true|false Enable or disable SmartShift optimization

Valid Duration Hours

The Amber API only accepts specific durations for battery overrides:

  • 0.5 hours (30 minutes)
  • 1 hour
  • 1.5 hours (90 minutes)
  • 2 hours

Docker

# Run (requires AMBER_USERNAME, AMBER_PASSWORD, and AUTH_TOKEN in .env)
docker run -p 8000:8000 --env-file .env ghcr.io/d1scolor/amber-api-wrapper:latest

Important: The container requires AMBER_USERNAME, AMBER_PASSWORD, and AUTH_TOKEN environment variables. Set these in a .env file:

# .env file example
AMBER_USERNAME=your-username@example.com
AMBER_PASSWORD='your-password'
AUTH_TOKEN=your-32-character-auth-token

Docker Compose

services:
  amber-api:
    image: ghcr.io/d1scolor/amber-api-wrapper:latest
    container_name: amber-api-wrapper
    restart: unless-stopped
    ports:
      - "8000:8000"
    env_file:
      - .env
    environment:
      # Cron schedules use this local timezone. Override in .env if needed.
      TZ: ${TZ:-Australia/Sydney}
    healthcheck:
      test: ["CMD", "python", "-c", "import httpx; httpx.get('http://localhost:8000/api/amber/health')"]
      interval: 30s
      timeout: 10s
      retries: 3

Environment Variables

Variable Description Required
AMBER_USERNAME Amber account username Yes
AMBER_PASSWORD Amber account password Yes
AUTH_TOKEN Auth token for REST API (32+ chars) Yes
READ_ONLY_AUTH_TOKEN Read-only auth token (optional) No
LOG_LEVEL Logging level (DEBUG/INFO/WARNING/ERROR) No
ENABLE_RAW_QUERY Enable the admin-only /api/amber/raw-query endpoint (true/false) No
TZ Scheduler timezone override, e.g. Australia/Sydney; see Australian examples above No
SCHEDULE_<name> Cron task definitions (any number) No

License

MIT


Note: This project is a wrapper around the Amber Electric API. Please review Amber Electric's Terms of Service regarding API usage. This license covers the wrapper code, not Amber's API or services.

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages