NAV Navbar
Logo
cURL

Introduction

Welcome to the Global Forest Watch API Documentation

Authentication

The GFW API uses JWT Tokens to identify and authenticate users.

How to generate your own Oauth Token

To generate your own token, follow the next steps:

  1. Navigate to http://ui.resourcewatch.org:82 If you aren’t logged in yet, the application will redirect you to the login page. You will see: Control Tower login page

You can login with your WRI credentials (email and password), or with your Google, Facebook, or Twitter account. If you don’t remember your password (don’t worry! it happens to everyone!), you can reset your password clicking on ‘Recover password’.

  1. After logging in you will be redirected to the Control Tower application and you will see: Control Tower Dashboard

  2. To obtain your token, click in the Profile menu item and you will see: Control Tower Profile

  3. Copy your token clicking the Copy button. Remember to add the header Authorization: Bearer: <yourToken> in order to use it.

Create a new user

To create a new user do the following:

curl -X POST https://production-api.globalforestwatch.org/auth/user \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
    "email":"<email>",
    "role":"<role>",
    "extraUserData": {
      "apps": [
        "<apps>"
      ]
    }
}'

Dataset

What is a Dataset?

A data set represents the raw data. We support four dataset types with different providers. It’s also possible to have the same dataset on different applications.

Supported dataset sources

Carto

(connectorType: ‘rest’, provider: 'cartodb’) CARTO is an open, powerful, and intuitive platform for discovering and predicting the key insights underlying the location data in our world.

ArcGIS

(connectorType: 'rest’, provider: 'featureservice’) ArcGIS Online is a Complete, Cloud-Based Mapping Platform

Google Earth Engine

(connectorType: 'rest’, provider: 'gee’) Google Earth Engine combines a multi-petabyte catalog of satellite imagery and geospatial datasets with planetary-scale analysis capabilities and makes it available for scientists, researchers, and developers to detect changes, map trends, and quantify differences on the Earth’s surface.

Rasdaman

(connectorType: 'rest’, provider: 'rasdaman’) Rasdaman ('raster data manager’) is a database with capabilities for storage, manipulation and retrieval of multidimensional arrays.

CSV

(connectorType: 'document’, provider: 'csv’)

JSON

(connectorType: 'document’, provider: 'json’)

TSV

(connectorType: 'document’, provider: 'tsv’)

XML

(connectorType: 'document’, provider: 'xml’)

WMS

(connectorType: 'wms’, provider: 'wms’)

Getting all datasets

To get all datasets:

curl -X GET https://production-api.globalforestwatch.org/v1/dataset

Response:

{
    "data": {
        "id": "c4ee894f-2a9f-4681-9c3d-d94cf106f796",
        "type": "dataset",
        "attributes": {
            "name": "World Price",
            "slug": "World-Price-1490086842551",
            "type": null,
            "subtitle": null,
            "application": ["aqueduct"],
            "dataPath": null,
            "attributesPath": null,
            "connectorType": "rest",
            "provider": "cartodb",
            "userId": "58333dcfd9f39b189ca44c75",
            "connectorUrl": "https://wri-01.carto.com/tables/combined01_prepared",
            "tableName": "combined01_prepared",
            "status": "saved",
            "published": true,
            "overwrite": false,
            "legend": {
                "date": [],
                "region": [],
                "country": []
            },
            "clonedHost": {},
            "errorMessage": null,
            "createdAt": "2017-01-31T11:47:27.811Z",
            "updatedAt": "2017-01-31T13:05:17.359Z"
        }
    }
}

Slug

Datasets have an auto-generated and unique slug that allows the user to get, create, update or clone a dataset. The dataset slug cannot be updated even if the name changes.

Error Message

When a dataset is created the status is set to “pending” by default. Once the adapter validates the dataset, the status is changed to “saved”. If the validation fails, the status will be set to “failed” and the adapter will also set an error message indicating the reason.

Filters

Available filters: Any dataset property

curl -X GET https://production-api.globalforestwatch.org/v1/dataset?name=birds&provider=cartodb

Inclusive filtering with array props using ’@’

curl -X GET https://production-api.globalforestwatch.org/v1/dataset?app=gfw@rw@prep

Sorting

Available sorting: Any dataset property (desc: -)

curl -X GET https://production-api.globalforestwatch.org/v1/dataset?sort=-provider,slug
curl -X GET https://production-api.globalforestwatch.org/v1/dataset?sort=slug,-provider,userId&status=saved

Relationships

Available relationships: Any dataset relationship ['widget’, 'layer’, 'vocabulary’, 'metadata’]

curl -X GET https://production-api.globalforestwatch.org/v1/dataset?sort=slug,-provider,userId&status=saved&includes=metadata,vocabulary,widget,layer

Advanced filters

By vocabulary-tag matching

curl -X GET https://production-api.globalforestwatch.org/v1/dataset?sort=slug,-provider,userId&status=saved&includes=metadata,vocabulary,widget,layer&vocabulary[legacy]=umd

Pagination

Field Description Type
page[size] The number elements per page Number
page[number] The page number Number
curl -X GET https://production-api.globalforestwatch.org/v1/dataset?sort=slug,-provider,userId&status=saved&includes=metadata,vocabulary,widget,layer&vocabulary[legacy]=threshold&page[number]=1
curl -X GET https://production-api.globalforestwatch.org/v1/dataset?sort=slug,-provider,userId&status=saved&includes=metadata,vocabulary,widget,layer&vocabulary[legacy]=threshold&page[number]=2

How to get a specific dataset

To get a dataset:

curl -X GET https://production-api.globalforestwatch.org/v1/dataset/51943691-eebc-4cb4-bdfb-057ad4fc2145

Response:

{
    "data": {
        "id": "51943691-eebc-4cb4-bdfb-057ad4fc2145",
        "type": "dataset",
        "attributes": {
            "name": "Timber Production RDC (test)",
            "slug": "Timber-Production-RDC-test-1490086842132",
            "type": null,
            "subtitle": null,
            "application": ["forest-atlas"],
            "dataPath": null,
            "attributesPath": null,
            "connectorType": "document",
            "provider": "csv",
            "userId": "58750a56dfc643722bdd02ab",
            "connectorUrl": "http://wri-forest-atlas.s3.amazonaws.com/COD/temp/annual%20timber%20production%20DRC%20%28test%29%20-%20Sheet1.csv",
            "tableName": "index_51943691eebc4cb4bdfb057ad4fc2145",
            "status": "saved",
            "overwrite": false,
            "legend": {
                "date": ["year"],
                "region": [],
                "country": [],
                "long": "",
                "lat": ""
            },
            "clonedHost": {},
            "errorMessage": null,
            "createdAt": "2017-01-25T21:48:27.535Z",
            "updatedAt": "2017-01-25T21:48:28.675Z"
        }
    }
}

To get the dataset including its relationships:

curl -X GET https://production-api.globalforestwatch.org/v1/dataset/06c44f9a-aae7-401e-874c-de13b7764959?includes=metadata,vocabulary,widget,layer

Creating a Dataset

To create a dataset, you will need an authorization token. Follow the steps of this guide to get yours.

To create a dataset, you need to define all of the required fields in the request body. The fields that compose a dataset are:

Field Description Type Values Required
name Dataset name Text Any Text Yes
type Dataset type Text Any Text No
subtitle Dataset subtitle Text Any Text No
application Applications the dataset belongs to Array Any valid application name(s) Yes
connectorType Connector type Text rest, document, wms Yes
provider The connectorType provider Text cartodb, featureservice, gee, csv, tsv, xml, json Yes
connectorUrl Url of the data source Url Any url Yes (except for gee and json formats)
tableName Table name Text Any valid table name No (just for GEE dataset)
data JSON DATA only for json connector if connectorUrl not present JSON [{},{},{}] No (just for json if connectorUrl is not present)
dataPath Path to the data in a json dataset Text Any valid JSON key No (just for json if connectorUrl is not present)
dataAttributes Data fields - for json connector if data present Object {“key1”: {“type”: “string”},… } No (just for json if connectorUrl is not present)
legend Legend for dataset. Keys for special fields Object “legend”: {“long”: “123”, “lat”: “123”, “country”: [“pais”], “region”: [“barrio”], “date”: [“startDate”, “endDate”]}} No
overwrite It allows to overwrite dataset data Boolean true/false No
published To set a public or private dataset Boolean true/false No
verified To generate a verified blockchain of the dataset Boolean true/false No
vocabularies Cluster of tags Object {“vocabularyOne”: {“tags”: []},“vocabularyTwo”: {“tags”: []}} No
widgetRelevantProps Group of relevant props of a widget Array Any Text No
layerRelevantProps Group of relevant props of a layer Array Any Text No
subscribable Available dataset queries Object {“”: “”} No (just for json if connectorUrl is not present)

There are some differences between datasets types.

Rest-Carto datasets

curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
    "connectorType":"rest",
    "provider":"cartodb",
    "connectorUrl":"<cartoUrl>",
    "application":[
     "your", "apps"
    ],
    "name":"Example Carto Dataset"
}'

