shell javascript

Introduction

Welcome to the AirHub API! Our API powers the Business of Drones through the delivery of data and services to power and enrich your UAS applications.

The AirHub API is organized around REST. Our API has predictable resource-oriented URLs, accepts form-encoded or JSON request bodies, returns JSON-encoded responses and uses standard HTTP response codes, authentication, and verbs.

You can use the AirHub API in sandbox mode, which does not affect your live data or interact with production systems. The base URL you use to make requests determines whether the request is live mode or sandbox mode.

We have language examples in curl/Shell and JavaScript. You can view code examples in the dark area to the right, and switch the programming language with the tabs on the top right.

Request access to the API by sending an email to developers@airspacelink.com. We may wish to learn more about your use case before granting access.

Terms and Conditions

Non-commercial use of this API is governed by the Non-commercial AirHub for Business Terms & Conditions.

Support

Need help, or want to get in touch? You can contact support here.

Authentication

OAuth

To authorize, use this code:

# With shell, you can just pass the correct header with each request
curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'x-api-key: <your-subscription-key>' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=<your-client-id>' \
--data-urlencode 'client_secret=<your-client-secret>' \
--data-urlencode 'scope=airhub-api/<your-requested-scope> airhub-api/<second-scope>'
const params = {
  grant_type: "client_credentials",
  client_id: "<your-client-id>",
  client_secret: "<your-client-secret>",
  scope: "airhub-api/<your-requested-scope> airhub-api/<second-scope>",
};

const query = Object.keys(params)
  .map((key) => key + "=" + params[key])
  .join("&");

const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v1/oauth/token");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded", true);
xhr.setRequestHeader("x-api-key", "<your-subscription-key>", true);
xhr.send(query);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "status": 200,
  "message": "success",
  "data": {
    "accessToken": "xyz123",
    "expires": "2021-03-16T21:57:33.332Z",
    "scope": "airhub-api/advisory.read airhub-api/token.create"
  }
}

AirHub uses client credentials and an API key to authenticate and authorize requests. Successful authentication will return an Oauth2 accessToken. AirHub expects the accessToken and x-api-key to be included in all subsequent API requests.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/oauth/token

Required Headers

Parameter Description
Content-Type application/x-www-form-urlencoded
x-api-key <your-api-key>

Form Encoded Parameters

Parameter Description
grant_type client_credentials
client_id Client id supplied to you by Airspace Link
client_secret Client secret supplied to you by Airspace Link
scope See available Oauth Scopes

Scopes

In addition to the Client ID and Secret, you must also supply one or many oauth scopes. If you're unfamiliar with scopes, you can think of them as bundles of related API endpoints that are authorized for access by your client application. Each scope should be prefixed with airhub-api/, for example, airhub-api/hazar.read. Multiple scopes may be requested by separating each scope by a space.

Available Scopes

Scope Description
advisory.read Grants read access to our available advisories. This includes local and federal flight advisories.
advisory.create Grants create access to our available advisories. This only includes local flight advisories.
advisory.update Grants update access to our available advisories. This only includes local flight advisories.
advisory.delete Grants delete access to our available advisories. This only includes local flight advisories.
aviation.read Grants read access to aviation facility map data.
hazar.read hazar is short for "Hazards and Risks". Grants read access to our hazar data.
operation.create Used for deep-linking applications. Allows the creation of a UAS operation that can be deep-linked into LAANC authorization app.
route.create Allows the creation of UAS waypoints that navigate around ground based hazards and risks.
token.create Used to generate a geo-token. A geo-token grants access to specific geographic specialized resources throughout the API.
flight.read Grants read access to our anonymized or group flight data.
token.generate DEPRECATED: Use token.create instead.

Advisories

Advisories represent geographic areas where special consideration must be made before operating drones. Examples of advisories may range from restricted airspace - where it's illegal to operate a drone - to warnings where it's important for you to understand the context of where you're flying to maximize safety. Additional advisory types will be documented as they're added.

Get Advisories

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v2/advisory' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
    "geometry": {
      "type": "Polygon",
      "coordinates": [[
        [-83.25923546832819,42.23958101718406],
        [-83.38626488727355,42.23958101718406],
        [-83.38626488727355,42.13782883968136],
        [-83.25923546832819,42.13782883968136],
        [-83.25923546832819,42.23958101718406]
      ]]
    },
    "category": "faa_107",
    "published": true             
  }'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v2/advisory");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [-83.25923546832819, 42.23958101718406],
          [-83.38626488727355, 42.23958101718406],
          [-83.38626488727355, 42.13782883968136],
          [-83.25923546832819, 42.13782883968136],
          [-83.25923546832819, 42.23958101718406],
        ],
      ],
    },
    category: "faa_107",
    published: true
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this (dates and times are in UTC, and can be null):

