NAV
bash javascript php

Introduction

Welcome to the Holiday Oracle API documentation. This API provides programatic access to data points that allow you to build out your applications and smart contracts.

Our API accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, and authentication.

Code Examples

Throughout this guide you will be shown example code to quickly create working integrations with the API. Examples currently exists for bash, Javascript and PHP.

Bash example assume you have curl installed in your development environment.

Javascript examples assume you have both nodejs and the node-fetch package installed.

PHP examples assume you have the Guzzle HTTP Client library installed.

Quick Start

Be sure to replace --TOKEN-- with your JWT token.

curl https://holidayoracle.io/api/v1/auth/me?api_token=--TOKEN--
const fetch = require("node-fetch");

const url = 'https://holidayoracle.io/api/v1/auth/me';
const headers = {
  "Content-Type": "application/json",
  "Authorization": "Bearer --TOKEN--"
}

fetch(url, { method: 'GET', headers: headers})
  .then((res) => {
     return res.json()
})
.then((json) => {
  console.log(json);
  // Do something with the returned data.
});
<?php
require __DIR__.'/vendor/autoload.php';
use GuzzleHttp\Client;

$client = new Client([
    'base_uri' => 'https://holidayoracle.io',
]);

$headers = [
    "Authorization" => "Bearer --TOKEN--"
];

$response = $client->request('GET', '/api/v1/auth/me', ['headers' => $headers]);
echo $response->getBody();
// Do something with the returned data.

Example Response

{
  "status": "success",
    "name": "Miguel Hernandez",
    "email": "miguel@holidayoracle.io"
}

To access the Holiday Oracle API you will need a JWT access token which you can obtain once you register an account. After registering your access token can be obtained at any time via the portal.

The API is located at https://holidayoracle.io/api/v1 and currently accepts HTTP POST and GET requests. You can test the validity of your access token by issuing a request to the auth::me endpoint.

If you authenticate successfully you should recieve a JSON response as the example on the right.

Authentication

JWTs are long lived and typically expire in a year. To invalidate your token, login to the portal and reset your token.

Your JWT can be sent to the API either as an api_token query parameter or via an Authorisation header. curl -H "Authorization: Bearer --TOKEN--" -X POST https://holidayoracle.io/api/v1/auth/me

API Token Hashing

The API allows you to pass in a SHA 256 hashed version of the api_token query parameter. This is useful if you need to expose the token in a publicly available asset such as a transaction on a Blockchain. To authenticate via a hashed api_token you must pass in the following parameters.

Parameter Description
auth_email Your account's email address
auth_nonce A random string
api_token SHA256(api_token + auth_nonce)

Client Libraries

A client library for Python can be found here https://pypi.org/project/holiday-oracle/, Javascript here https://www.npmjs.com/package/holiday-oracle and PHP here https://packagist.org/packages/offchaindata/holiday-oracle-php.

API Response

All valid responses are in JSON format. Every response contains a status property indicating if the request suceeded or failed. Additionally the API uses standard HTTP status codes to indicate the success or failure of an API call.

Errors

If your request fails or is rejected the status property in the response will be set to "error". The response will additionally contain an error message and error code.

{
    "status": "error",
    "error_message": "One of either 'timestamp' or 'date' is required.",
    "error_code":422
}

Auth

me

Requires authentication

Given a token, this will return the name and email of the user associated with the token. This is a useful method to test the validity of your token.

Example request:

curl -X GET "https://holidayoracle.io/api/v1/auth/me" \
    -H "Authorization: Bearer --TOKEN--"
const fetch = require("node-fetch");

const url = new URL("https://holidayoracle.io/api/v1/auth/me");