A real example:

curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "connectorType":"rest",
    "provider":"cartodb",
    "connectorUrl":"https://wri-01.carto.com/tables/wdpa_protected_areas/table",
    "application":[
     "gfw", "forest-atlas"
    ],
    "name":"World Database on Protected Areas -- Global"
}'

Rest-ArcGIS

curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "connectorType":"rest",
    "provider":"featureservice",
    "connectorUrl":"https://services.arcgis.com/uDTUpUPbk8X8mXwl/arcgis/rest/services/Public_Schools_in_Onondaga_County/FeatureServer/0?f=json",
    "application":[
     "prep"
    ],
    "name":"Uncontrolled Public-Use Airports -- U.S."
}'

Rest-GEE

curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "connectorType":"rest",
    "provider":"gee",
    "tableName": "JRC/GSW1_0/GlobalSurfaceWater"
    "application":[
     "rw"
    ],
    "name":"Water occurrence"
}'

Rasdaman

The connectorUrl must be a valid url that responds to a Web Coverage Service (WCS Core) DescribeCoverage call with a valid XML document.

curl -H 'Authorization: Bearer <your-token>'  -H 'Content-Type: application/json' -XPOST 'https://production-api.globalforestwatch.org/v1/dataset' -d '{
    "connectorType":"rest",
    "provider":"rasdaman",
    "connectorUrl":"http://54.146.170.2:8080/rasdaman/ows?&SERVICE=WCS&VERSION=2.0.1&REQUEST=DescribeCoverage&COVERAGEID=nightlights",
    "application":[
     "rw"
    ],
    "name":"nightlights"
}'

Document-CSV, Document-TSV, Document-XML

The connectorUrl must be an accessible CSV, TSV or XML file, non-compressed - zip, tar, tar.gz, etc are not supported.

CSV datasets support some optional fields on the creation process. They are:

Field Description Type Values Required
legend Object No
– lat Name of column with latitude value Text Any word No
– long Name of column with longitude value text Any word No
– date Name of columns with date value (ISO Format) Array Any list word No
– region Name of columns with region value (ISO3 code) Array Any list word No
– country Name of columns with country value (ISO3 code) Array Any list word No

z

curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "connectorType":"document",
    "provider":"csv",
    "connectorUrl":"<csvUrl>",
    "application":[
     "your", "apps"
    ],
    "legend": {
      "lat": "lat-column",
      "long": "long-column",
      "date": ["date1Column", "date2Column"],
      "region": ["region1Column", "region2Column"],
      "country": ["country1Column", "country2Column"]
    },
    "name":"Example CSV Dataset"
}'

Real example:

curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "connectorType":"document",
    "provider":"csv",
    "connectorUrl":"https://gfw2-data.s3.amazonaws.com/alerts-tsv/glad_headers.csv",
    "application":[
     "gfw"
    ],
    "legend": {
      "lat": "lat",
      "long": "lon"
    },
    "name":"Glad points"
}'

Document-JSON

The JSON dataset service supports data from external json file or data as json array send in request body

The connectorUrl must be an accessible JSON file

JSON datasets support some optional fields in the creation process. They are:

Field Description Type Values Required
data JSON DATA only for json connector if connectorUrl not present Array [{},{},{}] Yes for json if connectorUrl not present
legend Object No
– lat Name of column with latitude value Text Any word No
– long Name of column with longitude value text Any word No
– date Name of columns with date value (ISO Format) Array Any list word No
– region Name of columns with region value (ISO3 code) Array Any list word No
– country Name of columns with country value (ISO3 code) Array Any list word No
curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "connectorType":"document",
    "provider":"json",
    "connectorUrl":"<jsonURL>",
    "application":[
     "your", "apps"
    ],
    "legend": {
      "lat": "lat-column",
      "long": "long-column",
      "date": ["date1Column", "date2Column"],
      "region": ["region1Column", "region2Column"],
      "country": ["country1Column", "country2Column"]
    },
    "name":"Example JSON Dataset",
}'

Or it is also possible to create a JSON dataset setting the data directly in the request:

curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "connectorType":"document",
    "provider":"json",
    "connectorUrl":"",
    "application":[
     "your", "apps"
    ],
    "data": {"myData":[
            {"name":"nameOne", "id":"random1"},
            {"name":"nameTow", "id":"random2"}
          ]},
    "legend": {
      "lat": "lat-column",
      "long": "long-column",
      "date": ["date1Column", "date2Column"],
      "region": ["region1Column", "region2Column"],
      "country": ["country1Column", "country2Column"]
    },
    "name":"Example JSON Dataset"
}'

Uploading a Dataset (Binary)

You can upload your raw data directly to S3 making use of the “upload” endpoint. This endpoint accepts a file in the property “dataset” and returns a valid connectorUrl. With this connectorUrl you can create or update a “document” dataset.

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/upload \
-H "Authorization: Bearer <your-token>" \
-F "dataset=@<your-file>"

It returns the following:

Response

{
  "connectorUrl": "rw.dataset.raw/tmp/upload_75755182b1ceda30abed717f655c077d-observed_temp.csv"
}
curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"
'{
    "connectorType":"document",
    "provider":"csv",
    "connectorUrl":"rw.dataset.raw/tmp/upload_75755182b1ceda30abed717f655c077d-observed_temp.csv",
    "application":[
     "your", "apps"
    ],
    "name":"Example RAW Data Dataset"
}'