{
  "data":
    [
      {
        "type": "Feature",
        "geometry": {"type": "Polygon", "coordinates": [[...]]},
        "properties": {
          "title": "4th of July Parade",
          "message": "Parade in downtown Springfield to celebrate ...",
          "severity": "warning",
          "advisorySource": "community",
          "advisoryType": "admin",
          "startDate": "2020-01-01", // UTC
          "startTime": "10:10", // military time
          "endDate": "2020-01-01", // UTC
          "endTime": "20:00", // military time
          "timezone": "America/New_York",
          "effectiveDays": ["Mon","Tue","Fri"],
          "friendlyDayPhrase": "Active until further notice",
          "contactName": "John Doe",
          "contactPhone": "+12345678910",
          "contactEmail": "john@gov.gov",
          "contactUrl": "http://myadvisory.com/1234",
          "metadata": {
            // <custom attributes that may vary depending on the advisory>
          }
        }
      },
      {...},
      {...}
    ],
  "message": "success",
  "statusCode": 200
}

Find advisories that intersect the input geometry.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v2/advisory

Scope: airhub-api/advisory.read

Why POST and not GET? GeoJSON strings can often become quite long depending on the complexity of the coordinates. We use a POST to overcome any browser url length limitations when using this API in the browser.

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

Parameter Type Description
geometry GeoJSON GeoJSON formatted geometry. May be point, line, or polygon
category string See rule category. This is the specified rule category under which you'll be flying.
source string See advisory source. This is the advisory source you wish to return.
startTime string Argument for filtering active advisories on or after timestamp. Send as an ISO 8601 timestamp. See below for more details on how to use.
endTime string Argument for filtering active advisories on or before timestamp. Send as an ISO 8601 timestamp. See below for more details on how to use.
maxAltitude integer The maximimum altitude anticipated for the operation. This helps to determine FAA restrictions.
published boolean Argument for filtering published/unpublished advsisories. Send true for published advisories, false for unpublished, or omit this value to return all.

Filtering FAA Advisories using startTime/endTime

Some of the FAA Advisory types (e.g. tfr) can be filtered using startTime/endTime. This will limit the advisories to those which have a start time less than or equal to endTime and have an end time greater than or equal to startTime.

Filtering Community Advisories using startTime/endTime

For Community Advisories, filtering by startTime/endTime applies a windowed filter. For example, specifying 2020-11-05T12:00Z for startTime will filter advisories that are active (a) on or after November 5th, 2020, and (b) active after 12:00 UTC each day. An advisory that occurs 2020-11-06T10:00Z-2020-11-06T11:00Z would not be included in the result set; November 6th is after November 5th, but the advisory isn't active after 12:00 UTC, it ends at 11:00 UTC. Vice versa is also true for endTime.

If startTime and endTime are both specified, you can wrap the time window by specifying startTime's time portion in the ISO 8601 timestamp to be greater than endTime's timestamp. For example, setting 2020-11-05T23:00Z as startTime and 2020-11-07T01:00Z as endTime will capture anything within the following ranges:

  1. 2020 November 5th, 23:00-23:59
  2. 2020 November 6th, 00:00-01:00, 23:00-23:59
  3. 2020 November 7th, 00:00-01:00

Source

Represents the source of the advsiory or the authority that created the advisory. Additional sources will be made available in the future.

Source Description
faa Federal (FAA) advisories
community State & Local community advisories
all All available advisories

FAA Types

FAA advisories can have the following types as detailed below:

Type Description
controlled_airspace Controlled Airspace Classification.
uasfm_ceiling UAS Facility Management Flight Ceiling.
sua_prohibited Prohibited Special Use Airspace.
sua_restricted Restricted Special Use Airspace.
washington_frz Washington DC Flight Restricted Zone.
nsufr_pt Part Time National Security UAS Flight Restriction.
nsufr_ft Full Time National Security UAS Flight Restriction.
stadium Select stadiums containing temporary flight restriction. The stadium points are buffered by 3 nautical miles.
class_e_weather Weather ceiling when flying in class E airspace.
tfr Temporary Flight Restrictions imposed by the FAA to restrict aircraft operations within designated areas.

Community Types

Community advisories can have the following types as detailed below:

Type Description
admin Administrative advisory (e.g. city or utility infrastructure)
emergency Emergency response area (e.g. accident cleanup area)
recreation Recreational advisory (e.g. parks, events, public gatherings)

Severity

Each advisory will return a severity property. These severities are described as follows:

Type Description
grounded Flying within the advisory should not be undertaken without an additional FAA flight waiver
warning Flying within the advsiory area is not restricted, but discouraged for safety reasons
information The advisory is informational

Create Community Advisory

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v3/advisory' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
    "type": "Feature",
    "properties": {
      "title": "Test advisory: Market",
      "type": "Admin",
      "tags": ["City Event"],
      "effectiveDays": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      "startDate": "2020-12-29",
      "endDate": "2021-01-25",
      "startTime": "16:00",
      "endTime": "18:00",
      "timezoneName": "America/New_York",
      "referenceNumber": "farm 5.4",
      "published": true,
      "contactEmail": "Example@test.com",
      "contactPhone": "+12345678910"},
    "geometry": {"type": "Polygon", "coordinates": [[...]]}
  }'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v3/advisory");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    type: "Feature",
    properties: {
      title: "Test advisory: Market",
      type: "Admin",
      tags: ["City Event"],
      effectiveDays: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      startDate: "2020-12-29",
      endDate: "2021-01-25",
      startTime: "16:00",
      endTime: "18:00",
      timezoneName: "America/New_York",
      referenceNumber: "farm 5.4",
      published: true,
      contactEmail: "Example@test.com",
      contactPhone: "+12345678910"
    },
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [-83.25923546832819, 42.23958101718406],
          [-83.38626488727355, 42.23958101718406],
          [-83.38626488727355, 42.13782883968136],
          [-83.25923546832819, 42.13782883968136],
          [-83.25923546832819, 42.23958101718406],
        ],
      ],
    }
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "data": [{"id": <advisory-id>}],
  "message": "success",
  "statusCode": 200
}

