National Joint Council's (unofficial) REST API

This project aims to provie a REST API for the meals and incidentals allowances provided by the National Joint Council (NJC) for travel. This REST endpoint gives users the ability to query the rates programmatically from Excel or other software, for the purpose of cost estimates.

Features:

  • free, thanks to Vercel!
  • rates are based on the most recent tables from the official NJC website, refreshed at every request
  • overrides the country currency with the allowance-specific currency if one is given (e.g. Azores' currency is euros; but incidentals are listed as CAD 17.30)
  • correctly handles countries with a single rate, regardless of city requested
  • retrieves the rate for city "Other", if available, when requesting an unlisted city
  • features case and locale insentive country/city matching (e.g. bogota works for Bogotá)
  • supports partial country name matching - e.g. Aruba works for Aruba (Kingdom of the Netherlands)
  • supports country names expressed in ISO-3166 digraphs and trigraphs (e.g. UK, CA, CAN, GBR) (using the geonames.org country data set)
  • supports json or csv formatted output
  • merges rates from both Appendix C (Canada and continental United States) and Appendix D (international) tables
  • leverages javascript promises to perform GET requests and fetch appendices C & D simultaneously, to improve performance
  • for Canada and the USA, determines the city's region (territory/state) to return specific regional rates (using the geonames.org API) (Hawaii, Yukon, Northwest Territories, Nunavut, Alaska)
  • overcomes the unterminated <strong> tags in the appendix D HTML source
  • limitation: provides only commercial daily rates for days 1-30 (rates for longer stays can be computed using percentages)


Note: please always verify the rates against the official National Joint Council rate tables.

API examples with sample output (truncated)

  • Full list in json format https://njc-rest.ca/api/allowances
    { "results" : [
            {"country":"Afghanistan","currency":"CAD","city":"Kabul","breakfast":"*","lunch":"*","dinner":"*","meals":"*","incidentals":"17.30","total":"*"},
            {"country":"Afghanistan","currency":"CAD","city":"Kandahar","breakfast":"*","lunch":"*","dinner":"*","meals":"*","incidentals":"17.30","total":"*"},
            {"country":"Afghanistan","currency":"CAD","city":"Other","breakfast":"*","lunch":"*","dinner":"*","meals":"*","incidentals":"17.30","total":"*"},
            {"country":"Albania","currency":"EUR","city":"Tirana","breakfast":"9.75","lunch":"15.85","dinner":"22.50","meals":"48.10","incidentals":"15.39","total":"63.49"},
            {"country":"Albania","currency":"EUR","city":"Other","breakfast":"7.80","lunch":"12.68","dinner":"18.00","meals":"38.48","incidentals":"12.31","total":"50.79"},
            {"country":"Algeria","currency":"CAD","city":"Algiers","breakfast":"28.45","lunch":"52.30","dinner":"71.00","meals":"151.75","incidentals":"48.56","total":"200.31"},
            {"country":"Algeria","currency":"CAD","city":"Other","breakfast":"22.76","lunch":"41.84","dinner":"56.80","meals":"121.40","incidentals":"38.85","total":"160.25"},
            ...
    ] }
  • Full list in csv format https://njc-rest.ca/api/allowances?format=csv
    
            country,currency,city,breakfast,lunch,dinner,meals,incidentals,total
            Afghanistan,CAD,Kabul,*,*,*,*,17.30,*
            Afghanistan,CAD,Kandahar,*,*,*,*,17.30,*
            Afghanistan,CAD,Other,*,*,*,*,17.30,*
            Albania,EUR,Tirana,9.75,15.85,22.50,48.10,15.39,63.49
            Albania,EUR,Other,7.80,12.68,18.00,38.48,12.31,50.79
            Algeria,CAD,Algiers,28.45,52.30,71.00,151.75,48.56,200.31
            Algeria,CAD,Other,22.76,41.84,56.80,121.40,38.85,160.25
            Andorra,CAD,Andorra la Vella,*,*,*,*,17.30,*
            Angola,CAD,Luanda,*,59.20,70.05,129.25,51.70,180.95
            ...
            
  • Country listing https://njc-rest.ca/api/allowances?country=Australia
    { "results" : [
            {"country":"Australia","currency":"AUD","city":"Adelaide","breakfast":"32.15","lunch":"55.75","dinner":"79.15","meals":"167.05","incidentals":"53.46","total":"220.51"},
            {"country":"Australia","currency":"AUD","city":"Brisbane","breakfast":"34.50","lunch":"60.00","dinner":"88.15","meals":"182.65","incidentals":"58.45","total":"241.10"},
            {"country":"Australia","currency":"AUD","city":"Canberra","breakfast":"28.60","lunch":"55.40","dinner":"69.55","meals":"153.55","incidentals":"49.14","total":"202.69"},
            {"country":"Australia","currency":"AUD","city":"Hobart","breakfast":"27.00","lunch":"54.00","dinner":"74.25","meals":"155.25","incidentals":"49.68","total":"204.93"},
            {"country":"Australia","currency":"AUD","city":"Melbourne","breakfast":"32.00","lunch":"61.15","dinner":"85.65","meals":"178.80","incidentals":"57.22","total":"236.02"},
            {"country":"Australia","currency":"AUD","city":"Perth","breakfast":"33.25","lunch":"59.70","dinner":"82.10","meals":"175.05","incidentals":"56.02","total":"231.07"},
            {"country":"Australia","currency":"AUD","city":"Sydney","breakfast":"35.00","lunch":"66.45","dinner":"90.80","meals":"192.25","incidentals":"61.52","total":"253.77"},
            {"country":"Australia","currency":"AUD","city":"Other","breakfast":"22.88","lunch":"44.32","dinner":"55.64","meals":"122.84","incidentals":"39.31","total":"162.15"}
    ] } 
  • Specific city https://njc-rest.ca/api/allowances?city=bogota
    (only works for cities specifically listed in Appendix D)
    { "results" : [
            {"country":"Colombia","currency":"COP","city":"Bogotá","breakfast":"40,700.00","lunch":"71,300.00","dinner":"93,700.00","meals":"205,700.00","incidentals":"65,824.00","total":"271,524.00"}
    ] }
  • Country with single rate; when an unlisted city requested https://njc-rest.ca/api/allowances?country=Armenia&city=Talin
    { "results" : [
            {"country":"Armenia","currency":"USD","city":"Yerevan","breakfast":"15.65","lunch":"21.15","dinner":"32.15","meals":"68.95","incidentals":"22.06","total":"91.01"}
    ] } 
  • Country with "Other" rates, with an unlisted city name https://njc-rest.ca/api/allowances?country=Australia&city=Cairn
    { "results" :[
            {"country":"Australia","currency":"AUD","city":"Other","breakfast":"22.88","lunch":"44.32","dinner":"55.64","meals":"122.84","incidentals":"39.31","total":"162.15"}
    ] }
  • Canada (using ISO-3166 digraph) with a city matching a territory with specific rate https://njc-rest.ca/api/allowances?country=CA&city=Yellowknife
    { "results" : [
    {"country":"Canada (Northwest Territories)","currency":"CAD","city":"Other","breakfast":"24.85","lunch":"30.15","dinner":"64.50","meals":"119.50","incidentals":"17.30","total":"136.80"}
    ] }
  • USA (using ISO-3166 trigraph) with a city matching a state with specific rate https://njc-rest.ca/api/allowances?country=usa&city=anchorage
    { "results" : [
    {"country":"United States of America (Alaska)","currency":"USD","city":"Other","breakfast":"23.05","lunch":"21.15","dinner":"61.00","meals":"105.20","incidentals":"17.30","total":"122.50"}
    ] }

Deployed with Gatsby on Vercel!

with the help of react.js, cheerio.js, axios and geonames.org