Updating a Dataset

In order to modify the dataset, you can PATCH a request. It accepts the same parameters as the create dataset endpoint, and you will need an authentication token.

An example update request:

curl -X PATCH https://production-api.globalforestwatch.org/v1/dataset/<dataset-id> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json" -d \
'{
    "name": "Another name for the dataset"
}'

Deleting a Dataset

curl -X DELETE https://production-api.globalforestwatch.org/v1/dataset/<dataset-id> \
-H "Authorization: Bearer <your-token>"
-H "Content-Type: application/json"

Cloning a Dataset

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/5306fd54-df71-4e20-8b34-2ff464ab28be/clone \
-H "Authorization: Bearer <your-token>"
-H "Content-Type: application/json" -d \
'{
  "dataset": {
    "dataset_url": "/query/5306fd54-df71-4e20-8b34-2ff464ab28be?sql=select%20%2A%20from%20data%20limit%2010",
    "application": [
      "your",
      "apps"
    ]
  }
}'

Concatenate Data

You can add more data to a dataset only if the overwrite dataset property has been set to true.

Concatenate data using external data source:

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/:dataset_id/concat \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
   "connectorUrl":"<csvUrl>",
   "dataPath": "data... etc"
}'

Concatenate data using JSON array in post body:

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/:dataset_id/concat \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
   "data": [{},{}]
}'

Overwrite Data

You can overwrite the data if the overwrite dataset property has been set to true.

Overwrite data using external data source:

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/:dataset_id/data-overwrite \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
   "connectorUrl":"<url>",
   "dataPath": "data"
}'

Overwrite data using JSON array in post body:

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/:dataset_id/data-overwrite \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
   "data": [{},{}]
}'

Overwrite specific Data

You can overwrite specific data if the overwrite dataset property has been set to true.

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/:dataset_id/data/:data_id \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
   "data_id":":data_id",
   "data": {"a": 1}
}'

Delete specific Data

You can delete specific data if the overwrite dataset property has been set to true.

curl -X DELETE https://production-api.globalforestwatch.org/v1/dataset/:dataset_id/data/:data_id \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"

Dataset data sync

To sync the data of a dataset, you need to choose the action type (concat or overwrite), a cron pattern and a valid url. This configuration should be set in the 'sync’ property when creating or updating a document dataset.

Please be sure that the 'overwrite’ property is set to true. This could be used as a lock in order to not allow new updates even if the sync task is actually created.

curl -X POST https://production-api.globalforestwatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"
'{
    "connectorType":"document",
    "provider":"csv",
    "connectorUrl":"<csvUrl>",
    "application":[
     "your", "apps"
    ],
    "name":"Example SYNC Dataset",
    "overwrite": true,
    "sync": {
        "action":"concat",
        "cronPattern":"0 * * * * *",
        "url":"<updateCsvUrl>"
    }
}'

Layer

What is a Layer?

Is a graphic representation of a Dataset’s data.

Layer contains the next fields:

Field Description Type
userId Id of the owner Text
application Application to which the dataset belongs Array
iso Isos to which the dataset belongs Array
slug Unique identifier of the layer Text
name Name of the layer Url
description Description of the layer Array
dataset UuId of the dataset that the layer belongs Text
layerConfig Custom configuration Object
legendConfig Custom configuration Object
applicationConfig Custom configuration Object
staticImageConfig Custom configuration Object
default If it’s a default layer for the dataset that it belongs Boolean
published Is the layer published? Boolean

How obtain all layers

To obtain all layers:

curl -X GET https://production-api.globalforestwatch.org/v1/layer

Example response:

{
   "data":[
      {
        "id": "e5c3e7c5-19ae-4ca0-a461-71f1f67aa553",
        "type": "layer",
        "attributes": {
          "slug": "total-co2-emissions-by-year",
          "userId": "5858f37140621f11066fb2f7",
          "application": [
            "rw"
          ],
          "name": "Total CO2 emissions by year",
          "default": false,
          "dataset": "11de2bc1-368b-42ed-a207-aaff8ece752b",
          "provider": "cartodb",
          "iso": [],
          "description": null,
          "layerConfig": {
            "account": "rw",
            "body": {
              "maxzoom": 18,
              "minzoom": 3,
              "layers": [
                {
                  "type": "mapnik",
                  "options": {
                    "sql": "SELECT * cait_2_0_country_ghg_emissions_filtered",
                    "cartocss": "",
                    "cartocss_version": "2.3.0"
                  }
                }
              ]
            }
          },
          "legendConfig": {
            "marks": {
              "type": "rect",
              "from": {
                "data": "table"
              }
            }
          },
          "applicationConfig": {},
          "staticImageConfig": {}
        }
      }
   ],
   "links":{
      "first":"https://production-api.globalforestwatch.org/v1/layer?page%5Bnumber%5D=1",
      "prev":"https://production-api.globalforestwatch.org/v1/layer?page%5Bnumber%5D=1",
      "next":"https://production-api.globalforestwatch.org/v1/layer?page%5Bnumber%5D=2&page%5Bsize%5D=10",
      "last":"https://production-api.globalforestwatch.org/v1/layer?page%5Bnumber%5D=64&page%5Bsize%5D=10",
      "self":"https://production-api.globalforestwatch.org/v1/layer?page%5Bnumber%5D=1&page%5Bsize%5D=10"
   }
}

Filter params

Available filters:

Field Description Type
name Filter the layers whose name contains the filter text Text
dataset Filter the layers by dataset uuid Text
sort Sort json response by specific attributes Text
status Filter layers on status (pending, saved, failed, all) Text
published Filter layers on published status (true, false) Boolean
app Filter layers on application (prep, gfw, etc..) Text

Return the layers filtered whose name contains emissions

curl -X GET https://production-api.globalforestwatch.org/v1/layer?name=emissions

Return the layers filtered by dataset

curl -X GET https://production-api.globalforestwatch.org/v1/layer?dataset=11de2bc1-368b-42ed-a207-aaff8ece752b
curl -X GET https://production-api.globalforestwatch.org/v1/dataset/11de2bc1-368b-42ed-a207-aaff8ece752b/layer

Sort by name

curl -X GET https://production-api.globalforestwatch.org/v1/layer?sort=name

Filter layers by status

curl -X GET https://production-api.globalforestwatch.org/v1/layer?status=failed

Filter layers by published status

curl -X GET https://production-api.globalforestwatch.org/v1/layer?published=false

Return the layers filtered whose applications contain rw

curl -X GET https://production-api.globalforestwatch.org/v1/layer?app=rw

Pagination params

Field Description Type
page[size] Number elements per page Number
page[number] Number of page Number

Return the layers of the page 2 with 5 elements per page

curl -X GET https://production-api.globalforestwatch.org/v1/layer?page[size]=5&page[number]=2

How obtain a layer for specific dataset

To obtain the layer:

curl -X GET https://production-api.globalforestwatch.org/v1/dataset/11de2bc1-368b-42ed-a207-aaff8ece752b/layer/e5c3e7c5-19ae-4ca0-a461-71f1f67aa553
curl -X GET https://production-api.globalforestwatch.org/v1/layer/e5c3e7c5-19ae-4ca0-a461-71f1f67aa553