let headers = {
    "Authorization": "Bearer --TOKEN--",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
$client = new \GuzzleHttp\Client();
$response = $client->get("https://holidayoracle.io/api/v1/auth/me", [
    'headers' => [
            "Authorization" => "Bearer --TOKEN--",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "status": "success",
    "name": "Miguel Hernandez",
    "email": "miguel@holidayoracle.io"
}

HTTP Request

GET api/v1/auth/me

Response Properties

Parameter Type Description
name string The name of the user.
email string The email address of the user.

Date

Query date and holiday information.

date

Requires authentication Chainlink

The date endpoint accepts a date or timestamp and returns information on the given date. This information will include indicate things such as if the date is a holiday in your specified location or if the date is a weekend.

Additionally the endpoint can be used to add a number of days and/or calculate the next business day from a specified date.

Example request:

curl -X GET "https://holidayoracle.io/api/v1/date" \
    -H "Authorization: Bearer --TOKEN--" \
    -H "Content-Type: application/json" \
    -d '{"date":"2019-01-01","country":"AU","subdivision":"NSW"}'
const fetch = require("node-fetch");

const url = new URL("https://holidayoracle.io/api/v1/date");

let headers = {
    "Authorization": "Bearer --TOKEN--",
    "Content-Type": "application/json",
}

let body = {
    "date": "2019-01-01",
    "country": "AU",
    "subdivision": "NSW"
}

fetch(url, {
    method: "GET",
    headers: headers,
    body: JSON.stringify(body)
})
    .then(response => response.json())
    .then(json => console.log(json));
$client = new \GuzzleHttp\Client();
$response = $client->get("https://holidayoracle.io/api/v1/date", [
    'headers' => [
            "Authorization" => "Bearer --TOKEN--",
            "Content-Type" => "application/json",
        ],
    'json' => [
            "date" => "2019-01-01",
            "country" => "AU",
            "subdivision" => "NSW",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "data": [
        {
            "country": "AU",
            "date": "2019-01-01",
            "day": "Tuesday",
            "day_type": "weekday",
            "holidays": [
                {
                    "coverage": 7,
                    "holiday_description": "New Year's Day",
                    "holiday_duration": "full_day",
                    "holiday_type": "PUBLIC",
                    "score": "0.86"
                }
            ],
            "is_business_day": false,
            "next_business_date": "2019-01-02",
            "next_business_timestamp": 1546387200,
            "subdivision": "NSW",
            "timestamp": 1546300800
        }
    ],
    "status": "success"
}

HTTP Request

GET api/v1/date

POST api/v1/date

Body Parameters

Parameter Type Status Description
date string required The date for your request. The date must be in the format of YYYY-MM-DD. One of date or timestamp is required.
timestamp integer required A Unix epoch timestamp for your request. One of date or timestamp is required.
country string required ISO 3166-1 2 letter country code. Use the date/locations end point for list of supported countries.
subdivision string optional The geographical location where the date is applied. Use the date/locations end point for list of supported locations.
score float optional By default only dates with a score higher than 0.5 will be returned. You can adjust this threshold via this parameter.
add_days integer optional add_days The number of days to add to the given date or timestamp.
next_business_day integer optional Set to 1 to return the next business day, if the specified date/timestamp is not a business day. When used with add_days the system will first add days to your specified date/timestamp and if the calculated date is a non business day, the system will find the next business day.
language string optional Language (ISO 639-1) to return the day description in. If the requested language is not available, the default language will be returned.

Response Properties

Parameter Type Description
business_day_of_month integer Day of the month, excluding non-business days.
country string The specified country.
date string The calculated date for your request. The date is in the format of YYYY-MM-DD.
day string Day of the week name.
day_type string weekday or weekend.
holidays array List of holiday information if a holiday falls on the specified date.
coverage integer The number of data sources used in establishing holiday rules for the date.
holiday_description string A day description if it exists.
holiday_duration string If the date is a holiday, this will indicate the duration of the holiday (full_day or part_day).
holiday_type string If the date is a holiday, this will indicate the type of holiday.
language string Language of holiday_description
is_business_day boolean True if this is a business day.
next_business_date string If is_business_day is false, this will be the next business day.
score float The date rule's score.
subdivision string The specified subdivision.
timestamp integer The calculated unix epoch timestamp for your request.

holidays

Requires authentication

The holidays endpoint returns a list of holidays for the specified country, year and optional subdivision.

Example request:

curl -X GET "https://holidayoracle.io/api/v1/date/holidays" \
    -H "Authorization: Bearer --TOKEN--" \
    -H "Content-Type: application/json" \
    -d '{"country":"AU","subdivision":"WA","year":2020}'
const fetch = require("node-fetch");

const url = new URL("https://holidayoracle.io/api/v1/date/holidays");

let headers = {
    "Authorization": "Bearer --TOKEN--",
    "Content-Type": "application/json",
}

let body = {
    "country": "AU",
    "subdivision": "WA",
    "year": 2020
}

fetch(url, {
    method: "GET",
    headers: headers,
    body: JSON.stringify(body)
})
    .then(response => response.json())
    .then(json => console.log(json));
$client = new \GuzzleHttp\Client();
$response = $client->get("https://holidayoracle.io/api/v1/date/holidays", [
    'headers' => [
            "Authorization" => "Bearer --TOKEN--",
            "Content-Type" => "application/json",
        ],
    'json' => [
            "country" => "AU",
            "subdivision" => "WA",
            "year" => "2020",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "data": [
        {
            "country": "AU",
            "coverage": 7,
            "date": "2020-01-01 00:00:00",
            "day": "Wednesday",
            "holiday_description": "New Year's Day",
            "day_type": "weekday",
            "holiday_duration": "full_day",
            "holiday_type": "PUBLIC",
            "is_business_day": false,
            "score": "0.86",
            "subdivision": "WA",
            "timestamp": 1577836800
        },
        {
            "country": "AU",
            "coverage": 7,
            "date": "2020-01-27 00:00:00",
            "day": "Monday",
            "holiday_description": "Australia Day",
            "day_type": "weekday",
            "holiday_duration": "full_day",
            "holiday_type": "PUBLIC",
            "is_business_day": false,
            "score": "1.00",
            "subdivision": "WA",
            "timestamp": 1580083200
        },
        {
            "country": "AU",
            "coverage": 7,
            "date": "2020-03-02 00:00:00",
            "day": "Monday",
            "holiday_description": "Labour Day",
            "day_type": "weekday",
            "holiday_duration": "full_day",
            "holiday_type": "PUBLIC",
            "is_business_day": false,
            "score": "1.00",
            "subdivision": "WA",
            "timestamp": 1583107200
        },
        {
            "country": "AU",
            "coverage": 7,
            "date": "2020-04-10 00:00:00",
            "day": "Friday",
            "holiday_description": "Good Friday",
            "day_type": "weekday",
            "holiday_duration": "full_day",
            "holiday_type": "PUBLIC",
            "is_business_day": false,
            "score": "1.00",
            "subdivision": "WA",
            "timestamp": 1586476800
        }
    ],
    "status": "success"
}

HTTP Request

GET api/v1/date/holidays

POST api/v1/date/holidays

Body Parameters

Parameter Type Status Description
country string required ISO 3166-1 2 letter country code. Must be used with subdivision. Use the date/locations end point for list of supported countries.
subdivision string optional The geographical location where the date is applied. Use the date/locations end point for list of supported locations.
score string optional By default only dates with a score higher than 0.5 will be returned. You can adjust this threshold via this parameter.
year integer required Year for the request.
language string optional Language (ISO 639-1) to return the day description in. If the requested language is not available, the default language will be returned.
ical boolean optional Set to true if you would like holidays return in the iCal format.

Response Properties

Parameter Type Description
country string The specified country.
coverage integer The number of data sources used in establishing holiday rules for the date.
date string The calculated date for your request. The date is in the format of YYYY-MM-DD.
day string Day of the week name.
holiday_description string A day description if it exists.
day_type string weekday or weekend.
holiday_duration string If the date is a holiday, this will indicate the duration of the holiday (full_day or part_day).
holiday_type string If the date is a holiday, this will indicate the type of holiday.
language string Language of holiday_description
is_business_day boolean True if this is a business day.
score float The date rule's score.
subdivision string The specified subdivision.
timestamp integer The calculated unix epoch timestamp for your request.

locations

Requires authentication

Returns a list of supported countries and subdivisions for the Date Group API

Example request:

curl -X GET "https://holidayoracle.io/api/v1/date/locations" \
    -H "Authorization: Bearer --TOKEN--"
const fetch = require("node-fetch");

const url = new URL("https://holidayoracle.io/api/v1/date/locations");

let headers = {
    "Authorization": "Bearer --TOKEN--",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
$client = new \GuzzleHttp\Client();
$response = $client->get("https://holidayoracle.io/api/v1/date/locations", [
    'headers' => [
            "Authorization" => "Bearer --TOKEN--",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "data": [
        {
            "name": "Andorra",
            "iso_codes": {
                "alpha2": "AD",
                "alpha3": "AND",
                "numeric": "020"
            },
            "languages": [
                "ca",
                "en"
            ],
            "subdivisions": {
                "03": {
                    "name": "Encamp",
                    "code": "03"
                },
                "04": {
                    "name": "La Massana",
                    "code": "04"
                },
                "05": {
                    "name": "Ordino",
                    "code": "05"
                },
                "06": {
                    "name": "Sant Julià de Lòria",
                    "code": "06"
                },
                "07": {
                    "name": "Andorra la Vella",
                    "code": "07"
                },
                "08": {
                    "name": "Escaldes-Engordany",
                    "code": "08"
                },
                "02": {
                    "name": "Canillo",
                    "code": "02"
                }
            }
        },
        {
            "name": "United Arab Emirates",
            "iso_codes": {
                "alpha2": "AE",
                "alpha3": "ARE",
                "numeric": "784"
            },
            "languages": [
                "ar"
            ]
        },
        {
            "name": "Antigua and Barbuda",
            "iso_codes": {
                "alpha2": "AG",
                "alpha3": "ATG",
                "numeric": "028"
            },
            "languages": [
                "en"
            ],
            "subdivisions": {
                "05": {
                    "name": "Saint Mary",
                    "code": "05"
                },
                "06": {
                    "name": "Saint Paul",
                    "code": "06"
                },
                "10": {
                    "name": "Barbuda",
                    "code": "10"
                },
                "07": {
                    "name": "Saint Peter",
                    "code": "07"
                },
                "11": {
                    "name": "Redonda",
                    "code": "11"
                },
                "08": {
                    "name": "Saint Philip",
                    "code": "08"
                },
                "03": {
                    "name": "Saint George",
                    "code": "03"
                },
                "04": {
                    "name": "Saint John",
                    "code": "04"
                }
            }
        }
    ]
}

HTTP Request

GET api/v1/date/locations

POST api/v1/date/locations

business-days

Requires authentication Chainlink

Calculates the number of business days, holidays and weekend days between two given dates.

Example request:

curl -X GET "https://holidayoracle.io/api/v1/date/business-days" \
    -H "Authorization: Bearer --TOKEN--" \
    -H "Content-Type: application/json" \
    -d '{"date1":"2019-01-01","date2":"2019-01-01","country":"AU","subdivision":"NSW"}'
const fetch = require("node-fetch");

const url = new URL("https://holidayoracle.io/api/v1/date/business-days");

let headers = {
    "Authorization": "Bearer --TOKEN--",
    "Content-Type": "application/json",
}

let body = {
    "date1": "2019-01-01",
    "date2": "2019-01-01",
    "country": "AU",
    "subdivision": "NSW"
}

fetch(url, {
    method: "GET",
    headers: headers,
    body: JSON.stringify(body)
})
    .then(response => response.json())
    .then(json => console.log(json));
$client = new \GuzzleHttp\Client();
$response = $client->get("https://holidayoracle.io/api/v1/date/business-days", [
    'headers' => [
            "Authorization" => "Bearer --TOKEN--",
            "Content-Type" => "application/json",
        ],
    'json' => [
            "date1" => "2019-01-01",
            "date2" => "2019-01-01",
            "country" => "AU",
            "subdivision" => "NSW",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "data": {
        "business_days": 232,
        "weekend_days": 96,
        "total_holidays": 10,
        "weekday_holidays": 7
    },
    "status": "success"
}

HTTP Request

GET api/v1/date/business-days

POST api/v1/date/business-days

Body Parameters

Parameter Type Status Description
date1 string required The start date for your request. The date must be in the format of YYYY-MM-DD.
date2 string required The end date for your request. The date must be in the format of YYYY-MM-DD.
country string required ISO 3166-1 2 letter country code. Use the date/locations end point for list of supported countries.
subdivision string optional The geographical location where the date is applied. Use the date/locations end point for list of supported locations.
score float optional By default only holidays with a score higher than 0.5 will be used in the day calculations.

Response Properties

Parameter Type Description
business_days integer Number of business days between requested dates.
weekend_days integer Number of weekend days between requested dates.
total_holidays integer Total holidays between requested dates.
weekday_holidays integer Total holidays excluding weekend days.

Help and Feedback

If you're looking for help with the API or wish to provide feedback in regards to additional features you would like to see, click on the help button below and let us know.

Leave Feedback

Middleware

The Holiday Oracle API provide a convenient mechanism for performing a variety of tasks on your request that can help reduce computational processing needed by your application and helps reduce the number of components you need to manage.

To enable a specific middleware you must pass in the middleware parameter as a list. Note that at the moment, we only support chainlink as a valid value.

Chainlink Middleware

By using the Chainlink Middleware you eliminate the need to have an external adaptor running on your Chainlink node and complex job specifications. Simply use the HttpPost adapter and pass in your JWT as either an authentication header or a POST parameter.

Smart Contract Integration

Provable

The Holiday Oracle API can be integrated into your smart contracts via the Provable Oracle service. The Provable website has detailed documentation on how to use their Oracle service, but here are some specific details on how to fashion your Holiday Oracle API calls in your contract.

Provable recommends that you do not place your API key in plain text into your contract as it is a security risk. Instead you should make use of Provable's encrypted queries. You will need to encrypt the entire URL with the API key as a request parameter along with the JSON Parsing command to extract the relevant bits of data from the API response. An example string to encrypt is shown on the right.

python encrypted_queries_tools.py -e \
-p 044992e9473b7d90ca54d2886c7addd14a61109af202f1c95e218b0c99eb060c7134c4ae46345d0383ac996185762f04997d6fd6c393c86e4325c469741e64eca9 \
"json(https://offchaindata.com/api/v1/date?api_token=YOUR_API_KEY).data.0.business_day_of_month"

Once you have your encrypted string, you will need to use a nested data source. You'll find an example request in the contract on the right which builds upon the example contracts in Provable's documentation.

pragma solidity ^0.4.22;
import "github.com/provable-things/ethereum-api/provableAPI_0.4.25.sol";

contract ExampleContract is usingProvable {

    string public WDOM;
    event LogConstructorInitiated(string nextStep);
    event LogUpdated(string WDOM);
    event LogError(string error);
    event LogNewProvableQuery(string description, bytes32 queryId);

    mapping (bytes32 => bool) public pendingQueries;

    function ExampleContract() payable {
        LogConstructorInitiated("Constructor was initiated. Call 'updateWDOM()' to send the Provable Query.");
    }

    function __callback(bytes32 myid, string result) {
        if (msg.sender != provable_cbAddress()) revert();
        require (pendingQueries[myid] == true);
        WDOM = result;
        LogUpdated(result);
        delete pendingQueries[myid]; // This effectively marks the query id as processed.
    }

    function updateWDOM() payable {
        if (provable_getPrice("URL") > this.balance) {
          LogError("Provable query was NOT sent, please add some ETH to cover for the query fee");
        } else {

          bytes32 queryId = provable_query("nested", "[URL] ['BIvj16A4sfdJAqBB0zJ5VVonyjdc5Q3yVoZlRv8ISk0TdrLSZWWjNqHcfQp4B8o5+B2tWe2hUMwsh6mR2d5qQKBOe5g6j5kFUlUcn4jbH1w4SzIAES10Z7tJc6mKArkK9eJ75dROsacEqR8+2FbJIyekKRX9Lh2DRgLenLHxjmpaaHT0bKLTUibh7IurohKVDNr7A0rBNj8gweVarbk/VhLaa3zrR7GTHXntsykB/uChfKnldxiIQRN4La3y2KM0Zzcl9aAXJaJ++pP1c5VPQjXUHrJYa8BOkM/cNMMEJj+MeHvF00J25mabb6q2aenyQi0EcPvnpV0ChK0MdcYl2e0jszSB4KhlT8B8KNQGuTrnB+ACfh5PufepejtxIOn6KDAbZkp8RUY7RStMtuKKQmpAQGyTOOCCPjvlv0n5hKgpQiO4BHbFNhCDDUdKi4qsflTBho1io9aUicuRAxrRoyJWwYsTpk0Ltm3IDzWHt3R0HVavSBcSS8B5Zl5h74LNSXtgU82ISq6e8HSQjCcOk02fhpRshIkimuHZ7s4YM9nQWllmPgyXNLdLqW4uiMV1vOfIuuElxSLbunBCKBFuh3r2pAOd/9evMBPvlNCB27E76pA/nOJuwNkzDJygXGS3NEo=', '{ \"date\": \"2019-01-05\",   \"region\": \"AU-NSW\"}']");
          LogNewProvableQuery("Nested - Provable query was sent, standing by for the answer..", queryId);
          pendingQueries[queryId] = true;
        }
    }
}