Create an advisory to notify UAS pilots about Administrative, Emergency, or Recreational activities.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v3/advisory

Scope: airhub-api/advisory.create

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

The POST body is expected to be a GeoJSON Feature. The feature's geometry must be a GeoJSON Polygon.

Parameter Type Description
type static string Feature
geometry object GeoJSON Polygon
properties object See advisory properties

Advisory Properties

Parameter Type Description
title string Name of the advisory.
type string The type of the advisory.
timezoneName string Timezone of the advisory.
startDate string ISO 8601 compliant start date of the advisory. If timestamp is provided, it will be ignored. Defaults to be active until endDate.
endDate string ISO 8601 compliant end date of the advisory. If timestamp is provided, it will be ignored. Defaults to be active indefinitely.
startTime string Start time for each day that the advisory is active (in 24hr format "hh:mm"). If date is provided, it will be ignored. Defaults to start at "00:00".
endTime string End time for each day that the advisory is active (in 24hr format "hh:mm"). If date is provided, it will be ignored. Defaults to end at "23:59".
effectiveDays string array List of weekdays in which advisory is active. Valid option is a subset of ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]. Defaults to [].
tags string array List of tags as metadata for the advisory.
referenceNumber string Optional reference number from external data systems.
contactUrl string Url with more information about the advisory.
published boolean If true, the advisory is considered published. Defaults to false.
contactEmail string Contact email address of the advisory source.
contactPhone string Contact phone number of the advisory source. contactPhone should be formatted with '+1' country code followed by 10-digit phone number (e.g. "+11234567890").
groupId string A GUID supplied to your jurisdiction by Airspace Link.

Edit Community Advisory

curl --location --request PATCH 'https://airhub-api-sandbox.airspacelink.com/v3/advisory/<your-advisory-id>' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
    "type": "Feature",
    "properties": {
      "title": "Test advisory: Market",
      "type": "Admin",
      "tags": ["City Event"],
      "effectiveDays": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      "startDate": "2020-12-29",
      "endDate": "2021-01-25",
      "startTime": "16:00",
      "endTime": "18:00",
      "timezoneName": "America/Denver",
      "contactPhone": "+12445672910"
    },
    "geometry": {"type": "Polygon", "coordinates": [[...]]}
  }'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("PATCH", "https://airhub-api-sandbox.airspacelink.com/v3/advisory/<your-advisory-id>");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    type: "Feature",
    properties: {
      title: "Test advisory: Market",
      type: "Admin",
      tags: ["City Event"],
      effectiveDays: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      startDate: "2020-12-29",
      endDate: "2021-01-25",
      startTime: "16:00",
      endTime: "18:00",
      timezoneName: "America/Denver",
      contactPhone: "+12345678910"
    },
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [-83.25923546832819, 42.23958101718406],
          [-83.38626488727355, 42.23958101718406],
          [-83.38626488727355, 42.13782883968136],
          [-83.25923546832819, 42.13782883968136],
          [-83.25923546832819, 42.23958101718406],
        ],
      ],
    }
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "data": [{"id": <advisory-id>}],
  "message": "success",
  "statusCode": 200
}

Some or all of an advisory's properties may be updated.

HTTP Request

PATCH https://airhub-api-sandbox.airspacelink.com/v3/advisory/<id>

Scope: airhub-api/advisory.update

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON PATCH Body

The PATCH body is expected to be a GeoJSON Feature. The feature's geometry must be a GeoJSON Polygon.

Parameter Type Description
type static string Feature
geometry object GeoJSON Polygon. Set as null if update is not needed
properties object See advisory properties. Set as null or {} if update is not needed

Advisory Properties

Parameter Type Description
title string Name of the advisory. Not nullable.
type string The type of the advisory. Not nullable.
timezoneName string Timezone of the advisory. Not nullable.
startDate string ISO 8601 compliant start date of the advisory. If timestamp is provided, it will be ignored. Defaults to be active until endDate. Nullable, set to null to erase current value.
endDate string ISO 8601 compliant end date of the advisory. If timestamp is provided, it will be ignored. Defaults to be active indefinitely. Nullable, set to null to erase current value.
startTime string Start time for each day that the advisory is active (in 24hr format "hh:mm"). If date is provided, it will be ignored. Defaults to start at "00:00". Nullable, set to null to erase current value.
endTime string End time for each day that the advisory is active (in 24hr format "hh:mm"). If date is provided, it will be ignored. Defaults to end at "23:59". Nullable, set to null to erase current value.
effectiveDays string array List of weekdays in which advisory is active. Valid option is a subset of ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]. Defaults to []. Nullable, set to null or [] to erase current value.
tags string array List of tags as metadata for the advisory. Nullable, set to null or [] to erase current value.
referenceNumber string Optional reference number from external data systems. Nullable, set to null to erase current value.
contactUrl string Url with more information about the advisory. Nullable, set to null to erase current value.
published boolean If true, the advisory is considered published. Not nullable.
contactEmail string Contact email address of the advisory source. Nullable, set to null to erase current value.
contactPhone string Contact phone number of the advisory source. contactPhone should be formatted with '+1' country code followed by 10-digit phone number (e.g. "+11234567890"). Nullable, set to null to erase current value.
groupId string A GUID supplied to your jurisdiction by Airspace Link. Nullable, set to null to erase current value.