Example response:

{
  "data": {
    "id": "e5c3e7c5-19ae-4ca0-a461-71f1f67aa553",
    "type": "layer",
    "attributes": {
      "slug": "total-co2-emissions-by-year",
      "userId": "5858f37140621f11066fb2f7",
      "application": [
        "rw"
      ],
      "name": "Total CO2 emissions by year",
      "default": false,
      "dataset": "11de2bc1-368b-42ed-a207-aaff8ece752b",
      "provider": "cartodb",
      "iso": [],
      "description": null,
      "layerConfig": {
        "account": "rw",
        "body": {
          "maxzoom": 18,
          "minzoom": 3,
          "layers": [
            {
              "type": "mapnik",
              "options": {
                "sql": "SELECT * cait_2_0_country_ghg_emissions_filtered",
                "cartocss": "",
                "cartocss_version": "2.3.0"
              }
            }
          ]
        }
      },
      "legendConfig": {
        "marks": {
          "type": "rect",
          "from": {
            "data": "table"
          }
        }
      },
      "applicationConfig": {},
      "staticImageConfig": {}
    }
  },
  "meta": {
    "status": "saved",
    "published": true,
    "updatedAt": "2017-01-23T16:51:42.571Z",
    "createdAt": "2017-01-23T16:51:42.571Z"
  }
}

Create a Layer

To create a layer, you need to define all of the required fields in the request body. The fields that compose a layer are:

Field Description Type Values Required
name Name of the layer Text Any Text Yes
description Description of the dataset Text Any text No
application Application to which the layer belongs Array gfw, forest-atlas, rw, prep, aqueduct, data4sdg Yes
layerConfig Custom configuration Object Valid object No
legendConfig Custom configuration Object Valid object No
applicationConfig Custom configuration Object Valid object No
staticImageConfig Custom configuration Object Valid object No
iso Isos to which the layer belongs Array BRA, ES No
status Status of the Layer Number 1 No
dataset UuId of the dataset Text Uuid of Dataset No

To create a layer, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/<dataset_id>/layer \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "layer": {
      "application":[
         "your", "apps"
      ],
      "name":"Example layer",
      "status": 1
   }
}'

Update a Layer

To update a layer, you need to define all of the required fields in the request body. The fields that compose a layer are:

Field Description Type Values Required
name Name of the layer Text Any Text Yes
description Description of the dataset Text Any text No
application Application to which the layer belongs Array gfw, forest-atlas, rw, prep, aqueduct, data4sdg Yes
layerConfig Custom configuration Object Valid object No
legendConfig Custom configuration Object Valid object No
applicationConfig Custom configuration Object Valid object No
staticImageConfig Custom configuration Object Valid object No
iso Isos to which the layer belongs Array BRA, ES No
status Status of the Layer Number 1 No
dataset UuId of the dataset Text Uuid of Dataset No

To create a layer, you have to do a POST with the following body:

curl -X PATCH https://production-api.globalforestwatch.org/v1/dataset/<dataset_id>/layer/<layer_id> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "layer": {
      "application":[
         "your", "apps"
      ],
      "name":"New Example layer Name",
      "layerConfig": {}
   }
}'

Delete a Layer

curl -X DELETE https://production-api.globalforestwatch.org/v1/dataset/<dataset_id>/layer/<layer_id> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"

Query

In order to retrieve data from the datasets it is possible query in SQL or Feature Service languages to the API.

It is possible to query the dataset using the table name of the dataset or just the id or slug of it.

/query/?sql=select * from /query?sql=select * from

Query examples

# Select and aggregations

select * from table
select count(*) from table
select a, b from table
select a, count(*) from table

# Functions and alias

select sum(int) from table
select avg(int) from table
select max(int) from table
select min(int) from table
select min(int) as minimun from table

select * from table limit=20
select a as b from table limit=20

# Where conditionals

select * from table where a > 2
select * from table where a = 2
select * from table where a < 2
select * from table where a >= 2
select * from table where a = 2 and b < 2
select * from table where text like ‘a%’
Select * from table where st_intersects(st_setsrid(st_geomfromgeojson(‘{}’), 4326), the_geom)

# Group by

select a, count(int) from table group by a
select count(*) FROM tablename group by ST_GeoHash(the_geom, 8)

Rasdaman queries

Rasdaman datasets do not expose a SQL interface from where to query the data – instead it offers interfaces to WCPS (the OGC Web Coverage Processing Service) and RasQL (a superset of SQL dealing with coverages). So far only WCPS is supported in the GFW API. Two different endpoints are offered: one to directly run WCPS queries against the database, and one that abstracts the calculation of (2D) zonal statistics on rasdaman coverages with vector masks. For more information on the WCPS standard, consult the OGC page about it

In order to run a query directly, POST your query in the wcps attribute to the endpoint:

curl -i -H 'Authorization: Bearer your-token>' -H 'Content-Type: application/json' -XPOST 'http://production-api.globalforestwatch.org/v1/query/491ae6fe-6767-44d1-b5c3-c7b8b384bb7a/' -d '{
    "wcps": "FOR c in (nightlights) return 1"
}
'

The result of a WCPS query can have varying dimensionality, depending of the axes of the original dataset. The result must be encoded in an appropriate file format, which is done with the encode WCPS function. A large variety of formats is supported (as the underlying implementation depends on GDAL), but some care has to be taken to match the dimensionality of the query output with one that the desired format supports. For subsetting the domain of the original coverage, trimming and slicing can be used too:

curl -i -H 'Authorization: Bearer <your-token>' -H 'Content-Type: application/json' -XPOST 'http://production-api.globalforestwatch.org/v1/query/491ae6fe-6767-44d1-b5c3-c7b8b384bb7a/' -d '{
    "wcps":  "for cov in (nightlights) return encode( cov[ Long(-1:1), Lat(-1:1)], \"CSV\")"
}
'

For zonal stats, use the ‘stats’ endpoint. The geostore will be used to generate spatial masks. If the original coverage is not 2-dimensional, additional subsettings have to be specified in the requests as 'additionalAxes’ to reduce the coverage dimensionality. The most usual subsetting will be a time slice that has to be specified as an ANSI (ISO 8601) date –with the appropriate level of granularity.

curl -i -H 'Authorization: Bearer <your-token>' -H 'Content-Type: application/json' -XPOST 'http://production-api.globalforestwatch.org/v1/stats/e9c3a94d-6b1c-4513-a745-6acdff53cfc9' -d '{
    "geostore": "70ba01daaa803aea2eeff502c845bcef",
    "additionalAxes": {
        "ansi": "1950-03-03"
    }
}
'

Response

{
    "data": [
        {
            "min": 0,
            "max": 0.00016111972217913717,
            "mean": 2.019295106901743e-05,
            "count": 993
        }
    ]
}

Fields

What are fields?

Fields can be defined as the dataset properties. These fields are automatically generated when a dataset is created.

How to get the dataset fields

Once the dataset is properly created and saved, it is possible to access to its fields getting also some information about them.

To do that, it is just necessary to make use of the following endpoint:

curl -X GET https://production-api.globalforestwatch.org/v1/fields/<dataset-id>

