Working Days 
API for Developers 
|
v1.3


Introduction

Our HTTP JSON API (v1.3) exposes several services:

  • Analyse a period. You provide a start date and an end date, we respond with the number of days, working days, work hours, weekend days, the list of the public holidays over the period for a given country.
  • Add any number of working days or work hours to a given date. You provide a start date, we return the end date. We also return the days ventilation over that period.
  • List non working days between two dates
  • Get detailed information about a specific date or a period

We cover more than 50 countries and 270 regional calendars. We also cover main stock exchanges calendars. The quality of our data is our top priority. We work hard to keep our database up to date by following government announcements regarding public holidays changes.

All the calendars can be fully customized from our friendly working days websites’ user interfaces (public holidays, weekend days, work hours, custom dates & more) or programmatically, adding or deleting a custom period from the API.

Without a key, you can immediately evaluate the service as long as your dates are inside the year 2013. In order to access the API without dates limitations, you will be needing a personal API key. Get your key right now, it comes with a SLA and a Data Quality Insurance.

Give also a try to our API test tool, it will let you understand the API behavior very quickly, or refer to our open API documentation.

Now, let's look at all the API endpoints, some sample HTTP requests and JSON replies, and some PHP code examples (JSON libraries are available in all languages).


calendar illustration

They trust us:
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer
logo customer

Authentication

In every request, you should add the HTTP header
"key: YOUR-PERSONAL-API-KEY".
containing your subscriber's key.

Your key may also be sent as a GET HTTP parameter &key=YOUR-PERSONAL-API-KEY

Without any key, you can query the year 2013 which is dedicated to the evaluation.
Outside, the year 2013, you will get a 401-Unauthorized error code if your key is missing or unknown.

Analyse a period

Endpoint /analyse


Analyse a given calendar over a time period.


Arguments

Name Description

country_code

Required
The ISO country code (2 letters).
See the list of countries
For instance, if you want to take into account the french calendar, send country_code=FR

start_date

Required
The start date (YYYY-MM-DD)

end_date

Required
The end date (YYYY-MM-DD)

start_time

Optional
The start date's time (24 hours format, like 09:00 or 15:00, but not 3pm).
If omitted, default value is 00:00.

end_time

Optional
The end date's time (24 hours format, like 09:00 or 15:00, but not 3pm)
If omitted, default value is 23:59.

configuration

Optional
The name of the regional preset configuration. See the list of configurations
Each country comes with a set of preset configurations (applicable public holidays in that region).
For instance in the USA, you don't have the same public holidays in New York and in California. If you are interested with the working days calendar in New York State, you would go : contry_code=US&configuration=New+York. If you are interested in the american stock exchange opening calendar, you would go : contry_code=US&configuration=New+York+Stock+Exchange.
If you don't provide the configuration parameter, the default configuration will be applied. In the case of the USA, the default configuration is California.
Many countries have only one preset configuration (Chile, Denmark, China, Colombia, etc..), in that case this parameter is not necessary and will be ignored.

holiday_language

Optional
Specifies the language in which the names of public holidays are presented (ISO 639-1, 2 letters code).
This optional parameter is beneficial when querying a country with multiple official languages. Refer to the list of supported languages for more details.
If this parameter is not specified, the default language used will be the primary official language of the queried country.

profile_id

Optional
If you want to query a customized calendar, provide its profile_id.
See this example.

Suppose we want to analyse the period from 1st january 2013 to 31th december 2013 in Canada, with default parameters, the URL to request is going to be:


and the service is going to reply with a JSON response like that (because the parameter is omitted, default configuration Ontario is used):



Suppose now we want to analyse the period from 1st january 2013 to 31th december 2013 in Germany with the public holidays calendar applicable in the land of Baden-Württemberg, the URL to request is going to be :


and the service is going to reply with a JSON response like that:



Example PHP client code

Add working days to a date


Endpoint /add_working_days


Adding any number of working days to a given date can be useful in many situations, for example computing a shipping delay or a contract deadline.
The resulting period (from start_date included to end_date included) will be of a working days length equal to the increment parameter.

Arguments

Name Description

country_code

Required
The ISO country code (2 letters).
See the list of countries
For instance, if you want to take into account the french calendar, send country_code=FR

start_date

Required
The start date (YYYY-MM-DD)

increment

Required
The number of working days you want to add to your start date (positive or negative integer but not zero)

include_start

Optional
Should the count include the start_date? Default value is true.
If you set include_start to false ("false" or "0"), the count will start at the next working day (or previous working day, if increment is negative) If set to false, the resulting period (from start_date excluded to end_date included) will be of a working days length equal to the increment parameter.

configuration