Delete Community Advisory

curl --location --request DELETE 'https://airhub-api-sandbox.airspacelink.com/v3/advisory/<your-advisory-id>' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{}'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://airhub-api-sandbox.airspacelink.com/v3/advisory/<your-advisory-id>");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(JSON.stringify({}));

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "data": [{"id": <advisory-id>}],
  "message": "success",
  "statusCode": 200
}

Allows deletion of an advisory. Use caution; this action cannot be undone.

HTTP Request

DELETE https://airhub-api-sandbox.airspacelink.com/v3/advisory/<id>

Scope: airhub-api/advisory.delete

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

Operations

Operation

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/operation' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
    "type": "Feature",
    "properties": {"operationName": "test"},
    "geometry": {"type": "Polygon", "coordinates": [[...]]}
  }'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v1/operation");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    type: "Feature",
    properties: {
      operationName: "Test Operation"
    },
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [-83.25923546832819, 42.23958101718406],
          [-83.38626488727355, 42.23958101718406],
          [-83.38626488727355, 42.13782883968136],
          [-83.25923546832819, 42.13782883968136],
          [-83.25923546832819, 42.23958101718406],
        ],
      ],
    }
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "data": {"uuid": "<uuid>"},
  "message": "success",
  "statusCode": 200
}

To support LAANC authorizations within 3rd-party applications, the API allows the creation of operations for deep-linking workflows. Each operation includes information such as pilot name and contact information, operation start time and duration, requested altitude, and the operation boundary (shape).

LAANC Deep Linking

Successfully creating an operation will return a uuid that may be used to retrieve the operation within the AirHub for Pilots LAANC application. Following is a sample deep-link url (used after the operation has been successfully generated):

https://pilots.airspacelink.com?operation=<uuid returned by API>

Important: Operations created in the sandbox API must deeplink into the sandbox pilot environment.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/operation

Scope: airhub-api/operation.create

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

The POST body is expected to be a GeoJSON Feature. The feature's geometry must be a GeoJSON Polygon.

Parameter Type Description
type static string Feature
geometry object GeoJSON Polygon
properties object See operation properties

Operation Properties

Parameter Type Description
operationName string Name of the operation.
category string Rule category.
startTime string ISO 8601 compliant start timestamp of the operation.
timezoneName string Operation timezone.
duration integer Duration of the operation from 1 - 720 minutes.
maxAltitude integer Maximum requested altitude of the operation from 5 - 400' Above Ground Level.
fixedAltitude boolean If false, the platform will adjust the altitude to remain below any applicable ceiling limits. This makes for easier FAA approvals, but may not meet the parameters of your operation.

Rule Category

Type Description
faa_107 FAA Commercial Part 107 rules
faa_44809 FAA Recreational Part 44809 rules

Timezone

Type Description
America/New_York Eastern Time (EDT, EST)
America/Chicago Central Time (CDT, CST)
America/Denver Mountain Time (MDT, MST)
America/Phoenix Mountain Time - No Daylight Savings (MST)
America/Los_Angeles Pacific Time (PDT, PST)
America/Anchorage Alaska Time (AKDT, AKST)
Pacific/Honolulu Hawaii Time (HST)
America/Puerto_Rico Atlantic Time (AST)
Pacific/Guam Chamorro Time (ChST)
America/Adak Aleutian Time (HADT, HAST)
Pacific/Pago_Pago Samoa Time (SST)

Flights

Anonymized flight data

To get anonymized flight data, use this code:

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/flight' \
  --header 'Content-Type: application/json;charset=UTF-8' \
  --header 'Authorization: Bearer <your-access-token>' \
  --header 'x-api-key: <your-api-key>' \
  -d '{
    "geoType": "place",
    "geoID": "2622000",
    "startTime": "2021-03-08T12:00Z",
    "endTime": "2021-03-25T13:00Z"
  }'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open(`POST`, `https://airhub-api-sandbox.airspacelink.com/v1/flight`);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    "geoType": "place",
    "geoID": "2622000",
    "startTime": "2021-03-08T12:00Z",
    "endTime": "2021-03-25T13:00Z"
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "statusCode": 200,
  "message": "success",
  "data": {
    "numberOfPilots": 15,
    "flights": [
      {
        "approvedAuths": 0,
        "operationID": "ZKPBDFY5",
        "startTime": "2021-03-22T19:37:00.000Z",
        "indices": [
          "89298616d93ffff",
          ...
        ]
      },
      ...
    ]
  }
}

Flights are UAS operations within a given geographic boundary. The data is returned as hex addresses which represent a hexagonal shape corresponding to one area of the flight. Therefore, the data is anonymized such that the boundaries do not reflect the actual area of the flight.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/flight

Scope: airhub-api/flight.read