Real example

curl -X GET https://production-api.globalforestwatch.org/v1/fields/1170030b-9725-4bfe-8fb4-1b0eb81020d2

Response

{
    "tableName": "public.cait_2_0_country_ghg_emissions_toplow2011",
    "fields": {
        "cartodb_id": {
            "type": "number"
        },
        "the_geom": {
            "type": "geometry"
        },
        "the_geom_webmercator": {
            "type": "geometry"
        },
        "x": {
            "type": "string"
        },
        "y": {
            "type": "number"
        },
        "z": {
            "type": "string"
        }
    }
}

Rasdaman

The structure of datacubes needs of a more verbose fields specification. The fields endpoint for rasdaman-backed datasets includes information on the spatial reference system, nodata values, axes, units, and bands. It looks like so:

Example

curl -i  -XGET 'http://production-api.globalforestwatch.org/v1/fields/491ae6fe-6767-44d1-b5c3-c7b8b384bb7a' 

Response

{
  "coverageId": "nightlights",
  "srs": {
    "srsDimension": "2",
    "srs": "crs/EPSG/0/4326"
  },
  "axisLabels": "Lat Long",
  "uomLabels": "degree degree",
  "fields": {
    "undefined": {
      "swe:nilValues": {
        "swe:NilValues": {
          "swe:nilValue": [
            {
              "reason": "",
              "$t": "1"
            },
            {
              "reason": "",
              "$t": "2"
            }
          ]
        }
      },
      "swe:uom": {
        "code": "10^0"
      }
    }
  },
  "coverageBounds": {
    "upperCorner": "89.999999999966665 180.000000000189335",
    "lowerCorner": "-89.999999999961335 -179.999999999666665"
  }
}

Metadata

Metadata definition

A Metadata can be any kind of data associated to an existing resource (i.e. Dataset, Layer or Widget)

Some fields are important to identify the entity properly, others are just optional and give extra information about it.

Field Description Type
application The metadata application String
language The metadata language String
dataset The associated dataset id to the metadata String
resource The resource associated to the metadata Object
– id Resource id String
– type Resource type String
name The metadata name String
description The metadata description String
source The metadata source String
citation The metadata citation String
license The metadata license type String
info Some info about the metadata Object
units Measurement units Object

Creating a metadata object

Field Required/Optional
application required
language required
dataset required
name optional
description optional
source optional
citation optional
license optional
info optional
units optional

“application” and “language” attributes are required and it is mandatory to include them in the payload.

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/<dataset-id>/metadata \
-H "Content-Type: application/json"  -d \
 '{
   "application": <app>,
   "language": <language>
  }'

Real example

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/metadata \
-H "Content-Type: application/json"  -d \
 '{
   "application": "rw",
   "language": "en"
  }'

Response: 200 OK HTTP RESPONSE + JSON-API-LIKE BODY

{
  "data": [
    {
      "id": "942b3f38-9504-4273-af51-0440170ffc86-dataset-942b3f38-9504-4273-af51-0440170ffc86-rw-en",
      "type": "metadata",
      "attributes": {
        "dataset": "942b3f38-9504-4273-af51-0440170ffc86",
        "application": "rw",
        "resource": {
          "type": "dataset",
          "id": "942b3f38-9504-4273-af51-0440170ffc86"
        },
        "language": "en",
        "createdAt": "2017-01-20T08:07:53.272Z",
        "updatedAt": "2017-01-20T08:07:53.272Z",
        "status": "published"
      }
    }
  ]
}

It could response a 401 status code if the request is not authenticated, 403 if the request is not allowed to do that operation, 400 if the request is not well formatted or 5XX HTTP codes in other cases

The same operation applies to Widget and Layer just changing the endpoint for the appropriate one.

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/metadata \
-H "Content-Type: application/json"  -d \
 '{
   "application": <app>,
   "language": <language>
  }'
curl -X POST https://production-api.globalforestwatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/metadata \
-H "Content-Type: application/json"  -d \
 '{
   "application": <app>,
   "language": <language>
  }'

Getting metadata

application filter: application: gfw, gfw-climate, prep, rw, forest-atlas (select one or some of them)

language filter: language: select between available languages (select one or some of them)

limit filter: limit: the desired number

Custom param for /metadata endpoint type: [dataset, widget, layer]

curl -X GET https://production-api.globalforestwatch.org/v1/dataset/<dataset-id>/metadata
curl -X GET https://production-api.globalforestwatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/metadata
curl -X GET https://production-api.globalforestwatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/metadata

Real example

curl -X GET https://production-api.globalforestwatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/metadata

Updating a metadata

Partial update

“application” and “language” attributes are required and it is mandatory to include them in the payload.

curl -X PATCH https://production-api.globalforestwatch.org/v1/dataset/<dataset-id>/metadata \
-H "Content-Type: application/json"  -d \
 '{
   "application": <app>,
   "language": <language>
  }'

Real example

curl -X PATCH https://production-api.globalforestwatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/metadata \
-H "Content-Type: application/json"  -d \
 '{
   "application": "rw",
   "language": "en",
   "name": "Cloud Computing Market - USA - 2016",
   "source": "http://www.forbes.com/",
   "info": {
       "summary": "These and many other insights are from the latest series of cloud computing forecasts and market estimates produced by IDC, Gartner, Microsoft and other research consultancies. Amazon’s decision to break out AWS revenues and report them starting in Q1 FY2015 is proving to be a useful benchmark for tracking global cloud growth.  In their latest quarterly results released on January 28, Amazon reported that AWS generated $7.88B in revenues and attained a segment operating income of $1.863B. Please see page 8 of the announcement for AWS financials.  For Q4, AWS achieved a 28.5% operating margin (% of AWS net sales).",
       "author": "Louis Columbus",
       "date": "MAR 13, 2016 @ 10:42 PM",
       "link": "http://www.forbes.com/sites/louiscolumbus/2016/03/13/roundup-of-cloud-computing-forecasts-and-market-estimates-2016/#5875cf0074b0"
   }
  }'

Response

{
  "data": [
    {
      "id": "942b3f38-9504-4273-af51-0440170ffc86-dataset-942b3f38-9504-4273-af51-0440170ffc86-rw-en",
      "type": "metadata",
      "attributes": {
        "dataset": "942b3f38-9504-4273-af51-0440170ffc86",
        "application": "rw",
        "resource": {
          "type": "dataset",
          "id": "942b3f38-9504-4273-af51-0440170ffc86"
        },
        "language": "en",
        "name": "Cloud Computing Market - USA - 2016",
        "source": "http://www.forbes.com/",
        "info": {
          "summary": "These and many other insights are from the latest series of cloud computing forecasts and market estimates produced by IDC, Gartner, Microsoft and other research consultancies. Amazon’s decision to break out AWS revenues and report them starting in Q1 FY2015 is proving to be a useful benchmark for tracking global cloud growth.  In their latest quarterly results released on January 28, Amazon reported that AWS generated $7.88B in revenues and attained a segment operating income of $1.863B. Please see page 8 of the announcement for AWS financials.  For Q4, AWS achieved a 28.5% operating margin (% of AWS net sales).",
          "author": "Louis Columbus",
          "date": "MAR 13, 2016 @ 10:42 PM",
          "link": "http://www.forbes.com/sites/louiscolumbus/2016/03/13/roundup-of-cloud-computing-forecasts-and-market-estimates-2016/#5875cf0074b0"
        },
        "createdAt": "2017-01-20T08:07:53.272Z",
        "updatedAt": "2017-01-20T08:40:30.190Z",
        "status": "published"
      }
    }
  ]
}

