A Python client for interacting with the Amber Electric API, providing REST endpoints for GraphQL queries and scheduled tasks.
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.
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.
- 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
Auth Token Authentication Required
All API endpoints (except /api/amber/health) require a valid auth token in the X-Auth-Token header.
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-Tokenheader 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
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.
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.
Generate a secure auth token using Docker:
docker run --rm ghcr.io/d1scolor/amber-api-wrapper:latest python -m amber_api_wrapper generate-keyThis 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.
Add the generated token to your .env file:
AUTH_TOKEN=xK9mP2qR7vL5nM8wQ3eY6tU1zA4sD0fGOptionally, you can set a separate read-only token for dashboards:
READ_ONLY_AUTH_TOKEN=your-read-only-token-hereRead-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.
- Minimum length: 32 characters
- Format: Any string at least 32 characters long
- Header:
X-Auth-Token: <your-token>
- 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.
- 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.
- Never commit
.envfiles to version control - Use different tokens for different environments (dev, staging, prod)
- Keep the auth token secret - Anyone with your token can control your battery
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_TOKENenvironment variable (admin access)READ_ONLY_AUTH_TOKENenvironment variable (read-only access)X-Auth-TokenHTTP 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
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
}uv syncpip install -e .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())Start the FastAPI server:
uvicorn api.main:app --reloadSet 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.
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-queryThis endpoint forwards your query to Amber using the service's Amber session, so only enable it when you understand the query being sent.
# 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/addConfigure 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| 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, * |
| 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 | 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 |
The Amber API only accepts specific durations for battery overrides:
- 0.5 hours (30 minutes)
- 1 hour
- 1.5 hours (90 minutes)
- 2 hours
# 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:latestImportant: 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-tokenservices:
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| 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 |
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.