Já search API

The Já search API takes a query and returns a series of listing from Já’s database of persons, companies, and places that match the query.

Request

Requests are made over HTTPS using the GET method with URL query parameters. Responses are JSON objects.

Query parameters

Search query

The q parameter names the thing to search for. Loosely speaking, for a listing to appear in the search results for a given query, each word of the query must appear in some form in some field of the listing.

Fields searched

The fields containing the following information are searched by default:

  • Name
  • Address (street name and house number)
  • Postal code
  • Neighborhood
  • Municipality
  • Country
  • Occupation
  • Phone number
  • National id number (kennitala)
  • VAT number
  • Website address
  • Email address
  • Keywords
  • Tags
  • Yellow pages classification

So, in addition to obvious queries like a person’s full name or phone number, you can combine words from any of the above to make queries like:

Haukur forritari Grettisgötu

The keywords, tags, and classification fields enable searching for types of things rather than a specific thing.

Keywords

The keywords are chosen by our clients for their commercial listings. They can be anything our client imagines their potential customers would search for but mainly the names and categories of products and services. Some examples:

hellur
hellulagnir
fjármálaráðgjöf
consulting
hankook
dekk
crossfit
kleinur
Tags

Tags also name products and services, but they are curated by Já’s agents. At the time of this writing, tags are relatively new and only cover isolated market segments, for example restaurants.

Yellow pages classification

This is the continuation of the categorization from the yellow pages of the physical phonebook, though the book is no longer published.

Neighborhood

This is a curated grouping of locations into neighborhoods like “vesturbær” and “skeifan”:

hádegismatur skeifunni

See also Filtering by named region.

Equivalent forms

A query word is considered to appear in a listing field not only when one of the field’s word is precisely equal, character-by-character, to the query word, but also if they are equal after these transformations:

  • Lower-casing
  • Inflection (Grettisgata→Grettisgötu for instance)
  • Transliteration of Icelandic and other weird characters into ASCII (á→a, ð→d, þ→th, ë→e etc.)
  • Mapping of ‘&’, ‘og’, and ‘and’ to the same form

Quoting

One or more consecutive query words may be wrapped in double quotation marks to require the quoted words to appear in the same field in the given order and inflection:

"Reykjavíkur"
"Sendibílastöð Reykjavíkur"

Operators

Parentheses and operators are available:

(Jón OR Gunna) AND Dæmisstræti

The operators are only recognized as such in the upper case. They also come in Icelandic: EÐA and OG.

It’s never necessary to use the AND operator. It’s implied whenever two query parts appear without an OR between them.

Wildcards

Wildcards are available. A question mark stands for a single letter, an asterisk for zero or more letters. They can appear on either edge of a word or within it:

Sigm* Sig*son *gerði

An asterisk that is not attached to a word is not useful. For instance, the query “Haukur * Hreinsson” might be imagined to return people who have the first and last names mentioned and additionally have a middle name but is really just a redundant way of saying “Haukur Hreinsson”.

Filtering

The filter parameter takes queries of the same kind as the q parameter and additionally accepts the special token open. See Filtering by opening hours.

Multiple filters can be passed into a single filter parameter by joining them with commas.

The search results will be as if the filters given had been joined to the q parameter with the AND operator, except that open has no special significance in the q parameter:

curl "https://api.ja.is/search/v6/?q=matur&filter=open,region:suðurland" -H Authorization:${JA_SEARCH_API_KEY}

Filtering by coordinates

Use the north, west, east, and south query parameters to filter by area. They take latitude and longitude as signed floating point numbers:

curl "https://api.ja.is/search/v6/?q=matur&west=-21.926686&east=-21.838508&south=64.123039&north=64.147390" -H Authorization:${JA_SEARCH_API_KEY}

Filtering by named region

Filter on the svæði or region field to limit the results to listings in a given part of the country like East Iceland or the capital region. The exact names available (in Icelandic only) are as follows:

  • Reykjanes
  • Reykjanesbær
  • Vesturland
  • Snæfellsbær
  • Vestfirðir
  • Ísafjarðarbær
  • Vesturbyggð
  • Norðurland
  • NorðurlandE
  • NorðurlandV
  • Norðurþing
  • Fjallabyggð
  • Austurland
  • Fjarðarbyggð
  • Suðurland
  • Árborg
  • Höfuðborgarsvæðið
  • Reykjavík
  • Mosfellsbær
  • Kópavogur
  • Hafnarfjörður