Deleting a metadata

“application” and “language” attributes are required and it is mandatory to include them in the Queryparams

curl -X DELETE https://production-api.globalforestwatch.org/v1/dataset/<dataset-id>/metadata?application=<app-id>&language=<language>

Real example

curl -X DELETE https://production-api.globalforestwatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/metadata?application=rw&language=en \

Getting all

curl -X GET https://production-api.globalforestwatch.org/v1/metadata

Real examples

curl -X GET https://production-api.globalforestwatch.org/v1/metadata
curl -X GET https://production-api.globalforestwatch.org/v1/metadata?type=dataset
curl -X GET https://production-api.globalforestwatch.org/v1/metadata?type=widget
curl -X GET https://production-api.globalforestwatch.org/v1/metadata?application=rw&language=es,en&limit=20
curl -X GET https://production-api.globalforestwatch.org/v1/metadata?application=rw,gfw&language=en&type=dataset
curl -X GET https://production-api.globalforestwatch.org/v1/metadata?language=en

Finding (getting) by ids

“ids” property is required in the payload, in other case the endpoint responds a 400 HTTP ERROR (Bad Request) This property can be an Array or a String (comma-separated) payload -> {“ids”: [“112313”, “111123”]} payload -> {“ids”: “112313, 111123”}

application filter: application: gfw, gfw-climate, prep, rw, forest-atlas (select one or some of them)

language filter: language: select between available languages (select one or some of them)

limit filter: limit: the desired number

Custom param for /metadata endpoint type: [dataset, widget, layer]

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/metadata/find-by-ids \
-H "Content-Type: application/json"  -d \
 '{
   "ids": [<ids>]
  }'

Real example

curl -X POST https://production-api.globalforestwatch.org/v1/dataset/metadata/find-by-ids \
-H "Content-Type: application/json"  -d \
 '{
     "ids": "b000288d-7037-43ba-aa34-165eab549613, 942b3f38-9504-4273-af51-0440170ffc86"
  }'

Response

{
  "data": [
    {
      "id": "b000288d-7037-43ba-aa34-165eab549613-dataset-b000288d-7037-43ba-aa34-165eab549613-prep-en",
      "type": "metadata",
      "attributes": {
        "dataset": "b000288d-7037-43ba-aa34-165eab549613",
        "application": "prep",
        "resource": {
          "type": "dataset",
          "id": "b000288d-7037-43ba-aa34-165eab549613"
        },
        "language": "en",
        "name": "Projected temperature change",
        "description": "The Puget Sound region is projected to warm rapidly during the 21st century. Prior to mid-century, the projected increase in air temperatures is about the same for all greenhouse gas scenarios, a result of the fact that a certain amount of warming is already “locked in” due to past emissions. After about 2050, projected warming depends on the amount of greenhouse gases emitted globally in the coming decades. For the 2050s (2040-2069, relative to 1970-1999), annual average air temperature is projected to rise +4.2°F to +5.9°F, on average, for a low (RCP 4.5) and a high (RCP 8.5) greenhouse gas scenario. These indicators are derived from the Multivariate Adaptive Constructed Analogs (MACA) CMIP5 Future Climate Dataset from the University of Idaho. For more information about this analysis, please see http://cses.washington.edu/picea/mauger/ps-sok/ps-sok_sec12_builtenvironment_2015.pdf. For more information about the MACA CMIP5 Future Climate Dataset please see http://maca.northwestknowledge.net/index.php",
        "source": "http://maca.northwestknowledge.net",
        "citation": "Abatzoglou, J. T.,   Brown, T. J. 2012. A comparison of statistical downscaling methods suited for wildfire applications. International Journal of Climatology, 32(5), 772-780. doi: http://dx.doi.org/10.1002/joc.2312 ",
        "license": "Public domain",
        "info": {
          "organization": "Joe Casola, University of Washington",
          "license": "Public domain",
          "source": "http://maca.northwestknowledge.net",
          "citation": "Abatzoglou, J. T.,   Brown, T. J. 2012. A comparison of statistical downscaling methods suited for wildfire applications. International Journal of Climatology, 32(5), 772-780. doi: http://dx.doi.org/10.1002/joc.2312 ",
          "description": "The Puget Sound region is projected to warm rapidly during the 21st century. Prior to mid-century, the projected increase in air temperatures is about the same for all greenhouse gas scenarios, a result of the fact that a certain amount of warming is already “locked in” due to past emissions. After about 2050, projected warming depends on the amount of greenhouse gases emitted globally in the coming decades. For the 2050s (2040-2069, relative to 1970-1999), annual average air temperature is projected to rise +4.2°F to +5.9°F, on average, for a low (RCP 4.5) and a high (RCP 8.5) greenhouse gas scenario. These indicators are derived from the Multivariate Adaptive Constructed Analogs (MACA) CMIP5 Future Climate Dataset from the University of Idaho. For more information about this analysis, please see http://cses.washington.edu/picea/mauger/ps-sok/ps-sok_sec12_builtenvironment_2015.pdf. For more information about the MACA CMIP5 Future Climate Dataset please see http://maca.northwestknowledge.net/index.php",
          "short-description": "Projected temperature change in the Puget Sound Lowlands relative to average temperature between 1950-2005. Light colored lines in the background show the range of projections. All climate scenarios project warming for the Puget Sound region during the 21st century.",
          "subtitle": "",
          "title": "Projected temperature change"
        },
        "createdAt": "2016-12-13T10:02:28.337Z",
        "updatedAt": "2016-12-13T10:03:02.445Z",
        "status": "published"
      }
    },
    {
      "id": "942b3f38-9504-4273-af51-0440170ffc86-dataset-942b3f38-9504-4273-af51-0440170ffc86-rw-en",
      "type": "metadata",
      "attributes": {
        "dataset": "942b3f38-9504-4273-af51-0440170ffc86",
        "application": "rw",
        "resource": {
          "type": "dataset",
          "id": "942b3f38-9504-4273-af51-0440170ffc86"
        },
        "language": "en",
        "name": "Cloud Computing Market - USA - 2016",
        "source": "http://www.forbes.com/",
        "info": {
          "link": "http://www.forbes.com/sites/louiscolumbus/2016/03/13/roundup-of-cloud-computing-forecasts-and-market-estimates-2016/#5875cf0074b0",
          "date": "MAR 13, 2016 @ 10:42 PM",
          "author": "Louis Columbus",
          "summary": "These and many other insights are from the latest series of cloud computing forecasts and market estimates produced by IDC, Gartner, Microsoft and other research consultancies. Amazon’s decision to break out AWS revenues and report them starting in Q1 FY2015 is proving to be a useful benchmark for tracking global cloud growth.  In their latest quarterly results released on January 28, Amazon reported that AWS generated $7.88B in revenues and attained a segment operating income of $1.863B. Please see page 8 of the announcement for AWS financials.  For Q4, AWS achieved a 28.5% operating margin (% of AWS net sales)."
        },
        "createdAt": "2017-01-20T08:07:53.272Z",
        "updatedAt": "2017-01-20T08:40:30.190Z",
        "status": "published"
      }
    }
  ]
}