Why POST and not GET? GeoJSON strings can often become quite long depending on the complexity of the coordinates. We use a POST to overcome any browser url length limitations when using this API in the browser.

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

Parameter Type Description
geoType string A geographic type
geoID string A string serial ID qualified from geoType
startTime string Filters flights on or after timestamp. Send as an ISO 8601 timestamp.
endTime string Filters flights on or before timestamp. Send as an ISO 8601 timestamp.

Geographic Types

Type Description
state A state identifier
county A county identifier
county_subdivision A county subdivision identifier
place A place identifier
region A region identifier
campus A campus identifier

Group flight data

To get flight data, use this code:

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/flight/group' \
  --header 'Content-Type: application/json;charset=UTF-8' \
  --header 'Authorization: Bearer <your-access-token>' \
  --header 'x-api-key: <your-api-key>' \
  -d '{
    "startTime": "2021-03-08T12:00Z",
    "endTime": "2021-03-25T13:00Z",
    "includeGeometry": true
  }'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open(`POST`, `https://airhub-api-sandbox.airspacelink.com/v1/flight/group`);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    "startTime": "2021-03-08T12:00Z",
    "endTime": "2021-03-25T13:00Z",
    "includeGeometry": true
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "statusCode": 200,
  "message": "success",
  "data": [
    {
      "type": "Feature",
      "geometry": {"type": "Polygon", "coordinates": [[...]]},
      "properties": {
        "id": "ABC123",
        "operationName": "Operation Good Times",
        "stateCode": "",
        "submissionCategory": "faa_107",
        "maxAltitude": 200,
        "fixedAltitude": false,
        "startTime": "2021-03-08T12:00Z",
        "timezoneName": "America/New_York",
        "duration": 60,
        "pilotFirstName": "Johnny",
        "pilotLastName": "Guy",
        "contactNumber": "+15555555555",
        "contactEmail": "johnny@guy.com",
        "createdDate": "2021-03-08T12:00Z",
        "canceledDate": "2021-03-08T12:00Z",
        "closedDate": "2021-03-08T12:00Z",
        "status": "approved",
        "droneModel": "Aero",
        "droneMake": "3D Robotics"
      }
    },
    {...},
    {...}
  ]
}

Get all flights created within your group.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/flight/group

Scope: airhub-api/flight.read

Why POST and not GET? GeoJSON strings can often become quite long depending on the complexity of the coordinates. We use a POST to overcome any browser url length limitations when using this API in the browser.

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer token generated by login to the web application
x-api-key API key supplied to you by Airspace Link

JSON POST Body

Parameter Type Description
startTime string Filters flights on or after timestamp. Must be within 30 days of endTime. Defaults to 30 days before endTime, if endTime is specified. Send as an ISO 8601 timestamp.
endTime string Filters flights on or before timestamp. Must be within 30 days of startTime. Defaults to 30 days after startTime, if startTime is specified. If startTime isn't specified, it will default to now. The latest time allowed is 30 days into the future. The final range must not exceed a span of 30 days as well. Send as an ISO 8601 timestamp.
includeGeometry boolean Flag to include the geometry of the GeoJSON in the payload. Defaults to true.

Token

Geo-Token

curl --location --request GET 'https://airhub-api-sandbox.airspacelink.com/v1/token/geo-token' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--header 'referer: <your-application-referer>'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open(
  "GET",
  "https://airhub-api-sandbox.airspacelink.com/v1/token/geo-token"
);
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.setRequestHeader("referer", "<your-application-referer>");
xhr.send();

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "data": {
    "token": "<geo-token>",
    "expires": 1600382940719,
    "ssl": true
  },
  "message": "success",
  "statusCode": 200
}

Some datasets require additional authorization. We call the token required for these requests a geo-token. Examples of these types of resources include tile mapping services or specialized data limited to specific groups of individuals. The documentation will indicate when this token is necessary. If required, the geo-token will be supplied in a request header using the x-geo-token header.

HTTP Request

GET https://airhub-api-sandbox.airspacelink.com/v1/token/geo-token

Scope: airhub-api/token.create

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

URL Parameters

Parameter Type Description
useGroup boolean If true, the geo-token will utilize the security group assigned to the authenticated user. This parameter should be excluded from the request under normal circumstances.

Risk

Hazard and risk is an important part of the UAS ecosystem. The FAA publishes well established guidelines on how operations should behave with respect to population and other ground-based risk. This set of API resources will help developers quantify these hazards and their associated risk with a geographic boundary.

Hazard

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/hazard' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [-83.33816528320312, 42.20156425714052],
        [-83.2059860229492, 42.20156425714052],
        [-83.2059860229492, 42.274514451885],
        [-83.33816528320312, 42.274514451885],
        [-83.33816528320312, 42.20156425714052]
      ]
    ]
  }
}'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v1/hazard");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [-83.33816528320312, 42.20156425714052],
          [-83.2059860229492, 42.20156425714052],
          [-83.2059860229492, 42.274514451885],
          [-83.33816528320312, 42.274514451885],
          [-83.33816528320312, 42.20156425714052],
        ],
      ],
    },
  })
);

The above command returns JSON like this:

{
  "statusCode": 200,
  "message": "success",
  "data": [
    {
      "type": "Feature",
      "properties": {
        "Category": "Critical Infrastructure",
        "CategoryType": "Child Care Center",
        "Name": "RIVERSIDE ACADEMY EARLY CHILDHOOD CENTER",
        "Risk": 1,
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-83.2320785522461, 42.33418438593939],
            [-83.22624206542969, 42.33418438593939],
            [-83.22624206542969, 42.33646849299472],
            [-83.2320785522461, 42.33646849299472],
            [-83.2320785522461, 42.33418438593939]
          ]
        ]
      }
    }
  ]
}

Find hazards that intersect the input geometry.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/hazard

Scope: airhub-api/hazar.read

Why POST and not GET? GeoJSON strings can often become quite long depending on the complexity of the coordinates. We use a POST to overcome any browser url length limitations when using this API in the browser.

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

Parameter Type Description
geometry object GeoJSON formatted geometry. Available geometries may be a point, line, or polygon. The resulting bounding box of the geometry can't have a side length greater than 10 nautical miles.

Ground Type

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/groundType' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
  "geometry": {
    "type": "Point",
    "coordinates": [
      [-85.52521705627441, 41.7848170756551]
    ]
  },
  "resolution": 10
}'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v1/groundType");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    geometry: {
      type: "Point",
      coordinates: [[-85.52521705627441, 41.7848170756551]],
    },
    resolution: 10,
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "data": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [[
          [-83.108219359342,42.385396234885185],
          [-83.1091231948962,42.38517018839536],
          [-83.10928346569173,42.38450374309799],
          [-83.10853992433273,42.38406334748932],
          [-83.10763610686435,42.38428938593143],
          [-83.10747581266932,42.38495582802976],
          [-83.108219359342,42.385396234885185]
        ]]
      },
      "properties": {
        "density": "Urban",
        "popPerSqMi": 3270.2970129961664,
      }
    },
    ...
  ],
  "message": "success",
  "statusCode": 200
}

Represents the population classification(s) for the input geometry. Returns an array of the population densities and their respective geometries over the input geometry.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/groundType

Scope: airhub-api/hazar.read

Why POST and not GET? GeoJSON strings can often become quite long depending on the complexity of the coordinates. We use a POST to overcome any browser url length limitations when using this API in the browser.

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

Parameter Type Description
geometry object GeoJSON formatted geometry. Available geometries may be a point, line, or polygon
resolution number The resolution of the output surface. A larger number means finer granularity.

Ground Risk

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/groundRisk' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
  "geometry": {
    "type": "Polygon",
    "coordinates": [[
      [-83.33816528320312, 42.20156425714052],
      [-83.2059860229492, 42.20156425714052],
      [-83.2059860229492, 42.274514451885],
      [-83.33816528320312, 42.274514451885],
      [-83.33816528320312, 42.20156425714052]
    ]]
  },
  "maxAltitude": 100,
  "uavWeight": "MICRO",
  "uavType": "HELICOPTER",
  "pilotControl": "SINGLE_PILOT",
  "losType": "VLOS",
  "resolution": 10
}'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v1/groundRisk");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    geometry: {
      type: "Polygon",
      coordinates: [[
        [-83.12633514404297,42.36539333502107],
        [-83.06419372558594,42.36539333502107],
        [-83.06419372558594,42.38619069220356],
        [-83.12633514404297,42.38619069220356],
        [-83.12633514404297,42.36539333502107]
      ]]
    },
    maxAltitude: 100,
    uavWeight: "MICRO",
    uavType: "HELICOPTER",
    pilotControl: "SINGLE_PILOT",
    losType: "VLOS",
    resolution: 10
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "status": 200,
  "message": "success",
  "data": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [[
          [-83.108219359342,42.385396234885185],
          [-83.1091231948962,42.38517018839536],
          [-83.10928346569173,42.38450374309799],
          [-83.10853992433273,42.38406334748932],
          [-83.10763610686435,42.38428938593143],
          [-83.10747581266932,42.38495582802976],
          [-83.108219359342,42.385396234885185]
        ]]
      },
      "properties": {
        "density": "Urban",
        "infrastructureTypes": ["Right of Way"],
        "popPerSqMi": 3270.2970129961664,
        "score": 2.4
      }
    },
    ...
  ]
}

Ground Risk is modeled from a combination of ground-based hazards, altitude, and drone characteristics (e.g. weight, speed, etc).

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/groundRisk

Scope: airhub-api/hazar.read

Why POST and not GET? GeoJSON strings can often become quite long depending on the complexity of the coordinates. We use a POST to overcome any browser url length limitations when using this API in the browser.

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

Parameter Type Description
geometry object GeoJSON formatted geometry. Available geometries may be a point, line, or polygon.
uavWeight string Describes the weight of the drone.
uavType string Describes the wing type of the drone.
pilotControl string Describes how the drone will be piloted for the operation.
losType string Describes how the pilot will be observing the drone fly during the operation (if at all).
maxAltitude number An integer representing the altitude of the flight in feet. Must be at least 100 feet.
resolution number The resolution of the output surface. Must be an integer 8-10. A larger number means finer granularity.

UAV Weight

Different classifications of drone weights, in pounds

Type Description
micro A drone that weighs ≤ 0.55 pounds
mini A drone that weighs more than micro and ≤ 4.4 pounds
limited A drone that weighs more than mini and ≤ 20.9 pounds
bantam A drone that weighs more than limited