curl "https://api.ja.is/search/v6/?q=matur&filter=svæði:suðurland" -H Authorization:${JA_SEARCH_API_KEY}

This functionality is based on postal codes so listings without postal codes will not appear in any of these regions.

Filtering by opening hours

To limit the results to companies that have their opening hours registered and are open at a given time, use the filter and time query parameters:

curl "https://api.ja.is/search/v6/?q=matur&filter=open&time=2017-02-21T18:40" -H Authorization:${JA_SEARCH_API_KEY}

You can also skip the time parameter. It defaults to the current time. The time is given in RFC 3339 format with UTC (+0000) as the default time zone.

Times more than a week in the future may yield incorrect results.

Ordering

By default, people are ordered by first name, last name, middle name, occupation, and address. Note that middle names are taken into account after last names.

We deviate from the above to ensure that, for instance, a query for Bob returns a Bob ahead of a Billy Bob with the same last name.

TODO: Order in businesses, map scope

Response field restriction

Use the fields parameter to reduce the set of fields on result items. This saves bandwidth and makes responses nicer to look at during debugging. It takes a comma-separated list of field names. Only the fields mentioned will be returned.

    curl "https://api.ja.is/search/v6/?q=dekk&fields=name,address" -H Authorization:${JA_SEARCH_API_KEY}

Versioning

The current version of the API is 6. The API uses semantic versioning, so given a version number MAJOR.MINOR.PATCH we will increment the:

  • MAJOR version when we make incompatible API changes;
  • MINOR version when we add functionality in a backwards-compatible manner; and
  • PATCH version when we make backwards-compatible bug fixes.

A change in the MAJOR version will mean a change in the API’s base URL — e.g. from https://api.ja.is/search/v6/ to https://api.ja.is/search/v7/. We list all changes meriting an update to the version number in the Changelog.

Authentication

To authenticate your account when making a request to the API, include your secret key in the Authorization header.

If you make an API request without authentication or if you send an invalid secret key, you will a receive a response with a 400 Bad Request status code.

Your key carries privileges, so be sure to keep it secret. Do not share your secret key in publicly-accessible areas such as client-side code.

You must make all API requests over HTTPS.

Cross-origin resource sharing

You should not share your secret key in publicly-accessible areas such as client-side code. For this reason the API does not support CORS requests by default — i.e. no Access-Control-Allow-Origin header is sent with a response.

If you do wish to make browser-based requests to the API within a private environment (an intranet, for example), contact us and we will include a set origin in the Access-Control-Allow-Origin response header that is linked to your API key.

Response

Errors and status codes

The API responds with standard HTTP status codes to indicate the success or failure of a request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that failed due to the information provided (e.g. a required parameter was omitted), and codes in the 5xx range indicate an error with Já’s servers.

The status codes you may encounter are:

  • 200 OK: both request and response worked as expected
  • 400 Bad Request: the request was unacceptable, likely due to a missing parameter or an invalid parameter value
  • 401 Unauthorized: you failed to provide a valid API key, or you do not have permission to access the resource you requested
  • 404 Not Found: the requested resource doesn’t exist
  • 500 Internal Server Error: Something went wrong at Já’s end

When the API returns a 4xx or 5xx status code the response body will be a JSON object describing the error. For example:

{
  "error": "\"null\" is not a valid int value for parameter start",
}

Search results

The overall shape of the response differs based on the scope of the search. In the more fundamental case of scope=people or scope=businesses, the response looks like this:

{
   "items": [],
   "meta": {}
}

With scope=fast, two such responses are combined:

{
    "people": {
        "items": [],
        "meta": {}
    },
    "businesses": {
        "items": [],
        "meta": {}
    }
}

The result item

A result item can represent entities of several types:

  • a person
  • an organization
  • an address
  • a named place

The set of fields on the item is the same in every case, but many of them only apply to some of the types and take on a null value in other cases.

Even in items of the appropriate type, most fields can be null under some circumstances.

There are many fields and we will not describe each one in detail. Some are collected into logical groups and described in the following sections. All can be seen in the Listing examples section.

Basic fields

Here we bring together the quintessential fields of a phonebook listing so they can be seen at a glance:

{
    "name": "Haukur Hreinsson",
    "occupation": "forritari",
    "address": "Grettisgötu 45",
    "postal_station": "101 Reykjavík",
    "phone": { ... },
    "additional_phones": [],
    "geo": {
        "coordinates": { ... },
        ...
    },
}

The address field is a combination of the street, house_number and house_number_supplement fields. There’s also an address_nominative field.

The postal_station field is a combination of the postal_code and municipality fields. There’s also a postal_station_nominative field.

Phone object

An object representing a telephone number:

"phone": {
    "banned": true,
    "number": "8600369",
    "pretty": "860 0369",
    "type": "gsm"
}
  • banned
    (boolean): If true, the owner does not want to be contacted by parties that conduct direct marketing. See Lög um fjarskipti, number 81 from 2003, article 45, paragraph 2.
  • number
    (string): The plain phone number. May be fully qualified with a leading plus symbol and country code. If not, it’s an Icelandic phone number. Note that some phone numbers are short (three or four digits). Dialling those preceded by +354 (Iceland’s international calling code) won’t work
  • pretty
    (string): The phone numer with some whitespace to make it easier to read
  • mobile
    (boolean): The phone number is assigned to a mobile phone

Listing examples

An example of an individual’s result item:

{
    "additional_phones": [],
    "address": "Grettisgötu 45",
    "address_nominative": "Grettisgata 45",
    "booking_link": null,
    "branch_title": {
        "en": {
            "plural": "Other entries",
            "singular": "Another entry"
        },
        "is": {
            "plural": "Aðrar skráningar",
            "singular": "Önnur skráning"
        }
    },
    "card_logo_url": null,
    "cluster_key": "1254436",
    "cluster_rating_count": 0,
    "cluster_rating_mean": 0,
    "cluster_rating_score": 0,
    "cluster_rating_split": null,
    "common_id": "1254436",
    "company_registry_name": null,
    "company_type": [],
    "country": null,
    "email": null,
    "fax": null,
    "first_name": "Haukur",
    "geo": {
        "coordinates": {
            "lat": 64.143786,
            "lon": -21.92265
        },
        "coordinates_isn93": {
            "x": 357772,
            "y": 407837
        },
        "ja360_links": {
            "interactive": "https://ja.is/kort/?d=phashid%3AOwXnv&x=357772&y=407837&z=8&ja360=1",
            "static": "https://storage-2.ja.is/preview/normal/preview_1254436.jpg",
            "static_unblurred": "https://storage-2.ja.is/preview/normal/preview_1254436.jpg"
        },
        "ja360_parameters": null,
        "ja360_preview_blurred": false,
        "map_links": {
            "interactive": "https://ja.is/kort/?d=phashid%3AOwXnv&x=357772&y=407837&z=8&type=map",
            "static": "https://ja.is/kort/static/?x=357772&y=407837&z=7"
        }
    },
    "has_branches": false,
    "hashid": "OwXnv",
    "hide_ssn": false,
    "hours": null,
    "hours_presentation": null,
    "house_number": 45,
    "house_number_supplement": "",
    "indexed_at": "2020-10-28 20:51:37",
    "is_branch": false,
    "is_open": null,
    "is_person": true,
    "is_primary": false,
    "last_name": "Hreinsson",
    "logo_url": null,
    "logo_url_high": null,
    "logo_url_low": null,
    "logo_url_medium": null,
    "map_img_url": null,
    "match_in_oskrad": false,
    "middle_name": "",
    "municipality": "Reykjavík",
    "name": "Haukur Hreinsson",
    "national_id_number": "...",
    "occupation": "forritari",
    "phone": {
        "banned": true,
        "mobile": true,
        "number": "8600369",
        "pretty": "860 0369"
    },
    "phonebook_id_number": "1254436",
    "postal_code": 101,
    "postal_station": "101 Reykjavík",
    "postal_station_nominative": "101 Reykjavík",
    "rating_comment_id": null,
    "rating_count": 0,
    "rating_display": false,
    "rating_mean": 0,
    "rating_score": 0,
    "rating_split": null,
    "see_also": {
        "skra": "https://api.ja.is/skra/v1/kennitolur/...?redirect"
    },
    "slogan": null,
    "social": [],
    "solicitation_prohibited": true,
    "square_logo_url_large": null,
    "square_logo_url_small": null,
    "street": "Grettisgötu",
    "tags": null,
    "type": "person",
    "url": "",
    "url_pretty": "",
    "vat_number": null
}