Geostore

What is Geostore?

Geostore is a geojson database. You can save your geojson or obtain geojson from country, region, Protected areas, etc.

Geostore object contains the next fields:

Field Description Type
id Id of the geostore Text
geojson Geojson with the geometry Object
hash MD5 hash generated from geojson. Is the same that the id Object
provider This field is completed, if the geostore was created from a provider Object
– type Provider type Text
– table Table name Text
– user User of the account Text
– filter Conditions to obtain the geojson. Is possible put and and or conditions. This conditions must only return one row. Text
areaHa Area in Hectares of the geojson Number
bbox Bounding box of the geojson Array

Create Geostore

You can create a geostore from 4 different ways:

With a Geojson

If you have your own geojson, you can save it in geostore. To create the geostore, you need to define all the required fields in the request body. The fields that compose a geostore are:

Field Description Type Values Required
geojson Geojson with your geometry Object Yes

To create a Geostore, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/geostore \
-H "Content-Type: application/json"  -d \
 '{
   "geojson": <yourGeoJSONObject>
  }'

Real example

curl -X POST https://production-api.globalforestwatch.org/v1/geostore \
-H "Content-Type: application/json"  -d \
 '{
   "geojson":{
      "type":"FeatureCollection",
      "features":[
         {
            "type":"Feature",
            "properties":{

            },
            "geometry":{
               "type":"LineString",
               "coordinates":[
                  [
                     -3.9942169189453125,
                     41.044922165782175
                  ],
                  [
                     -3.995418548583985,
                     41.03767166215326
                  ],
                  [
                     -3.9842605590820312,
                     41.03844854003296
                  ],
                  [
                     -3.9844322204589844,
                     41.04589315472392
                  ],
                  [
                     -3.9942169189453125,
                     41.044922165782175
                  ]
               ]
            }
         },
         {
            "type":"Feature",
            "properties":{

            },
            "geometry":{
               "type":"Polygon",
               "coordinates":[
                  [
                     [
                        -4.4549560546875,
                        40.84706035607122
                     ],
                     [
                        -4.4549560546875,
                        41.30257109430557
                     ],
                     [
                        -3.5211181640624996,
                        41.30257109430557
                     ],
                     [
                        -3.5211181640624996,
                        40.84706035607122
                     ],
                     [
                        -4.4549560546875,
                        40.84706035607122
                     ]
                  ]
               ]
            }
         }
      ]
   }
}'

The response will be 200 if the geostore will save correctly and return the geostore object with all information:

Example response

{
   "data":{
      "type":"geoStore",
      "id":"c9bacccfb9c3fe225dc67545bb93a5cb",
      "attributes":{
         "geojson":{
            "features":[
               {
                  "type":"Feature",
                  "geometry":{
                     "type":"Polygon",
                     "coordinates":[
                        [
                           [
                              -4.4549560546875,
                              40.84706035607122
                           ],
                           [
                              -4.4549560546875,
                              41.30257109430557
                           ],
                           [
                              -3.5211181640624996,
                              41.30257109430557
                           ],
                           [
                              -3.5211181640624996,
                              40.84706035607122
                           ],
                           [
                              -4.4549560546875,
                              40.84706035607122
                           ]
                        ]
                     ]
                  }
               }
            ],
            "crs":{

            },
            "type":"FeatureCollection"
         },
         "hash":"c9bacccfb9c3fe225dc67545bb93a5cb",
         "provider":{

         },
         "areaHa":397372.34122605197,
         "bbox":[
            -4.4549560546875,
            40.84706035607122,
            -3.5211181640624996,
            41.30257109430557
         ]
      }
   }
}

From country

If you need obtain the geostore of a country, you can obtain it with the ISO3 code in the Geostore API.

GET https://production-api.globalforestwatch.org/v1/geostore/admin/<ISO3>

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/admin/<ISO3>

Real example obtaining the geostore of Spain shell curl -X GET https://production-api.globalforestwatch.org/v1/geostore/admin/ESP

From country and region

If you need obtain the geostore of a region in a country, you can obtain it with the ISO3 and region code:

GET https://production-api.globalforestwatch.org/v1/geostore/admin/<ISO3>/<regionCode>

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/admin/<ISO3>/<regionCode>

Real example obtaining the geostore of Madrid’s Comunity in Spain

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/admin/ESP/8

From World Database on Protected Areas (wdpa)

Is possible obtain the geostore of a World Database on Protected Areas of the world. You only need the id of the protected area (WDPA). World Database on Protected Areas web

GET https://production-api.globalforestwatch.org/v1/geostore/wdpa/<wdpaId>

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/wdpa/<wdpaId>

Real example obtaining the geostore of ‘Sierra de Guadarrama’ protected area

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/wdpa/555538160

From land use areas

Geostore has the geojson of 4 differents lands use:

Oil palm

GET https://production-api.globalforestwatch.org/v1/geostore/use/oilpalm/<id>

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/oilpalm/<id>

Real example obtaining the geostore of one Oil palm area

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/oilpalm/556

Mining

GET https://production-api.globalforestwatch.org/v1/geostore/use/mining/<id>

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/mining/<id>

Real example obtaining the geostore of one mining area

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/mining/573

Wood fiber

GET https://production-api.globalforestwatch.org/v1/geostore/use/fiber/<id>

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/fiber/<id>

Real example obtaining the geostore of one Wood fiber area

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/fiber/346

Congo Basin logging roads

GET https://production-api.globalforestwatch.org/v1/geostore/use/logging/<id>

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/logging/<id>

Real example obtaining the geostore of Oil palm area

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/logging/102

From Carto

If your geojson is in carto table, is possible import this geojson in geostore. To import the geojson in geostore, you need to define all of the required fields in the request body. The fields that compose a import are:

Field Description Type Values Required
provider Provider of data Object Yes
– type Provider type Text carto Yes
– table Table name Text Yes
– user User of the account Text Yes
– filter Conditions to obtain the geojson. Is possible put and and or conditions. This conditions must only return one row. Text Yes

To import a Geostore, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/geostore \
-H "Content-Type: application/json"  -d \
 '{
    "provider":{
        "type": "carto",
        "table": <tableName>,
        "user": <userName>,
        "filter": <conditions>
    }
}'

Real example

curl -X POST https://production-api.globalforestwatch.org/v1/geostore \
-H "Content-Type: application/json"  -d \
 '{
    "provider":{
        "type": "carto",
        "table": "gfw_mining",
        "user": "wri-01",
        "filter": "cartodb_id=573"
    }
}'

Example response

