A Laravel package for interacting with the Amber Energy public API. Amber is an Australian electricity retailer that passes through real-time wholesale prices, allowing you to automate high-power devices based on current and forecast prices.
- 🔌 Full support for all Amber Energy API endpoints
- 📊 Eloquent models for optional local data persistence
- 🔄 Automatic retry logic with progressive backoff
- ⚡ Rate limiting with graceful exception handling
- 🎯 Fluent facade API for clean, readable code
- 🛡️ Comprehensive exception handling
- 📝 Publishable configuration and migrations
- 🔍 Query scopes for easy data filtering
- PHP 8.1 or higher
- Laravel 10.x, 11.x, or 12.x
Install the package via Composer:
composer require wojt-janowski/laravel-amberPublish the configuration file:
php artisan vendor:publish --tag=amber-configIf you want to store API data locally, simply run the migrations:
php artisan migrateThe package migrations are automatically loaded and will be executed with your application's migrations.
Add your Amber API key to your .env file:
AMBER_API_KEY=your-api-key-hereYou can obtain an API key from the Amber app or by contacting Amber support.
AMBER_BASE_URL=https://api.amber.com.au/v1 # API base URL (default)
AMBER_TIMEOUT=30 # Request timeout in seconds
AMBER_RETRY_TIMES=3 # Number of retry attempts
AMBER_RETRY_SLEEP=1000 # Base retry delay in milliseconds
AMBER_RATE_LIMIT_WARNING=10 # Log warning when requests remaining < thresholdThe package provides a fluent facade for easy API access:
use WojtJanowski\LaravelAmber\Facades\Amber;
// Get all sites linked to your account
$sites = Amber::getSites();
// Get current prices for a site
$prices = Amber::getCurrentPrices('site-id-123');
// Get current prices with forecast and historical data
$prices = Amber::getCurrentPrices(
siteId: 'site-id-123',
next: 48, // Next 48 intervals forecast
previous: 48, // Previous 48 actual intervals
resolution: 30 // 30-minute intervals
);
// Get historical prices for a date range
$historicalPrices = Amber::getPrices(
siteId: 'site-id-123',
startDate: '2024-01-01',
endDate: '2024-01-07',
resolution: 30
);
// Get usage data
$usage = Amber::getUsage(
siteId: 'site-id-123',
startDate: '2024-01-01',
endDate: '2024-01-07'
);
// Get renewable percentage for a state
$renewables = Amber::getCurrentRenewables(
state: 'vic',
next: 24,
previous: 24
);You can also inject the AmberClient directly:
use WojtJanowski\LaravelAmber\AmberClient;
class EnergyController extends Controller
{
public function __construct(
protected AmberClient $amber
) {}
public function getCurrentPrices(string $siteId)
{
$prices = $this->amber->getCurrentPrices($siteId);
return response()->json($prices);
}
}If you've published and run the migrations, you can persist API data locally:
use WojtJanowski\LaravelAmber\Facades\Amber;
use WojtJanowski\LaravelAmber\Models\AmberSite;
$sitesData = Amber::getSites();
foreach ($sitesData as $siteData) {
AmberSite::updateOrCreate(
['id' => $siteData['id']],
$siteData
);
}use WojtJanowski\LaravelAmber\Models\AmberSite;
// Get all active sites
$activeSites = AmberSite::active()->get();
// Get a site with its price intervals
$site = AmberSite::with('priceIntervals')->find('site-id-123');
// Get sites by status
$pendingSites = AmberSite::pending()->get();
$closedSites = AmberSite::closed()->get();use WojtJanowski\LaravelAmber\Models\AmberPriceInterval;
$pricesData = Amber::getCurrentPrices('site-id-123');
foreach ($pricesData as $priceData) {
AmberPriceInterval::create([
'site_id' => 'site-id-123',
'type' => $priceData['type'],
'channel_type' => $priceData['channelType'],
'duration' => $priceData['duration'],
'spot_per_kwh' => $priceData['spotPerKwh'],
'per_kwh' => $priceData['perKwh'],
'date' => $priceData['date'],
'nem_time' => $priceData['nemTime'],
'start_time' => $priceData['startTime'],
'end_time' => $priceData['endTime'],
'renewables' => $priceData['renewables'],
'spike_status' => $priceData['spikeStatus'],
'descriptor' => $priceData['descriptor'],
'estimate' => $priceData['estimate'] ?? null,
'tariff_information' => $priceData['tariffInformation'] ?? null,
]);
}use WojtJanowski\LaravelAmber\Models\AmberPriceInterval;
// Get all actual price intervals
$actualPrices = AmberPriceInterval::actual()->get();
// Get forecast prices for a specific channel
$forecastPrices = AmberPriceInterval::forecast()
->channelType('general')
->get();
// Get spike prices
$spikes = AmberPriceInterval::spike()->get();use WojtJanowski\LaravelAmber\Models\AmberUsage;
// Get billable usage only
$billableUsage = AmberUsage::billable()->get();
// Get usage for a date range
$usage = AmberUsage::betweenDates('2024-01-01', '2024-01-07')->get();
// Get usage by channel type
$generalUsage = AmberUsage::channelType('general')->get();use WojtJanowski\LaravelAmber\Models\AmberRenewable;
// Get renewables for a specific state
$vicRenewables = AmberRenewable::state('vic')->get();
// Get actual renewables
$actualRenewables = AmberRenewable::actual()->get();
// Get renewables for a date range
$renewables = AmberRenewable::betweenDates('2024-01-01', '2024-01-07')->get();The package throws specific exceptions for different error scenarios:
use WojtJanowski\LaravelAmber\Facades\Amber;
use WojtJanowski\LaravelAmber\Exceptions\AmberAuthenticationException;
use WojtJanowski\LaravelAmber\Exceptions\AmberRateLimitException;
use WojtJanowski\LaravelAmber\Exceptions\AmberApiException;
try {
$sites = Amber::getSites();
} catch (AmberAuthenticationException $e) {
// Invalid or missing API key
Log::error('Authentication failed: ' . $e->getMessage());
} catch (AmberRateLimitException $e) {
// Rate limit exceeded
$retryAfter = $e->getRetryAfter();
Log::warning("Rate limit hit. Retry after {$retryAfter} seconds");
} catch (AmberApiException $e) {
// Other API errors (4xx, 5xx)
$statusCode = $e->getStatusCode();
$responseBody = $e->getResponseBody();
Log::error("API error {$statusCode}", $responseBody);
}The package automatically retries failed requests with progressive backoff:
- Retry attempts: 3 times by default (configurable)
- Backoff strategy: Exponential (1s, 2s, 4s)
- Retries on: Connection errors, 429 (rate limit), 500, 502, 503, 504
- No retry on: 400, 401, 404, 422
The Amber API includes rate limiting. The package:
- Automatically extracts rate limit headers from responses
- Logs warnings when approaching the limit (configurable threshold)
- Throws
AmberRateLimitExceptionwhen the limit is exceeded - Includes retry-after time in the exception
Represents an Amber Energy site (property).
Relationships:
priceIntervals()- HasMany relationship to price intervalsusage()- HasMany relationship to usage records
Scopes:
active()- Only active sitespending()- Only pending sitesclosed()- Only closed sites
Stores price interval data (actual, current, or forecast).
Relationships:
site()- BelongsTo relationship to site
Scopes:
actual()- Only actual intervalscurrent()- Only current intervalsforecast()- Only forecast intervalschannelType(string)- Filter by channel typespike()- Only spike prices
Stores energy usage data.
Relationships:
site()- BelongsTo relationship to site
Scopes:
billable()- Only billable qualityestimated()- Only estimated qualitychannelType(string)- Filter by channel typebetweenDates(string, string)- Date range filter
Stores renewable energy percentage data by state.
Scopes:
state(string)- Filter by stateactual()- Only actual renewablescurrent()- Only current renewablesforecast()- Only forecast renewablesbetweenDates(string, string)- Date range filter
| Method | Endpoint | Description |
|---|---|---|
getSites() |
GET /sites |
Get all sites linked to your account |
getCurrentPrices() |
GET /sites/{siteId}/prices/current |
Get current prices with optional forecast/history |
getPrices() |
GET /sites/{siteId}/prices |
Get historical prices for date range |
getUsage() |
GET /sites/{siteId}/usage |
Get usage data for date range |
getCurrentRenewables() |
GET /state/{state}/renewables/current |
Get renewable percentage for state |
For issues with the package, please open an issue on GitHub.
For Amber API support, contact dev@amber.com.au.
MIT License. See LICENSE file for details.
- Built for the Amber Energy API
- API specification: Amber Public API