An example of a business’s result item with null-valued fields left out:

{
    "additional_phones": [],
    "address": "Álfheimum 74",
    "address_nominative": "Álfheimar 74",
    "booking_link": null,
    "branch_title": {
        "en": {
            "plural": "Other entries",
            "singular": "Another entry"
        },
        "is": {
            "plural": "Aðrar skráningar",
            "singular": "Önnur skráning"
        }
    },
    "card_logo_url": null,
    "cluster_key": "ja",
    "cluster_rating_count": 0,
    "cluster_rating_mean": 0,
    "cluster_rating_score": 0,
    "cluster_rating_split": null,
    "common_id": "1349710",
    "company_registry_name": "Já hf.",
    "company_type": [
        "upplýsingaveita"
    ],
    "country": null,
    "email": "ja@ja.is",
    "fax": null,
    "first_name": "Já",
    "geo": {
        "coordinates": {
            "lat": 64.134421,
            "lon": -21.869281
        },
        "coordinates_isn93": {
            "x": 360320,
            "y": 406675
        },
        "ja360_links": {
            "interactive": "https://ja.is/kort/?d=hashid%3A0EXwo&x=360348&y=406651&z=8&ja360=1&ji=976256&jh=325&fov=90&vlookat=-12.8",
            "static": "https://storage-2.ja.is/preview/normal/preview_1349710.jpg",
            "static_unblurred": "https://storage-2.ja.is/preview/normal/preview_1349710.jpg"
        },
        "ja360_parameters": {
            "fov": 90,
            "heading": 325.4323,
            "image_id": 976256,
            "image_x": 360348,
            "image_y": 406651,
            "vlookat": -12.785471
        },
        "ja360_preview_blurred": false,
        "map_links": {
            "interactive": "https://ja.is/kort/?d=hashid%3A0EXwo&x=360320&y=406675&z=8&type=map",
            "static": "https://ja.is/kort/static/?x=360320&y=406675&z=7"
        }
    },
    "has_branches": false,
    "hashid": "0EXwo",
    "hide_ssn": false,
    "hours": "man-fos 09:00-17:00\n1. agu-3. agu 0",
    "hours_presentation": [
        [
            "mán-fös",
            "9-17",
            "current-closed"
        ]
    ],
    "house_number": 74,
    "house_number_supplement": "",
    "indexed_at": "2020-10-28 20:52:30",
    "is_branch": false,
    "is_open": false,
    "is_person": false,
    "is_primary": true,
    "last_name": "",
    "logo_url": "sala/logo/120x70/ja-logo-litid_3.png",
    "logo_url_high": "sala/logo/300x171/ja-logo-litid_3.png",
    "logo_url_low": "sala/logo/100x57/ja-logo-litid_3.png",
    "logo_url_medium": "sala/logo/200x114/ja-logo-litid_3.png",
    "map_img_url": null,
    "match_in_oskrad": false,
    "middle_name": "",
    "municipality": "Reykjavík",
    "name": "Já",
    "national_id_number": "4308050530",
    "occupation": "",
    "phone": {
        "banned": false,
        "mobile": false,
        "number": "5223200",
        "pretty": "522 3200"
    },
    "phonebook_id_number": "1349710",
    "postal_code": 104,
    "postal_station": "104 Reykjavík",
    "postal_station_nominative": "104 Reykjavík",
    "rating_comment_id": null,
    "rating_count": 0,
    "rating_display": false,
    "rating_mean": 0,
    "rating_score": 0,
    "rating_split": null,
    "see_also": {
        "skra": "https://api.ja.is/skra/v1/kennitolur/4308050530?redirect"
    },
    "slogan": null,
    "social": [
        {
            "account": "www.facebook.com/ja.er.svarid",
            "type": "FB"
        },
        {
            "account": "instagram.com/jaersvarid",
            "type": "IG"
        }
    ],
    "solicitation_prohibited": false,
    "square_logo_url_large": null,
    "square_logo_url_small": null,
    "street": "Álfheimum",
    "tags": [
        {
            "tags": [
                "upplýsingaveita"
            ],
            "type": "Tegund fyrirtækis"
        }
    ],
    "type": "business",
    "url": "",
    "url_pretty": "",
    "vat_number": "87491"
}

Changelog

2017-03-10

Initial release

2020-10-28

TODO spellcheck cluster=false cluster_by