{
  "data": {
    "type": "geoStore",
    "id": "26f8975c4c647c19a2edaa11f23880a2",
    "attributes": {
      "geojson": {
        "features": [
          {
            "type": "Feature",
            "geometry": {
              "type": "MultiPolygon",
              "coordinates": [
                [
                  [
                    [
                      -74.0957370284411,
                      10.6814701233475
                    ],
                    [
                      -74.0957357154309,
                      10.654348341203
                    ],
                    [
                      -74.1100850695703,
                      10.6543473339623
                    ],
                    [
                      -74.1100876551212,
                      10.6814691125096
                    ],
                    [
                      -74.0957370284411,
                      10.6814701233475
                    ]
                  ]
                ]
              ]
            }
          }
        ],
        "crs": {},
        "type": "FeatureCollection"
      },
      "hash": "26f8975c4c647c19a2edaa11f23880a2",
      "provider": {
        "filter": "cartodb_id=573",
        "user": "wri-01",
        "table": "gfw_mining",
        "type": "carto"
      },
      "areaHa": 471.001953054716,
      "bbox": [
        -74.1100876551212,
        10.6543473339623,
        -74.0957357154309,
        10.6814701233475
      ]
    }
  }
}

Obtain a Geostore

To obtain a geostore, you only need the id of the Geostore. You can perform a GET request for the geostore with its id.

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/<geostoreId>

Real example obtaining one geostore

curl -X GET https://production-api.globalforestwatch.org/v1/geostore/use/logging/26f8975c4c647c19a2edaa11f23880a2

Example response

{
  "data": {
    "type": "geoStore",
    "id": "26f8975c4c647c19a2edaa11f23880a2",
    "attributes": {
      "geojson": {
        "features": [
          {
            "type": "Feature",
            "geometry": {
              "type": "MultiPolygon",
              "coordinates": [
                [
                  [
                    [
                      -74.0957370284411,
                      10.6814701233475
                    ],
                    [
                      -74.0957357154309,
                      10.654348341203
                    ],
                    [
                      -74.1100850695703,
                      10.6543473339623
                    ],
                    [
                      -74.1100876551212,
                      10.6814691125096
                    ],
                    [
                      -74.0957370284411,
                      10.6814701233475
                    ]
                  ]
                ]
              ]
            }
          }
        ],
        "crs": {},
        "type": "FeatureCollection"
      },
      "hash": "26f8975c4c647c19a2edaa11f23880a2",
      "provider": {
        "filter": "cartodb_id=573",
        "user": "wri-01",
        "table": "gfw_mining",
        "type": "carto"
      },
      "areaHa": 471.001953054716,
      "bbox": [
        -74.1100876551212,
        10.6543473339623,
        -74.0957357154309,
        10.6814701233475
      ]
    }
  }
}

Subscriptions

Create Subscription

Field Description Type
name Name Text
application Application of the subscription gfw, rw, prep
language Language of the subscriptions (it’s used to select the email template) en, es, fr, pt, zh
resource This field contains if the subscription is of type email or hook Object
– type Type EMAIL or URL
– content Email or url Text
datasets Array of datasets of the subscription Array
datasetsQuery Subscriptions to datasets subscribibles Array
– id Id of dataset ObjectId
– type Type of subscription defined in the dataset Text
– params Geographic area of the subscription Object

It’s only required datasets or datasetsQuery, not both.

You can create a subscription with 6 different params:

With a area

Field Description Type
params Geographic area of the subscription Object
– area Id of area object Text (ObjectId)

To create a Subscription, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "area": "<idArea>"
   }
  }'

From country

Field Description Type
params Geographic area of the subscription Object
– iso Country or region information Object
—- country Iso code Text

To create a Subscription, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "iso": {
           "country": "<iso>"
       }
   }
  }'

From country and region

Field Description Type
params Geographic area of the subscription Object
– iso Country or region information Object
—- country Iso code Text
—- region Region code Number

To create a Subscription, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "iso": {
           "country": "<iso>",
           "region": "<region>"
       }
    }
  }'

From World Database on Protected Areas (wdpa)

Field Description Type
params Geographic area of the subscription Object
– wdpaid id of protected area Number

To create a Subscription, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "wdpaid": <idWdpa>
    }
  }'

From land use areas

Field Description Type
params Geographic area of the subscription Object
– use Use name Text
– useid Id use Number

To create a Subscription, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "use": "<useName>",
       "useid": <id>
    }
  }'

Subscription has 4 differents lands use:

Oil palm

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "use": "oilpalm",
       "useid": <id>
    }
  }'

Mining

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "use": "mining",
       "useid": <id>
    }
  }'

Wood fiber

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "use": "fiber",
       "useid": <id>
    }
  }'

Congo Basin logging roads

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "use": "logging",
       "useid": <id>
    }
  }'

From geostore

Field Description Type
params Geographic area of the subscription Object
– geostore Id of geostore Text

To create a Subscription, you have to do a POST with the following body:

curl -X POST https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "geostore": "<idGeostore>"
    }
  }'

Confirm subscription

All subscriptions are created unconfirmed. The user needs confirm his subscription with this endpoint.

curl -X GET https://production-api.globalforestwatch.org/v1/subscriptions/:id/confirm

Obtain the subscriptions of a user

To get the user subscriptions:

curl -X GET https://production-api.globalforestwatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>"

Response:


{
   "data":[
      {
         "type":"subscription",
         "id":"587cc014f3b3f6280058e478",
         "attributes":{
            "name":"test",
            "createdAt":"2017-01-16T12:45:08.434Z",
            "userId":"57a063da096c4eda523e99ae",
            "resource":{
               "type":"EMAIL",
               "content":"pepe@gmail.com"
            },
            "datasets":[
               "viirs-active-fires"
            ],
            "params":{
               "iso":{
                  "region":null,
                  "country":null
               },
               "wdpaid":null,
               "use":null,
               "useid":null,
               "geostore":"50601ff9257df221e808af427cb47701"
            },
            "confirmed":false,
            "language":"en",
            "datasetsQuery":[

            ]
         }
      }
   ]
}

Resend confirmation

To resend the confirmation

curl -X PATCH https://production-api.globalforestwatch.org/v1/subscriptions/:id/send_confirmation \
-H "Authorization: Bearer <your-token>"

Modify subscription

To modify a subscription

curl -X PATCH https://production-api.globalforestwatch.org/v1/subscriptions/:id \
-H "Authorization: Bearer <your-token>"

With the same body that create subscription.

Unsubscribe

To unsubscribe a subscription

curl -X GET https://production-api.globalforestwatch.org/v1/subscriptions/:id/unsubscribe \
-H "Authorization: Bearer <your-token>"

Delete subscription

To delete a subscription (same that unsubscribe)

curl -X DELETE https://production-api.globalforestwatch.org/v1/subscriptions/:id/unsubscribe \
-H "Authorization: Bearer <your-token>"

Errors

The Global Forest Watch API uses the following error codes:

Error Code Meaning
400 Bad Request – Your request is incomplete or contains errors
401 Unauthorized – Your API key is wrong
403 Forbidden – The kitten requested is hidden for administrators only
404 Not Found – The specified kitten could not be found
405 Method Not Allowed – You tried to access a kitten with an invalid method
406 Not Acceptable – You requested a format that isn’t json
410 Gone – The kitten requested has been removed from our servers
429 Too Many Requests – You’re requesting too many kittens! Slow down!
500 Internal Server Error – We had a problem with our server. Try again later.
503 Service Unavailable – We’re temporarially offline for maintanance. Please try again later.