UAV Type

The type of UAV used in the operation

Type Description
fixed_wing A drone using wings for flight
helicopter A drone using a single rotor for flight
multirotor A drone using more than one rotor for flight
hybrid A combination of the other 3 categories listed

Pilot Control

How the drone is to be flown during the operation

Type Description
single_pilot One pilot will fly the drone for the duration of the operation
multiple_pilot Multiple pilots will fly the drone for the duration of the operation
automated_control The drone will be controlled without a pilot

Drone Line of Sight

How the pilot(s) (if any) will observe the drone for the duration of the operation

Type Description
vlos Visual line of sight: the pilot can see the drone throughout the entire operation
evlos Extended visual line of sight: the drone has spotters relaying information to the pilot
bvlos Beyond visual line of sight: the pilot may not see the drone at some point throughout the operation

Meta routes

Metadata

The metadata route shows all the data sources available for usage.

curl --location --request GET 'https://airhub-api-sandbox.airspacelink.com/v1/metadata' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--header 'referer: <your-application-referer>'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("GET",  "https://airhub-api-sandbox.airspacelink.com/v1/metadata");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.setRequestHeader("referer", "<your-application-referer>");
xhr.send();

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "statusCode": 200,
  "message": "success",
  "data": [
    {
      "name": "Airports",
      "code": "airports",
      "description": "Points designated for landing or takeoff"
    }
  ]
}

HTTP Request

GET https://airhub-api-sandbox.airspacelink.com/v1/metadata

Scope: airhub-api/metadata.read

Required Headers

Parameter Description
Authorization Authorization bearer access_token generated in Authentication step
x-api-key API key supplied to you by Airspace Link
referer The base URL of the client application that will consume the token. For example, https://yourdomain.com.

Aviation

Aviation

Returns intersecting aviation data from the FAA.

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/aviation?buffer=4' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
  "type": ["sua_prohibited", "stadium", "airports"],
  "geometry": {
    "type": "Point",
    "coordinates": [-85.52521705627441, 41.7848170756551]
  }
}'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v1/aviation?buffer=4");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    type: ["sua_prohibited", "stadium", "airports"],
    geometry: {
      type: "Point",
      coordinates: [-85.52521705627441, 41.7848170756551],
    },
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "statusCode": 200,
  "message": "success",
  "data": [
    {
      "type": "Feature",
      "properties": {
        // ...metadata
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-83.2320785522461, 42.33418438593939],
            [-83.22624206542969, 42.33418438593939],
            [-83.22624206542969, 42.33646849299472],
            [-83.2320785522461, 42.33646849299472],
            [-83.2320785522461, 42.33418438593939]
          ]
        ]
      }
    }
  ]
}

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/aviation

Scope: airhub-api/aviation.read

Why POST and not GET? GeoJSON strings can often become quite long depending on the complexity of the coordinates. We use a POST to overcome any browser url length limitations when using this API in the browser.

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

URL Parameters

Parameter Type Description
buffer number Note: only used when type includes airports. buffer specifies the buffer around the airport in nautical miles. If not specified, the default is 3.

JSON POST Body

Parameter Type Description
geometry object GeoJSON formatted geometry. Available geometries may be a point, line, or polygon. The resulting bounding box of the geometry can't have a side length greater than 10 nautical miles.
type string An array of zero or more types from FAA types below. Specifying type will limit the results to only include the types that you specify. If you specify no type then all types will be returned.
startTime string Filters TFRs on or after timestamp. Send as an ISO 8601 timestamp. Only TFR data will be filtered by this property.
endTime string Filters TFRs on or before timestamp. Send as an ISO 8601 timestamp. Only TFR data will be filtered by this property.

FAA Types

Below are various FAA data types. Types will be represented by a constant string as detailed below.

Type Description
controlled_airspace Controlled Airspace Classification.
uasfm_ceiling UAS Facility Management Flight Ceiling.
sua_prohibited Prohibited Special Use Airspace.
sua_restricted Restricted Special Use Airspace.
sua Both sua_prohibited and sua_restricted.
washington_frz Washington DC Flight Restricted Zone.
nsufr_pt Part Time National Security UAS Flight Restriction.
nsufr_ft Full Time National Security UAS Flight Restriction.
stadium Select stadiums containing temporary flight restriction. The stadium points are buffered by 3 nautical miles.
airports Points designated for landing or takeoff. Returns all airports within 3 nautical miles of input geometry by default.
airspace_schedule Controlled airspace schedule for select airports across the country (geometry has no bearing on the result).
tfr Temporary Flight Restrictions imposed by the FAA to restrict aircraft operations within designated areas.

Surface

Surface routes provide hexagonal surfaces that describe the terrain, and can be used to quantify risk via suitability surfaces.

