Degree Days

Degree Days

Weather Data for Energy Saving

Access the Degree API using PowerShell

This page has a sample PowerShell script showing how to specify a JSON request, send it to our API servers (past the security system), and process the JSON response that comes back.

It's not a full client library (like we have for Java, .NET, and Python), but it should be pretty easy to adapt it to suit your needs.

See the JSON API docs for more about specifying the data you want in the JSON request. There are lots of options, and the request included in the PowerShell script below is just a simple example. The JSON docs also explain more about the data you can expect back in the response.

You might also find the JSON API test tool useful for testing different JSON requests and seeing the JSON responses that come back.

Many thanks to Tim Hartford from INSIGHT2PROFIT who sent us the PowerShell code that got this sample started.

# This is a PowerShell script.  Create a file called Get-DegreeDays.ps1 and copy
# this code in.  Then open PowerShell, use the cd command to navigate to the
# directory containing Get-DegreeDays.ps1, then run it using:
# .\Get-DegreeDays.ps1
# For more on adapting this script to suit your needs, see the docs at

# The test API access keys are described at
# They will let you access data for the Cape Cod area only.
# To fetch data for locations worldwide, sign up for a proper API account at
# and copy your API access keys here.
$accountKey = 'test-test-test'
$securityKey = 'test-test-test-test-test-test-test-test-test-test-test-test-test'
# You can call the API over HTTP using or
# over HTTPS using - set the endpoint URL
# below as appropriate.
$endpoint = ''

# ************* STEP 1: Create the request *************************************
# First we create a JSON request that specifies what we want from the API.
# See for more on this.

# You can fetch data from a station ID, a longitude/latitude position, or a 
# postal/zip code, as explained at
$location = [ordered]@{
    type = 'PostalCodeLocation'
    postalCode = '02532'
    countryCode = 'US'
# In this example we fetch both HDD and CDD, using the same breakdown (daily
# data covering the last 7 days) for both. For more breakdown options see
$breakdown = [ordered]@{
    type = 'DailyBreakdown'
    period = [ordered]@{
        type = 'LatestValuesPeriod'
        numberOfValues = 7
$locationDataRequest = [ordered]@{
    type = 'LocationDataRequest'
    location = $location
    dataSpecs = [ordered]@{
        # Here we specify 2 DataSpec items: one for HDD and one for CDD.  You
        # can specify up to 120 DataSpec items in one request (e.g. to fetch
        # data in lots of base temperatures).  With an API Standard+ account you
        # can have a DataSpec for hourly temperature data too.
        # Give each DataSpec a unique name so you can get the corresponding
        # DataSet from the response.
        myHDD =[ordered]@{
            type = 'DatedDataSpec'
            calculation = [ordered]@{
                type = 'HeatingDegreeDaysCalculation'
                baseTemperature = [ordered]@{
                    unit = 'F'
                    value = 60
            breakdown = $breakdown
        myCDD = [ordered]@{
            type = 'DatedDataSpec'
            calculation = [ordered]@{
                type = 'CoolingDegreeDaysCalculation'
                baseTemperature = [ordered]@{
                    unit = 'F'
                    value = 70
            breakdown = $breakdown
$fullRequest = [ordered]@{
    securityInfo = [ordered]@{
        endpoint = $endpoint
        accountKey = $accountKey
        timestamp = [DateTime]::UtcNow.ToString('yyyy-MM-ddTHH:mm:ss.fffZ')
        random = [Guid]::NewGuid().ToString()
    request = $locationDataRequest
$fullRequestJson = ConvertTo-Json $fullRequest -Depth 10 -Compress
# Now our JSON request is ready.  Uncomment the line below to see the JSON:

# ************* STEP 2: Send the request to the API ****************************
# Next we sign the JSON request and package everything together into an HTTP
# request which we send to the Degree API.  This follows the spec at
function ConvertTo-Bytes([string] $String) {
    return [System.Text.Encoding]::UTF8.GetBytes($String)
function Get-HmacSha256([byte[]] $Bytes, [byte[]] $KeyBytes) {
    $hmac = New-Object System.Security.Cryptography.HMACSHA256
    $hmac.Key = $KeyBytes
    return $hmac.ComputeHash($Bytes)
function ConvertTo-Base64Url([byte[]] $Bytes) {
    $base64 = [System.Convert]::ToBase64String(
            $bytes, [System.Base64FormattingOptions]::None)
    return $base64.TrimEnd('=').Replace('+', '-').Replace('/', '_')
$requestBytes = ConvertTo-Bytes $fullRequestJson
$securityKeyBytes = ConvertTo-Bytes $securityKey
$signatureBytes = Get-HmacSha256 $requestBytes $securityKeyBytes
$params = @{
    request_encoding = 'base64url'
    signature_method = 'HmacSHA256'
    signature_encoding = 'base64url'
    encoded_request = ConvertTo-Base64Url $requestBytes
    encoded_signature = ConvertTo-Base64Url $signatureBytes
$fullResponseJson = Invoke-WebRequest -Uri $endpoint -Method POST -Body $params
if ($fullResponseJson -eq $null) {
    Write-Warning 'Problem connecting to API. Exiting script.'

# ************* STEP 3: Process the response from the API **********************
# The JSON response is explained at

# Uncomment the line below to see the JSON response:
#Write-Host $fullResponseJson

# Use ConvertFrom-Json to turn the JSON response into an object:
$fullResponse = ConvertFrom-Json -InputObject $fullResponseJson
# $fullResponse.metadata has some rate limit info, but we are mainly
# interested in $fullResponse.response (a LocationDataResponse in this case).
$response = $fullResponse.response
if ($response.type -eq 'Failure') {
    # See for more about failures.
    Write-Host "Request failure: $response"
} else {
    # The response contains a lot of useful info.  See above to view the JSON,
    # or check the JSON docs at
    Write-Host "Station ID: $($response.stationId)"
    # "myHDD" is the name we gave the HDD DataSpec in our request.
    $hddData = $response.dataSets.myHDD
    if ($hddData.type -eq 'Failure') {
        Write-Host "Failure for HDD DataSet: $hddData"
    } else {
        Write-Host 'HDD:'
        foreach ($v in $hddData.values) {
            Write-Host "$($v.d): $($v.v)"
    $cddData = $response.dataSets.myCDD;
    if ($cddData.type -eq 'Failure') {
        Write-Host "Failure for CDD DataSet: $cddData"
    } else {
        Write-Host 'CDD:'
        foreach ($v in $cddData.values) {
            Write-Host "$($v.d): $($v.v)";

Further options and guidance

The sample code above will hopefully get you fetching degree days, but the JSON API docs also explain other options like fetching hourly temperature data and using the API for advanced regression.

You can quickly test out all sorts of JSON requests with the JSON API test tool, then write code like the example above for any that you want to use. The code in step 2 of the sample above will happily send any valid JSON request to the API and give you a response back that you can process.

It is also worth reading the higher-level integration guide for tips on the various approaches to integrating with the API. We have helped a lot of businesses integrate their software with our API so we are very familiar with the patterns that work well for common use cases. And please feel free to email us if you'd like more help.

Choose your API Plan and Start Today!

© 2008–2024 BizEE Software – About | Contact | Privacy | Free Website | API | Integration Guide | API FAQ | API Sign-Up