Optional
The name of the regional preset configuration. See the list of configurations
Each country comes with a set of preset configurations (applicable public holidays in that region).
For instance in the USA, you don't have the same public holidays in New York and in California. If you are interested with the working days calendar in New York State, you would go : contry_code=US&configuration=New+York. If you are interested in the american stock exchange opening calendar, you would go : contry_code=US&configuration=New+York+Stock+Exchange.
If you don't provide the configuration parameter, the default configuration will be applied. In the case of the USA, the default configuration is California.
Many countries have only one preset configuration (Chile, Denmark, China, Colombia, etc..), in that case this parameter is not necessary and will be ignored.

holiday_language

Optional
Specifies the language in which the names of public holidays are presented (ISO 639-1, 2 letters code).
This optional parameter is beneficial when querying a country with multiple official languages. Refer to the list of supported languages for more details.
If this parameter is not specified, the default language used will be the primary official language of the queried country.

profile_id

Optional
The ID of a customized calendar (6 caracters).
See this example.

Suppose we want to add 90 working days to the 1st january 2013 over the french usual calendar, with default parameters, the URL to request is going to be:


and the service is going to reply with this JSON response (the end date, and the resulting period analysis):



Example PHP client code





Suppose now, you simply want to know what is the next working day after any given date.
If you add 1 working day to a date, if this date is a sunday or a public holiday, you will get the next working, the resulting period being one working day long (and usually 2 days long). But the if the date is a working day, simply adding one day will lead to the same date, the resulting period being one working day long (and one day long).
That's why we added the parameter include_start: if you set it to false, it will ignore the first date of the resulting period count, and simply adding one working day will always return the next working day.


returns 2013-01-03 whereas


returns 2013-01-02

Work hours

When you analyse a period, the response also includes the number of work hours over the period.
If you omit the start_time and end_time parameters, the work hours are counted from the begining of the first day (start_date at 00:00) to the end of the last day (last_date at 23:59).
If you provid a start_time, and a end_time, the work hours are counted from start_date at start_time until end_date at end_time.

By default, the calculation of working hours is based on this default week time schedule but you can configure and use a custom week time schedule. Learn more about creating a custom configuration.

default week

Add working hours to a date


Endpoint /add_working_hours


Adding an amount of working time to a given start date/time, can be very useful (for instance, implementing an SLA for a support team).
An amount of working time can be added or removed, over the default working week time schedule or over a personalised time schedule.
This command will consume 1 day for every 8 hours added/removed from your monthly quota.
Let's look at the command definition and some examples.

Arguments

Name Description

country_code

Required
The ISO country code (2 letters).
See the list of countries
For instance, if you want to take into account the french calendar, send country_code=FR

start_date

Required
The start date (YYYY-MM-DD)

start_time

Required
The start time in a 24 hours format with leading zeros.
For example 08:15 (but not 8:15) or 15:00 (but not 3pm)

increment_time

Required
The amount of working time to be added (or removed) to the start date time. Format: H:i
For example, to add one hour : 1:00. To add 30 hours and 15 minutes: 30:15.
To remove 45 minutes : -0:45
This amount cannot exceed 5000 hours.

configuration

Optional
The name of the regional preset configuration. See the list of configurations

profile_id

Optional
The ID of a customized calendar (6 caracters).
See this example.

Suppose we want to add 4 working hours to the January 8th 2013, 11:00 over the south african usual calendar, with default settings, the URL to request is going to be:


The service is going to reply with a JSON response like that:
(because the default time schedule is applied, we have a lunch break between 12:00 and 14:00, and adding 4 hours takes us to 17:00 (5pm)).



Example PHP client code



Here is the default working hours of the week (for every calendars):
default week

Now let's configure a custom week time schedule.
Let's go to south-africa.workingdays.org sign up or sign in using any email
Then define your custom time schedule from the setup screen and note the profile_id

screenshot add working hours

Now let's try again adding 4 working hours to the January 8th 2013, 11:00 over the south african usual calendar, this time using our custom configuration:

https://api.workingdays.org/1.3/add_working_hours?country_code=ZA&start_date=2013-01-08&start_time=11:00&increment_time=2:00&profile_id=..

The service is going to reply with a JSON response like that:
(because now the lunch break being between 13:00 and 14:00, adding 4 hours takes us to 16:00 (4pm)).

Custom configuration & profiles

The calendar of each country can be fully personalised independently in a user friendly way from any of the working days websites.

