Getting Started

Making calls to the API

Most applications will use a wrapper library in the language of your choice, but first let's get familiar with the underlying API HTTP methods first. There's no easier way to do this than through cURL.

Let's start by testing our setup. Open up a command prompt and enter the following command. Remember to include your user key.

curl https://api.laminardata.aero/v1/airlines?{user_key}

<gml:FeatureCollection>
  <gml:featureMember xlink:href="https://api.laminardata.aero/v1/airlines/AAF" xlink:title="AAF"/>
  <gml:featureMember xlink:href="https://api.laminardata.aero/v1/airlines/AAL" xlink:title="AAL"/>
  <gml:featureMember xlink:href="https://api.laminardata.aero/v1/airlines/AAR" xlink:title="AAR"/>
  ...
</gml:FeatureCollection>

This makes a call to the Airlines List API and returns what looks like XML. Let's include the -i flag to include the headers:

curl -i https://api.laminardata.aero/v1/airlines?{user_key}

HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin,Content-Type,Accept
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, must-revalidate
Content-Type: application/xml
Date: Thu, 24 Mar 2016 13:53:53 GMT
ETag: "9a16f489b919d91b9153ed7b34f7abe1"
Expires: 0
Last-Modified: Wed, 23 Mar 2016 14:38:46 GMT
Pragma: no-cache
Content-Length: 25890
Connection: keep-alive

There are a few interesting bits in the response headers. As expected, the Content-Type is application/xml. The Access-Control-Allow-Methods allows GET and OPTIONS requests, meaning that the API is read only. And the Last-Modified header indicates how old the data is. These headers vary between the APIs so be sure to have a look before using each one.

Navigating Laminar

In this example we are going to navigate through the Laminar Data APIs in order to find TAFs (Terminal Aerodrome Forecast) from Southampton Airport. Laminar Data APIs follow RESTful principles, allowing for accessible and intuitive navigation across the data.

Jumping ahead for a second, we can see that if we want to get a TAF for a specific aerodrome we need to make a call to the TAFs by Aerodrome API. For the call to be successful we need a user_key (register here if you do not have one yet), and the ICAO code for the aerodrome we want data for. But how do we find this if we don't know it already?

Our starting point is to make a call to the ICAO Prefix List API:

https://api.laminardata.aero/v1/icao-prefixes?user_key={user_key}

The results of the call will look something like this (along with a lot of XML namespacing which has been left out for conciseness):

<gml:FeatureCollection>
    <gml:featureMember xlink:href="/v1/icao-prefixes/A" xlink:title="A"/>
    <gml:featureMember xlink:href="/v1/icao-prefixes/B" xlink:title="B"/>
    ...
    <gml:featureMember xlink:href="/v1/icao-prefixes/E" xlink:title="E"/>
    ...
</gml:FeatureCollection>

ICAO Prefixes represent large airspaces, often spanning numerous countries. There are 23 such airspaces, each assigned a single letter. We know that ICAO Prefix E represents Western Europe, so to drill down into the data further we can follow the xlink:href to the ICAO Prefix Detail API.

https://api.laminardata.aero/v1/icao-prefixes/E?user_key={user_key}

This yields a response like this and provides further detail on ICAO Prefix E:

<ld:ICAOPrefix>
    <gml:identifier codeSpace="http://api.laminardata.aero">/v1/icao-prefixes/E</gml:identifier>
    <gml:name>E</gml:name>
    <ld:firs xlink:href="https://api.laminardata.aero/v1/icao-prefixes/E/firs"/>
    <ld:aerodromes xlink:href="https://api.laminardata.aero/v1/icao-prefixes/E/aerodromes"/>
</ld:ICAOPrefix>

From the response we can see within Prefix E, data is available for FIRs and aerodromes. Since it is TAFs for Southampton Airport we are interested in, it makes sense to follow the aerodromes xlink:href. We therefore make a further call to the Aerodromes by ICAO Prefix API:

https://api.laminardata.aero/v1/icao-prefixes/E/aerodromes?user_key=user_key

The response contains a number of featureMembers, each representing an aerodrome within ICAO Prefix E. The featureMember representing Southampton Airport looks like this:

<gml:featureMember>
    <aixm:AirportHeliport gml:id="ID_36770_1459303491760_38220">
        <gml:identifier codeSpace="urn:uuid:">05bdbc20-b0f2-405e-a170-9026619b01d2</gml:identifier>
        <aixm:timeSlice>
            <aixm:AirportHeliportTimeSlice gml:id="ID_36770_1459303491760_38221">
                <gml:validTime>
                    <gml:TimeInstant gml:id="LOCAL_ID_1402">2016-03-30T09:57:28</gml:TimeInstant>
                </gml:validTime>
                <aixm:interpretation>SNAPSHOT</aixm:interpretation>
                <aixm:name>SOUTHAMPTON</aixm:name>
                <aixm:locationIndicatorICAO>EGHI</aixm:locationIndicatorICAO>
                <aixm:designatorIATA>SOU</aixm:designatorIATA>
                <aixm:ARP>
                    <aixm:ElevatedPoint srsName="urn:ogc:def:crs:EPSG::4326" gml:id="ID_36770_1459303491760_38225">
                        <gml:pos>50.950279235839844 -1.3566666841506958</gml:pos>
                        <aixm:elevation uom="FT">44</aixm:elevation>
                    </aixm:ElevatedPoint>
                </aixm:ARP>
            </aixm:AirportHeliportTimeSlice>
        </aixm:timeSlice>
    </aixm:AirportHeliport>
</gml:featureMember>

Remember from the beginning, we are looking for TAFs for Southampton Airport. The response from the Aerodromes by ICAO Prefix API tells us that the ICAO Code for Southampton Airport is EGHI:

<aixm:locationIndicatorICAO>EGHI</aixm:locationIndicatorICAO>

We can then use this information to make the final call to the TAFs by Aerodrome API, returning data only for Southampton Airport:

https://api.laminardata.aero/v1/aerodromes/EGHI/taf?user_key=user_key

Of course if you know the aerodrome ICAO code already you could just make the call.

There are many ways to use our data, whether it is exploratory, or whether you already know precisely what you're looking for. The diagram here shows how our APIs link together.