Surface

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/surface' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
  "resolution": 9,
  "noFill": true,
  "index": false,
  "features": {
    "schools": {
      "where": "",
      "fields": ["*"]
    }
  },
  "geometry": {
    "type": "Polygon",
    "coordinates": [[
      [-85.20858764648438, 42.37579287453795],
      [   -85.10009765625, 42.37579287453795],
      [   -85.10009765625, 42.45436780800864],
      [-85.20858764648438, 42.45436780800864],
      [-85.20858764648438, 42.37579287453795]
    ]]
  }
}'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v1/surface");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    "resolution": 9,
    "noFill": true,
    "index": false,
    "features": {
      "schools": {
        "where": "<where clause>",
        "fields": ["ADDRESS", "CITY"]
      }
    },
    "geometry": {
      "type": "Polygon",
      "coordinates": [[
        [-85.20858764648438, 42.37579287453795],
        [   -85.10009765625, 42.37579287453795],
        [   -85.10009765625, 42.45436780800864],
        [-85.20858764648438, 42.45436780800864],
        [-85.20858764648438, 42.37579287453795]
      ]]
    }
  })
);

The above command returns JSON like this:

{
  "statusCode": 200,
  "message": "success",
  "data": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [[
          [-85.15551950378466, 42.40390655703839 ],
          [-85.15743139843995, 42.40275510469299 ],
          [-85.15693125519239, 42.40099262351432 ],
          [ -85.1545193727733, 42.40038155809197 ],
          [ -85.1526074934986, 42.401532929461865],
          [-85.15310748125742, 42.403295447227336],
          [-85.15551950378466, 42.40390655703839 ]
        ]]
      },
      "properties": {
        "index": "89274822373ffff",
        "schools": {
          "ADDRESS": ["7422 POORMAN RD"],
          "CITY": ["BATTLE CREEK"]
        }
      }
    },
    ...
  ]
}

Generate a surface with any data sources you request.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/surface

Scope: airhub-api/surface.generate

Why POST and not GET? GeoJSON strings can often become quite long depending on the complexity of the coordinates. We use a POST to overcome any browser url length limitations when using this API in the browser.

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

Parameter Type Description
geometry object GeoJSON formatted geometry. Available geometries may be a point, line, or polygon. The resulting bounding box of the geometry can't have a side length greater than 10 nautical miles.
features object Key-value pairs with the key being a metadata source and the value being an object of parameters to the source.
resolution number The resolution of the output surface. A larger number means finer granularity.
noFill bool If there are no features in a particular hex, don't return it to reduce network latency.
index bool Instead of returning GeoJSON, return the indices of the hexagons.

Parameters object

Parameter Type Description
fields string[] The fields of the metadata source you'd like to return.
where string The where clause to apply to the metadata source.
weight float When computing risk, multiply the final risk score by this number if the feature is present.

Route

Route

curl --location --request POST 'https://airhub-api-sandbox.airspacelink.com/v1/route' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer <your-access-token>' \
--header 'x-api-key: <your-api-key>' \
--data-raw '{
  "geometry": {
      "type": "MultiPoint",
      "coordinates": [
          [-85.52521705627441, 41.7848170756551],
          [-85.52212715148926, 41.7848170756551]
      ]
  },
  "resolution": 10
}'
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE && this.status === 200) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://airhub-api-sandbox.airspacelink.com/v1/route");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Authorization", "Bearer <your-access-token>");
xhr.setRequestHeader("x-api-key", "<your-api-key>");
xhr.send(
  JSON.stringify({
    geometry: {
      type: "MultiPoint",
      coordinates: [
        [-85.52521705627441, 41.7848170756551],
        [-85.52212715148926, 41.7848170756551],
      ],
    },
    resolution: 10,
  })
);

Make sure to replace <your-xxx> with your applicable values.

The above command returns JSON structured like this:

{
  "data": {
    "type": "Feature",
    "properties": null,
    "geometry": {
      "type": "LineString",
      "coordinates": [[...]]}
  },
  "message": "success",
  "statusCode": 200
}

Returns a GeoJSON LineString representing a straight line avoiding ground-based hazards and advisories. In future releases, this route will also accept operation parameters (drone make/model, flight altitude, and time of day) to create an optimal path around spatial-temporal flight risks.

The MultiPoint input object will be used as the origin and destination for the route and must be limited to two points. Intermediate points will be ignored or the API will disallow the operation. In future releases, more than one point will be allowed as input, allowing for multi-destination routing.

HTTP Request

POST https://airhub-api-sandbox.airspacelink.com/v1/route

Scope: airhub-api/route.create

Required Headers

Parameter Description
Content-Type application/json;charset=UTF-8
Authorization Authorization bearer accessToken generated in Authentication step
x-api-key API key supplied to you by Airspace Link

JSON POST Body

The POST body's geometry property is expected to be a GeoJSON MultiPoint. If more or fewer than two points are supplied, the API will reject the request.

Parameter Description
geometry GeoJSON MultiPoint.
resolution The resolution to use for barriers. A larger number means finer granularity.

Errors

The AirHub API uses the following error codes:

Error Code Meaning
400 Bad Request: Your request is invalid.
401 Unauthorized: Your API key is wrong or your accessToken is malformed.
403 Forbidden: The resource requested is not available to your user or your request headers/parameters are malformed.
404 Not Found: The specified resource could not be found.
405 Method Not Allowed: You tried to access a resource with an invalid method.
406 Not Acceptable: You requested a format that isn't json.
410 Gone: The resource has been removed from our servers.
422 Unprocessable: The inputs could not be processed.
500 Internal Server Error: We had a problem with our server. Try again later or adjust your request.
503 Service Unavailable: We're temporarily offline for maintenance. Please try again later.