Through a custom configuration you can:
  • Define your weekend days one by one (half-day granularity)
  • Define your own default week time schedule (1 to 4 weeks templates are supported). It is your own default definition of a regular week (working hours morning and afternoon for each day of the week)
  • Choose your public holidays one by one, or by selecting one of our preset configurations
  • Define one or several custom periodic rules: for instance "every second monday of the month is closed" or "every tuesday of january" has specific working hours that overloads your default week time schedule
  • Add some specific "custom dates" (full day or half day, typically days off). If a custom date is a working day, you can define its working hours, morning and afternoon, overloading your default week time schedule.
  • The four layers of configuration

    One set of these custom parameters for a given country is called a "profile", and is created when connected to a working days website (using any email address).
    You can create up to 5 different profiles under one user account (with a premium account any number of profiles can be created).

    profiles

    From the API, querying any endpoint, just add profile_id=yourprofileID parameter in order to query your customized calendar.
    The profile ID can be copied from the user interface (it is a secret 6 caracters string):

    profile id

    This feature can be easily tried from the API TEST TOOL

    API users with a premium plan can create profiles with unlimited number of custom dates (just connect to the working days website with the same email as the one used under the API account).
    Other users will be limited to 200 custom dates per profile.

    Create a profile

    Endpoint /add_profile


    Creating or removing profiles can be done in a friendly way from the working days websites, however creating new profiles programmatically can be useful in some situations (for instance interfacing the human ressources repository, adding one profile per employee with a script).

    When you create a new profile programmatically, it will be under the under the email of the API's subscriber account.

    With an INITIAL plan, you can create up to 5 profiles per country.
    With a PRO plan, you can create up to 30 profiles per country.
    With a PREMIUM plan, you can create unlimited number of profiles.

    Creating a profile will remove 1000 days from your monthly quota.


    Arguments

    Name Description

    profile_name

    Required
    The name identifying your profile (up to 20 caracters)

    country_code

    Required
    The country_code calendar

    configuration

    Optional
    The name of the regional preset configuration.
    If omitted, the country's default configuration will be used.

    weekend

    Optional
    The weekend days of the calendars See advanced parameters

    start_template

    Optional
    In case you are using an alternating week template See advanced parameters

    week_times

    Optional
    The week work hours
    If omitted, working days's morning will be worked from 8:00 to 12:00 and working days's afternoon from 14:00 to 18:00
    See advanced parameters

    Suppose we want to create a new profile based on the calendar in Quebec, named "John Doe":


    and the service is going to reply with the ID of the new profile:




    You can connect (using the same email as our API account) to the correponding working days website (in this example workingdays.ca) to find your new profile created under the setup screen.

    Delete a profile

    Endpoint /delete_profile


    Delete a profile identified by its profile_id.
    Deleting a profile will remove 1 day from your quota.


    Arguments

    Name Description

    profile_id

    Required
    The ID of the profile you want to delete (under your account)

    Suppose we want to delete the profile created in the previous example:


    and the service is going to reply like that:


    Define a custom period

    Endpoint /define_custom_period


    Defining a custom period (typically days of vacations of an employee or days of annual closure of a company) can be done from the working days websites user interface but can also be done programmatically from the API.
    A typical use case would be to retrieve the vacations of the workers out of the human ressources software and insert them into a custom calendar, then being able to query available working days.


    Arguments

    Name Description

    profile_id

    Required
    The ID of the calendar we are customizing.

    start_date

    Required
    The start date of the custom period (YYYY-MM-DD)

    end_date

    Optional
    The end date of the custom period (YYYY-MM-DD)
    If omitted, end date will be equal to start date (one day custom period)

    working_days

    Optional
    Type of the custom period. Possible values are:
    • 'false' : vacations
    • 'true' : working days
    • 'note' : a note is just a short text on the period, not changing the working nature of the period (for instance, if you define a note over a period including working days and public holidays, working days will remain worked, and public holidays will remain not worked)
      Notes don't have a color.
    Default value is 'false' (not worked).

    description

    Required
    A textual description of the custom period (up to 30 caracters).

    color

    Optional
    The color of custom period when displayed on the calendar.
    Colors can be useful in order to classify custom periods.
    Possible value: orange | green | blue | yellow | pink
    Default value is orange.

    start_morning

    Optional
    Does the custom period starts in the morning of the start_date? ('true' | 'false')
    Default value is 'true'.
    (This parameter can be used if you want to create half day custom periods.)

    end_afternoon

    Optional
    Does the custom period ends in the afternoon of the end_date? ('true' | 'false')
    Default value is 'true'.
    (This parameter can be used if you want to create half day custom periods.)

    work_hours

    Optional
    When defining a custom working period, you may define its work hours.
    If left empty, the week default work hours of this profile will be used.
    If provided, this parameter defines the specific work hours for those custom dates. Expected format is 4 schedules separed by * . For instance '08:03*12:30*14:30*18:30*'

    wages

    Optional
    When defining a custom period (worked or not), you may define its wages per day.
    If provided, this parameter defines the specific wages (€ or $ per day) of this custom period. For instance '235.56', if you earned 235.56 ($ or €) per day over that period. If left empty when defining a custom working period, the work hours and the profile's hourly wage will be used to compute the wages per day over that custom period.
    When defining a custom non-working date, you may also define its wages (paid holidays). If left empty, the default wages will be 0. You can also provide the special value "D", which means the wages will be computed from the profile's hourly wages and the working hours of the underlying week schedule.

    teleworking

    Optional
    When defining a custom period working period, you may define it that period was a teleworking period (home office) ('true' | 'false')
    Default value is 'false'.

    Suppose we want to create a vacation period from the 1st to the 13rd of juanuary, the request is going to be:


    and the service is going to reply with a JSON response like that:




    We can go to the correponding working days website, to see the result:

    screnshot workingdays.ca

    Let's add now a custom period from March 5 afternoon to March 12 morning, and color green:


    and the service is going to reply with a JSON response like that:



    Again, we can go to the correponding working days website to check the result:

    screenshot workingdays.ca

    Delete a custom period

    Endpoint /delete_custom_period


    Removing a previously defined custom period


    Arguments

    Name Description

    profile_id

    Required
    The ID of the calendar we are customizing.

    start_date

    Required
    The start date of the custom period (YYYY-MM-DD)

    end_date

    Optional
    The end date of the custom period (YYYY-MM-DD)
    If omitted, end date will be equal to start date (one day custom period)

    Suppose we want to remove the vacation period from the 7th to the 13rd of juanuary, the request is going to be:


    and the service is going to reply with a JSON response like that:




    Following previous example, we can go to the correponding working days website, to see the result:

    screenshot workingdays.ca

    List custom dates

    When you analyze a period using the endpoint /analyse, the JSON response also includes the list of the custom dates over the period with their types.

    A custom date can be of this type:
  • 4 == custom date not worked
  • 8 == custom working day
  • 64 == custom working morning
  • 128 == custom working afternoon
  • 256 == custom morning not worked
  • 512 == custom afternoon not worked
  • 131072 == a note (a note is just a short text, not changing the working nature of the period)
  • 262144 == a note (morning)
  • 524288 == a note (afternoon)

  • Let's see an exemple: suppose one user defined those custom dates over the month of march:



    The /analyse endpoint over the month of march for that particular profile will responde like this:


    List non working days

    Endpoint /list_non_working_days


    List the non working days (weekend days, public holidays and custom dates) between 2 dates in chronological order.


    Arguments

    Name Description

    country_code

    Required
    The ISO country code (2 letters).
    See the list of countries
    For instance, if you want to take into account the french calendar, send country_code=FR

    start_date

    Required
    The start date (YYYY-MM-DD)

    end_date

    Required
    The end date (YYYY-MM-DD)

    configuration

    Optional
    The name of the regional preset configuration. See the list of configurations
    Each country comes with a set of preset configurations (applicable public holidays in that region).
    For instance in the USA, you don't have the same public holidays in New York and in California. If you are interested with the working days calendar in New York State, you would go : contry_code=US&configuration=New+York. If you are interested in the american stock exchange opening calendar, you would go : contry_code=US&configuration=New+York+Stock+Exchange.
    If you don't provide the configuration parameter, the default configuration will be applied. In the case of the USA, the default configuration is California.
    Many countries have only one preset configuration (Chile, Denmark, China, Colombia, etc..), in that case this parameter is not necessary and will be ignored.

    holiday_language

    Optional
    Specifies the language in which the names of public holidays are presented (ISO 639-1, 2 letters code).
    This optional parameter is beneficial when querying a country with multiple official languages. Refer to the list of supported languages for more details.
    If this parameter is not specified, the default language used will be the primary official language of the queried country.

    profile_id

    Optional
    If you want to query a customized calendar, provide its profile_id.
    See this example.

    Let's look at first example. Suppose one user defined this calendar over the month of february in Canada:



    and now let's send this request to get all the none working days for this calendar over this month:

    The service is going to reply with the list of 10 non working days over the month and their types.

    The type can be one (or several) of this types:
  • 1 == weekend day
  • 2 == public holiday
  • 4 == non-working custom date
  • 256 == non-working custom date, morning only
  • 512 == non-working custom date, afternoon only
  • 1024 == weekend day, morning only
  • 2048 == weekend day, afternoon only
  • 4096 == public holiday, morning only
  • 8192 == public holiday, afternoon only




  • The 5th is of type 1 because it is a week end day.
    The 21st is of type 2 because it is a public holiday.
    The 25th is of type 36 because it is a custom non working date (4) over a working day (32). The type = 4+32= 36

    Let's a second example in which, user has a custom week end definition (week end on saturday afternoons and sundays) and define a few custom dates:



    Let's query this url:


    and the service is going to reply this way:



    The 1st is of type 2050 because it is a public holiday (2) and a week end day afternoon (2048)
    The 3rd is of type 2 because it is a public holiday.
    The 4th is of type 36 because it is a custom non working date (4) over a working day (32).
    The 22 is of type 2304 because it is a custom non working morning (256) and a week end day afternoon (2048).


    Example PHP client code

    Get detailed day information


    Endpoint /get_info_day


    Get all the detailed information about a specific date.
    Each day is characterized by a morning and an afternoon.
    If an half day (morning or afternoon) is worked, it has working hours, and wages. It can be a regular working day, or a custom working day.
    If an half day is not worked, the number of working hours and the wages are equal to zero. It can be weekend, a public holiday, or a custom non working day.
    By default, a day is a working day, a weekend day or a public holiday.
    But they can be defined more finely through a custom configuration.

    Arguments

    Name Description

    country_code

    Required
    The ISO country code (2 letters).
    See the list of countries
    For instance, if you want to take into account the french calendar, send country_code=FR

    date

    Required
    The date to be analysed (YYYY-MM-DD)

    configuration

    Optional
    The name of the regional preset configuration. See the list of configurations

    holiday_language

    Optional
    Specifies the language in which the names of public holidays are presented (ISO 639-1, 2 letters code).
    This optional parameter is beneficial when querying a country with multiple official languages. Refer to the list of supported languages for more details.
    If this parameter is not specified, the default language used will be the primary official language of the queried country.

    profile_id

    Optional
    The ID of a customized calendar (6 caracters).
    See this example.

    Here is an example URL:
    And here is the correponding response:



    And here is the definition of each field of this JSON response:

  • : 0 if's not a working day / 1 if it is a working day / 0.5 in case you defined an half open day through a custom configuration

  • : the number of working hours in this day (a float between 0 and 24)

  • : the wages earned during this day this day (a float). By default, this is equal to the number of work hours x 20, but it can be define more finely through a custom configuration

  • : the start time of the working morning in a 24 hours format with leading zeros (for instance 08:00). If that morning is not worked, the field is empty.

  • : the end time of the working morning in a 24 hours format with leading zeros (for instance 12:00). If that morning is not worked, the field is empty.

  • : the start time of the working afternoon in a 24 hours format with leading zeros (for instance 14:00). If that afternoon is not worked, the field is empty.

  • : the end time of the working afternoon in a 24 hours format with leading zeros (for instance 18:00). If that afternoon is not worked, the field is empty.

  • : 0 if's not a public holiday / 1 if it is a public holiday / 0.5 if is a public holiday only the morning or the afternoon

  • : in case that day is a public holiday, you will get its official name here (as listed in other endpoints), up to 200 characters.For example, "Juneteenth National Independence Day"

  • : in case that day is a public holiday, you will get its short and more casual name here, up to 30 characters.For example, "Juneteenth"

  • : 0 if's not a weekend day / 1 if it is a weekend day / 0.5 if you defined an half weekend day through a custom configuration

  • : 0 if you did not define any custom date on that day / 1 if you define a custom date on that day / 0.5 if you define an half custom date on that day

  • : In case you defined a custom date through a custom configuration, you get the label you defined here. For example "My firm is closed"

  • : In case you defined a custom date, you get the color you choose here (orange, pink, blue, green, yellow or periodic). Colors can be used to organised your custom dates according to your own categories. "periodic" is the light blue color you get when you define a periodic custom date rule (for instance, "every second friday of the month is closed")


  • : amount of teleworking (days and hours)


  • : It is an integer, finely defining the type of a day, through a bit field:
  • 1 == weekend day
    2 == public holiday
    4 == custom date (vacation)
    8 == custom date (working)
    16 == school holidays
    32 == working day
    64 == custom date (working) (morning)
    128 == custom date (working) (afternoon)
    256 == custom date (vacation) (morning)
    512 == custom date (vacation) (afternoon)
    1024 == weekend (morning)
    2048 == weekend (afternoon)
    4096 == public holiday (morning)
    8192 == public holiday (afternoon)
    16384 == teleworking
    32768 == teleworking (morning)
    65536 == teleworking (afternoon)
    131072 == note
    262144 == note (morning)
    524288 == note (afternoon)
    For instance, a public holiday falling on a week end will have a type equal to 3 (1 + 2), or a custom working day over a weekend will have a type equal to 9 (1 + 8)
  • : It's a comment helping you understand the type value.


  • Each request to get_info_day will remove one day from your monthly quota.


    Now let's look at a possible use case:

    « A cultural establishment located in New York is opened to public from tuesday to sunday from 11:00 to 18:00.
    It remains open on every federal public holidays except on Thanksgiving Day and Christmas Day.
    Every first saturday of the month, it stays open until 23:00.
    Each year, there is an annual closure for maintenance, usualy in august but the dates can change every year and needs to be configured easily.
    The establishment has a website, it would be nice if it could give the opening hours of the day. »


    All that can be implemented in a few minutes with the working days API:
  • Go to workingdays.us sign up or sign in using the any email (all this process can be tested over the year 2013 without an active subscription from the API TEST TOOL)

  • Go to the setup screen and define your weekend days, and choose your public holidays:



  • From the setup screen and customize the default week time schedule:



  • From the setup screen, open the "Custom dates" panel -> "Periodic dates" sub panel and define your custom date rule (they will appear in a light blue on the calendar views):



  • From any calendar view, click and drag the mouse to define your annual closures periods (you can choose a color, to help you define you own categories : for example orange for inventory closure, yellow for exceptional closures due to the pandemic, and so on..)



  • Copy the current profile's id:



  • Now our calendar is fully configured.
    The webmaster of the establishment just need to implement this request every morning (typically through a cron) to display the opening hours of the establishment:

    Get detailed period information


    Endpoint /get_array_info_day


    Use this command, to retreive the detailed information, day by day, over a given period.
    You will receive an array of "days", each "day" being the JSON object defined in the previous endpoint /get_info_day

    Arguments

    Name Description

    country_code

    Required
    The ISO country code (2 letters).
    See the list of countries
    For instance, if you want to take into account the french calendar, send country_code=FR

    start_date

    Required
    The start date of the period to be analysed (YYYY-MM-DD)

    end_date

    Required
    The end date of the period to be analysed (YYYY-MM-DD)

    configuration

    Optional
    The name of the regional preset configuration. See the list of configurations

    holiday_language

    Optional
    Specifies the language in which the names of public holidays are presented (ISO 639-1, 2 letters code).
    This optional parameter is beneficial when querying a country with multiple official languages. Refer to the list of supported languages for more details.
    If this parameter is not specified, the default language used will be the primary official language of the queried country.

    profile_id

    Optional
    The ID of a customized calendar (6 caracters).
    See this example.

    Here is an example URL:
    And here is the correponding response:



    And here is the definition of each field of this JSON response:

  • : the date (YYYY-MM-DD)

  • : 0 if's not a working day / 1 if it is a working day / 0.5 in case you defined an half open day through a custom configuration

  • : the number of working hours in this day (a float between 0 and 24)

  • : the wages earned during this day this day (a float). By default, this is equal to the number of work hours x 20, but it can be define more finely through a custom configuration

  • : the start time of the working morning in a 24 hours format with leading zeros (for instance 08:00). If that morning is not worked, the field is empty.

  • : the end time of the working morning in a 24 hours format with leading zeros (for instance 12:00). If that morning is not worked, the field is empty.

  • : the start time of the working afternoon in a 24 hours format with leading zeros (for instance 14:00). If that afternoon is not worked, the field is empty.

  • : the end time of the working afternoon in a 24 hours format with leading zeros (for instance 18:00). If that afternoon is not worked, the field is empty.

  • : 0 if's not a public holiday / 1 if it is a public holiday / 0.5 if is a public holiday only the morning or the afternoon

  • : in case that day is a public holiday, you will get its official name here (as listed in other endpoints), up to 200 characters.For example, "Juneteenth National Independence Day"

  • : in case that day is a public holiday, you will get its short and more casual name here, up to 30 characters.For example, "Juneteenth"

  • : 0 if's not a weekend day / 1 if it is a weekend day / 0.5 if you defined an half weekend day through a custom configuration

  • : 0 if you did not define any custom date on that day / 1 if you define a custom date on that day / 0.5 if you define an half custom date on that day

  • : In case you defined a custom date through a custom configuration, you get the label you defined here. For example "My firm is closed"

  • : In case you defined a custom date, you get the color you choose here (orange, pink, blue, green, yellow or periodic). Colors can be used to organised your custom dates according to your own categories. "periodic" is the light blue color you get when you define a periodic custom date rule (for instance, "every second friday of the month is closed")

  • : Amount of teleworking during that day (days & hours)

  • : A bit field, defining the type of the day. See endpoint /get_info_day

  • : A comment helping you decode the type value. See endpoint /get_info_day



  • Each request to get_array_info_day will remove the length of the period in days from your monthly quota.




    Let's look at a simple PHP code exemple:

    Stock exchange calendars

    We do cover the following stock exchanges:

    Europe
  • London Stock Exchange
  • Paris, Amsterdam, Brussels, Lisbon, Madrid, Milan
  • Börse Frankfurt
  • Börse Zürich

  • America
  • New York Stock Exchange
  • Toronto Stock Exchange

  • Pacific
  • Australian Stock Exchange

  • When you query the API, the response's working days value correponds to the number of trading days.

    Note that in Paris, Amsterdam, Brussels, Lisbon, Madrid, Milan, Sydney, trading ceases at 14:00 on the 24th and 31th of december. Therefore, the API will count each of those days as 0.5 working day and 0.5 public holiday.

    What about hours of quotation?

    By default, it you omit the work_hours parameter, we apply the week hours schedule of the stock exchange, so the work_hours field in the response correponds to the number of hours of trading hours over the period.
    Let's have a look at an example:

    Suppose we want to know how many hours the market was open at Euronext on 2013-12-31:



    This script will output "Number of trading hours at Paris Euronext on 2013-12-31 : 5.083 h (5h05)"
    Indeed the market opens at 9:00 and closes at 14:05 on december 24th and 31th.

    If you want to visualize the week time schedule applied, you can go to the correponding working days website, in the setup screen, choose the "Bourse de Paris (Euronext)" preset configuation, under the "Work hours" tab-pane :


    Advanced parameters

    The endpoints /analyse, /add_working_days, /add_working_hours, /list_non_working_days, /get_info_day, /get_array_info_day, /add_profile support some advanced parameters (not documented above) that will allow you to define custom weekend days (if your weekendays are not saturdays and sundays) or custom work hours week template (if your working hours are not always 8:00 ->12:00, 14:00->18:00).
    Of course, all of this can be customized from the working days website in a friendly way and then queried using the profile_id parameter as seen in this section, but being able to provide them programmatically will allow you to perfom batch analytics calculation and profile overloading (we will explain this with an example below).

    First let's see those parameters definition:
    Name Description

    weekend

    Optional
    Your weekend structure. Sunday-Monday-Tuesday-Wednesday-Thursday-Friday-Saturday.
    1: weekend day, 2: half weekend day (morning only), 3 half weekend day (afternoon only), 0: day of week
    Default value is 1000001 (weekend days on saturdays, sundays) except for Israel (weekend days on fridays, saturdays).
    If the weekend for you is sunday and monday, you can send: 1100000
    If the weekend is saturday afternoon and sunday: 1000003

    Alternating week structure (up to 4 weeks) is also possible.

    start_template

    Optional
    The start date of an alternating week template (YYYY-MM-DD)
    If you define an alternating week template schedule, you have to tell which sunday the template is starting.

    week_times

    Optional
    Your week working schedule structure. This parameter is useful when computing work hours over a period.
    When used, this parameter overides the week_hours parameter.
    For each day of the week define when working morning starts and ends, and when working afternoon starts and ends.
    Sunday morning start*Sunday morning end*Sunday afternoon start*Sunday afternoon end*Monday morning start*
    Monday morning end*Monday afternoon start*Monday afternoon end*....
    *Saturday morning start*Saturday morning end*Saturday afternoon start*Saturday afternoon end*
    Defaut value is :
    08:00*12:00*14:00*18:00*08:00*12:00*14:00*18:00*08:00*12:00*14:00*18:00*08:00*12:00*14:00*18:00*
    08:00*12:00*14:00*18:00*08:00*12:00*14:00*18:00*08:00*12:00*14:00*18:00*
    (working mornings from 8:00 to 12:00, working afternoons from 14:00 to 18:00)
    Note that a working schedule for a weekend day is simply ignored.


    We invite you to use the API TEST TOOL to generate those 3 parameters in a easy way (click on the Show advanced parameters link).

    Let's see a few examples to make it clear:
    Suppose you want to get the number of working of days over the year having a 3 days weekend (fridays, saturdays, sundays):






    Suppose you want to get the number of working of days over the year having a 3 days weekend (fridays, saturdays, sundays) but only one week one of two (alternating weeks templates):






    Suppose you want to compute the number of working hours, but with a customized week hours structure:






    Now suppose, that your firm has custom annual closures and you defined all of them inside a custom profile (ABDDXS).
    You want to perform comparisons over this profile's basis. For example, how many working days would you get with a 2 days weekend, or a 3 days weekend corresponding to different workers contracts (but always same custom annual closures).
    You can overload the profile's definition providing those parameter at the same time as the profile_id parameter (the weekend parameter is overloading the weekend definition of the custom profile)


    or

    Hours and Daylight saving time (DST)

    When you analyse a period, the response also includes the number of hours over the period (days -> hours).
    Note that is not so simple, to accurately give the number of hours between two dates & times.
    For example, in Europe, between saturday, march 26th, 2022 at 5pm and sunday, march 27th at 5pm there are not 24 hours but only 23 because of the DST (one hour is lost at 2am).

    In North America, between saturday, november 5th 2022 at 5pm and sunday, november 6th 2022 at 5pm, there are 25 hours (one hour is gained during the night).
    Of course a full year, always have 365 * 24 hours (leap years 366 * 24).

    Our API takes into account the DST for each region covered.
    Some countries like China, Japan, Singapore, Russia, Colombia, Argentina do not change clock over the year.

    Know your quota


    Endpoint /quota


    Each API call consumes part of your monthly quota. The days removed from your quota after a query is equal to the lengh in days of the resulting period.
    When you send a request like "country_code=CA&command=analyse&start_date=2019-01-01&end_date=2019-12-31" , it will take off 365 days of your monthly quota because they are 365 days in the year 2019.
    When you send a request like "country_code=FR&command=add_working_days&start_date=2020-01-01&increment=100", it will take off 147 days of your monthly quota because the resulting period is 147 days long.


    Each API response contains the proprietary HTTP header 'consumed-quota' telling you the value of the quota consumed by the request.

    If you send a request and your quota is exceeded, you will receive a 403 error code with a specific message.

    The monthly quota is reset at the end of each month at midgnight UTC+1.
    During the month, you will receive an automatic email alert when you reach 80% of your quota, and when you reach 100% of your quota.

    At any time, you can know your quota through the API, querying the /quota endpoint. It will return the state of your plan (1:active, 2:cancelled, -2: unknown key), your current quota (days left to be analysed within this month) and the quota that will be available the next month.

    (A request on this endpoint does not consume any of your quota.)

    Arguments

    Name Description

    key

    Required
    Your personal API key (passed as GET parameter or HTTP header)


    The URL

    https://api.workingdays.org/1.3/quota?key=MYPERSONALKEY


    and the service is going to reply with a JSON response like that:

    Securing your code

    Before you go live, you want to make sure your code is robust.

    First, adding a changing HTTP parameter can be a good hack to avoid all the caches mechanism that could be met on the road (keep in mind we are regularly updating our public holidays database).

    Next handling exception properly is a key thing to do.
    You need to check the HTTP STATUS code of the web service response.
    If you get an HTTP 200, all is ok.
    If you get a 400, something is wrong with your request, you should be checking your input parameters.
    If you get a 401, it means your are sending an invalid key parameter.
    If you get a 403, your monthly quota has been exceeded: you should implement some alert for yourself and stop sending request.
    In any other case, you might want to implement one or several retries because networks failures happen.

    After you get an HTTP 200, you need to parse the response string (decode the JSON). This operation can fail too for an unknown reason: we suggest handling and logging any exception there also.

    PHP example


    Open API documentation


    Proposing an Open API documentation comes with an effort on our part to offering a standard API (OAS3) that can be discovered and interfaced easily with usual developer tools.
  • Here is the online Open API documentation
  • Here is the Swagger definiton file to be downloaded
  • Release note v1.3

    The v1.3 intends to be faster, more simple, more standard, and open up new possibilities.
    If you are a v1.2 user, note that the v1.2 continues to be fully maintained although we will encourage a migration toward the v1.3.
    Let's get through the changelog against the v1.2:

    New endpoints

  • /add_profile

  • /delete_profile

  • /define_custom_period

  • /delete_custom_period

  • Thoses endpoints were asked by our customers in order to be able to create new profiles and custom period programmatically, opening new use cases involving (for instance interfacing human ressources repository with our working days calendars in order to perform analytics computations).

    Changes in the responses schema

  • We removed the root node "result".
  • The numbers in the response where strings (containing floats) in the v1.2, we decided to make them now numbers so the response's schema is more strongly typed.
  • The /analyse endpoint response now includes an array of public holidays which is more standard for parsing than a list of key, value.
  • The response schema of the /list_non_working_days has evolved in order to describe more precisely the non working days in a standard way.

  • All the schemas are fully documentated in the swagger file.

    Removed endpoints

  • /add_public_holidays : was abandoned because it was not needed by any of our customer.

  • /add_weekend_days : was abandoned because it was not needed by any of our customer.

  • /address_to_configuration : was abandoned because it was not needed by any of our customer.

  • If you still need any of those endpoint, just let us now and we will add it righ away.

    use_custom_configuration parameter removed

    We made it more simple to query a customized calendar.
    Configure it through the working days website, note its secret "profile_id", and you are ready to query by simply adding this GET parameter profile_id=..
    There is no need anymore to log in on the working days website with the same email than the API subcriber's one, and no need for the use_custom_configuration parameter anymore.

    Key as an HTTP header

    The key should now be passed as an HTTP header, which is more standard.
    We still accept the key as a GET parameter (like in the v1.2).

    Change in HTTP error codes

  • An invalid credential request was returning a 400 error, it is now returning a 401 error which is more standard
  • A quota exceeded request was returning a 400 error, it is now returning a 403 status with a specific message which is more standard