NAV Navbar
Logo rw
cURL

Introduction

Welcome to the Resource Watch API Documentation

About these docs

This documentation page aims to cover the Resource Watch API functionality and details. In it, you’ll find a top-level description of the services it provides, as well as a breakdown of the different endpoints, their functionality, parameters and output. The goal is to give you the tools to create powerful applications and data products.

The RW API is HTTP and JSON based, and these docs assume you are familiar with both technologies. Besides endpoint descriptions, the documentation will include example code snippets that use cURL to illustrate how you would use each endpoint. Knowing the basics of cURL will help you better understand those examples.

For readability, URLs and query parameters may be displayed without escaping/encoding, but be sure to encode your URLs before issuing a request to the API, or it may produce undesired results. If you are using the RW API to build your own application, there’s probably a library out there that does this for you automatically.

In these examples, you’ll also find references to a Authorization: Bearer <your-token> HTTP header. You can find more details about tokens in the authentication section, which you should read before you get started.

Last but not least, the RW API and its docs are made by humans, who will occasionally make mistakes. If you find something that you think is incorrect, could be improved, if you want to contribute yourself, or just want to say “thank you”, you can reach us through the RW API documentation Github project page.

Concepts

Dataset

One of the Resource Watch API’s (RW API) goals is to provide a common interface for interacting with data hosted in different sources and formats. A Dataset is the Resource Watch’s API way of providing users with access to data, while trying to, as much as possible, abstract and standardise operations that would otherwise fall on the user’s hands to figure out. It’s one of the cornerstones that many other API features build upon - and those features can help you get even more out of your data!

Example: A Resource Watch API dataset can represent data in a JSON file, hosted on Carto or Google Earth Engine, to name a few. However, when accessing that data, you don’t have to learn 3 different technologies - the Resource Watch API gives you a single, unified query interface.

On top of datasets, the RW API offers multiple resources that allow you to access data in multiple formats. These will be covered later in full detail, but as an example, here are some ways in which you can access and use datasets:

Dataset providers

Each dataset has a provider (json/carto/GEE/…) that must specified on creation - it’s this value that tells the RW API how to handle different data providers and formats, so you don’t have to. Below you’ll find a list of the different providers supported:

Carto

Carto is an open, powerful, and intuitive map platform for discovering and predicting key insights underlying the location data in our world.

ArcGIS feature layer

ArcGIS server is a complete, cloud-based mapping platform. You can learn more about ArcGIS here.

Google Earth Engine

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.

Web Map Services

WMS connector provides access to data served through OGC WMS protocol standard.

Rasdaman (Raster Data Manager)

Rasdaman is a database with capabilities for storage, manipulation and retrieval of multidimensional arrays.

NEX-GDDP

The NASA Earth Exchange Global Daily Downscaled Projections (NEX-GDDP) dataset is comprised of downscaled climate scenarios for the globe that are derived from the General Circulation Model (GCM) runs conducted under the Coupled Model Intercomparison Project Phase 5 (CMIP5) and across two of the four greenhouse gas emissions scenarios known as Representative Concentration Pathways (RCPs).

Note: While you may find and use existing dataset of this type, creation of new NEX-GDDP based datasets is restricted to specific users.

BigQuery

BigQuery is a serverless, highly scalable, and cost-effective cloud data warehouse designed to help you make informed decisions quickly, so you can transform your business with ease.

Note: While you may find and use existing dataset of this type, creation of new BigQuery based datasets is restricted to specific users.

Loca

LOCA, which stands for Localized Constructed Analogs, is a technique for downscaling climate model projections of the future climate.

Note: While you may find and use existing dataset of this type, creation of new LOCA based datasets is restricted to specific users.

Comma-Separated Values (CSV)

Data provided in the form of a Comma-Separated Values (CSV) document.

Tab-Separated Values (TSV)

Data provided in the form of a Tab-Separated Values (TSV) document.

JavaScript Object Notation (JSON)

Data provided in the form of a JSON document.

Extensible (X) Markup Language (XML)

Data provided in the form of a XML document.

Dataset connector type

Each dataset provider has an associated connector type, which you can determine using the table below.

Connector type Providers
document csv, json, tsv, xml
rest cartodb, featureservice, gee, bigquery, rasdaman, nexgddp, loca
wms wms

The connector type reflects an important aspect of a dataset: where is the actual data kept, and how is it accessed:

Query

In the previous section, we covered the concept of a RW API dataset which, in simple terms, is a way to tell the RW API that your data exists, and where. While cataloging datasets in a public repository is useful, making that data easily accessible is one of the main goals of the RW API. This is where queries come in.

In the context of the RW API, a dataset query is very similar an SQL query would be to a database - it’s a specially crafted statement that allows you to express what data you want, from which dataset, and with which structure. The RW API will use that query to get you the data you need, in the format you asked for, so that it’s easy to use in the context of your applications. While it doesn’t comply (nor does it attempt to) with any of the formal SQL specifications, RW API queries use a SQL-like syntax that will be very familiar to anyone who has worked with a relational database in the past. If that’s not your case, there are many tutorials out there that will help you learn the basics in no time.

Using this common, SQL-based syntax, RW API queries allow you to query its datasets using a common API and syntax, no matter where the actual underlying data is hosted. Querying a carto dataset is the same as querying a JSON document or a BigQuery table. This is one of the main goals of the RW API, and one of most valuable features we offer you, the end user - using a single tool and language, you can quickly query data from a wide range of sources, on a broad set of topics.

In the query endpoint documentation below, we’ll go into more detail on how you can submit your queries to the API, the specifics of more advanced operations and detailed limitations of querying the RW API but, for now, there are 3 high-level ideas that you should keep in mind:

All queries should be SELECT queries

Querying in the RW API is meant to be used only to read data, not to manipulate it. If you have used SQL before, you know it can be used to modify data, but that’s not the approach used in the RW API. If you’d like to modify the data of a dataset, you should use the dataset update endpoints instead.

Not all SQL constructs are supported

If you’ve used SQL in the past, you know how powerful (and complex) it can be. Things like nested queries or joins can be hard to use and even more to maintain, even without the added complexity of an environment where multiple data providers coexist. That’s why the RW API limits its support to basic SQL syntax, so we can focus on delivering a tool that’s simple and easy to use for most users. The supported SQL syntax reference section below will go into more detail on what’s supported and what’s not, and will help you understand the specifics of what you can achieve with RW API queries.

Some operation will depend on the provider of the dataset you’re querying

Our goal is to provide a common querying interface across all datasets, independent of their provider. While we believe we’ve achieved it in most cases, RW API queries can only be as powerful as the underling provider (and their own APIs) allows them to be. There are cases in which a given SQL construct or function is supported for a given provider, but not for another. The supported SQL syntax reference below has more details on these limitations, per provider.

Authentication

The RW API uses JWT (JSON Web Tokens) to identify and authenticate its users. This token must be provided inside an Authorization header, with the form Bearer: <token>.

However, in order to perform GET requests for content that is not private, there’s no need for any sort of authentication or token.

How to generate your private token

  1. On the browser, visit the API’s login page at https://api.resourcewatch.org/auth/login.
  2. Login using your account.
  3. Once you are at auth/success, go to https://api.resourcewatch.org/auth/generate-token to generate a new token.

Auth success

Once generated, a token is valid until any of the associated user information (name, email, or associated applications) changes. If your token becomes invalid, you will need to log in and go to https://api.resourcewatch.org/auth/generate-token to generate a new token.

How to create a new user

To create a new user make a request like the one in the sidebar:

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

There are three allowed roles: USER, MANAGER and ADMIN. The ‘apps’ field only permits applications that are powered by the API: rw, gfw, prep, etc.

Contact

The following contact endpoints are available

Contact us

Sends a contact form including a topic, email address, and a message.

Example

Contact form sent using the type General question or feedback, the email address example@example.com and the message This is a text:

curl -X POST https://api.resourcewatch.org/v1/contact-us \
-H "Content-Type: application/json" -d \
    '{
        "topic": "General question or feedback",
        "email": "example.example@vizzuality.com",
        "text": "This is a test"
    }'

Collections

The users can save a collection of resources in the API.

Field Description Type
name Name of collection owner Text
ownerId Id of the owner Text
resources Resources in the collection Array of Objects
— type The type of resource Text (dataset, layer, widget)
— id The id of the resource Text

Create Collection

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

Field Description Type
name Name of collection owner Text

To create an empty collection, you have to do a POST with the following body:

curl -X POST https://api.resourcewatch.org/v1/collection \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>"
  }'

You can also add a resource in the body of the request when creating a new collection with the following body:

curl -X POST https://api.resourcewatch.org/v1/collection \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "resources": [
     {
      "type": "<type>",
      "id": "<id>"
      }
   ]
  }'

Update Collection

To update a collection, you should perform a PATCH request including the collection ID in the url. Here’s an example:

curl -X PATCH https://api.resourcewatch.org/v1/collection/<collection-id> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>"
  }'

Add Resource to Collection

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

Field Description Type
type Type of resource being added Text (dataset, layer, widget)
id Id of the resource Text

To add a resource to a collection, you have to do a POST with the following body:

curl -X POST https://api.resourcewatch.org/v1/collection/:id/resource \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "type": "<type>",
   "id": "<id>"
  }'

Get Collections

This endpoint returns the collections of the logged user.

To get all collections of the logged user, you have to do a GET request:

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

Get Collection by id

This endpoint returns the collection with id of the param. If the collection belongs to other user or not exist, the endpoint returns 400.

To get the collection by id, you have to do a GET request:

curl -X GET https://api.resourcewatch.org/v1/collection/:id \
-H "Authorization: Bearer <your-token>"

Delete Collection

This endpoint deletes the collection with id of the param. If the collection belongs to other user or not exist, the endpoint returns 400.

To delete the collection by id, you have to do a DELETE request:

curl -X DELETE https://api.resourcewatch.org/v1/collection/:id \
-H "Authorization: Bearer <your-token>"

Delete Collection Resource

Using this endpoint you can also delete a resource in a collection with the id, resource type and resource id of the param. If the collection belongs to other user or not exist, the endpoint returns 400.

To delete the resource you have to do a DELETE request:

curl -X DELETE https://api.resourcewatch.org/v1/collection/:id/resource/:resourceType/:resourceId \
-H "Authorization: Bearer <your-token>"

Dataset

What is a dataset?

If you are new to the RW API, or want to learn more about the concept of a dataset, we strongly encourage you to read the dataset concept documentation first. It gives you a brief and clear description of what a dataset is, and what it can do for you.

Once you’ve read that section, you can come back here to learn more details about using the RW API’s datasets feature. The RW API is home to many datasets uploaded by WRI, its partner organizations, or by API users like you. These datasets contain a lot of information about a wide range of topics that you may want to learn about or build on top of. To find out more about finding and accessing the datasets already available on the RW API, check out the documentation on getting datasets. A nice, visual way to explore existing datasets is by using the Resource Watch website.

You can also create you own datasets on the RW API, if you’d like to share your data with the world, or if you are looking to use the RW API and its features to gain insights into your data.

Getting all datasets

This endpoint will allow you to get the list of the datasets available in the API, and it’s a great place for new users to start exploring the RW API. By default, this endpoint will give you a paginated list of 10 datasets. In the sections below, we’ll explore how you can customize this endpoint call to match your needs.

For a detailed description of each field, check out the Dataset reference section.

Getting a list of datasets

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

Response:

{
    "data": [
        {
        "id": "00f2be42-1ee8-4069-a55a-16a988f2b7a0",
        "type": "dataset",
        "attributes": {
            "name": "Glad points",
            "slug": "Glad-points-1490086842129",
            "type": null,
            "subtitle": null,
            "application": ["data4sdgs"],
            "dataPath": null,
            "attributesPath": null,
            "connectorType": "document",
            "provider": "csv",
            "userId": "58333dcfd9f39b189ca44c75",
            "connectorUrl": "http://gfw2-data.s3.amazonaws.com/alerts-tsv/glad_headers.csv",
            "sources": [],
            "tableName": "data",
            "status": "pending",
            "published": true,
            "overwrite": false,
            "env": "production",
            "geoInfo": false,
            "legend": {
                "date": [],
                "region": [],
                "country": []
                },
            "clonedHost": {},
            "errorMessage": null,
            "updatedAt": "2017-01-13T10:45:46.368Z",
            "widgetRelevantProps": [],
            "layerRelevantProps": []
            }
        }
  ],
  "links": {
    "self": "http://api.resourcewatch.org/v1/dataset?page[number]=1&page[size]=10",
    "first": "http://api.resourcewatch.org/v1/dataset?page[number]=1&page[size]=10",
    "last": "http://api.resourcewatch.org/v1/dataset?page[number]=99&page[size]=10",
    "prev": "http://api.resourcewatch.org/v1/dataset?page[number]=1&page[size]=10",
    "next": "http://api.resourcewatch.org/v1/dataset?page[number]=2&page[size]=10"
  },
  "meta": {
    "total-pages": 99,
    "total-items": 990,
    "size": 10
  }
}

Pagination

The RW API lists many of its resources as pages, as opposed to showing all results at once. By default, datasets are listed in pages of 10 datasets each, and the first page is loaded. However, you can customize this behavior using the following query parameters:

Custom pagination: load page 2 using 25 results per page

curl -X GET https://api.resourcewatch.org/v1/dataset?page[number]=2&page[size]=25
Field Description Type Default
page[size] The number elements per page. Values above 100 are not officially supported. Number 10
page[number] The page number Number 1

Search for datasets

curl -X GET https://api.resourcewatch.org/v1/dataset?search=wind

The dataset service offers a simple yet powerful search mechanism that will help you look for datasets. The query argument search allows you to specify a search string that will match:

Filters

Filtering datasets

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

Matching vocabulary tags

curl -X GET https://api.resourcewatch.org/v1/dataset?vocabulary[legacy]=umd

The dataset list provides a wide range of parameters that you can use to tailor your dataset listing. Most of these parameters reflect fields you’ll find in a dataset itself (which you can learn more about in the Dataset reference section), while others are convenience filters for things like user role or favourites. These parameters can be combined into a complex and logic query.

Here’s the comprehensive list of filters supported by datasets:

Filter Description Type Expected values
name Filter returned datasets by the name of the dataset. String any valid text
slug Filter returned datasets by the slug of the dataset. String any valid text
type Filter returned datasets by dataset type. String any valid text
subtitle Filter returned datasets by dataset subtitle. String any valid text
application Applications associated to this dataset. Array any valid text
applicationConfig If the dataset has applicationConfig data (i.e. contains a non-empty object in the applicationConfig field) Boolean true or false
dataPath String any valid text
attributesPath String any valid text
connectorType Filter returned datasets by the type of connector used. String rest, document or wms
provider Dataset provider this include inner connectors and 3rd party ones String Check the available providers when creating a dataset
connectorUrl String any valid text
sources Array any valid text
tableName String any valid text
userId Filter results by the owner of the dataset. Does not support regexes. String valid user id
status Filter results by the current status of the dataset. String pending, saved or failed
overwrite If the data can be overwritten (only for being able to make dataset updates) Boolean trueor false
errorMessage If this dataset is in error state, this field may contain additional details about the error. String any valid text
mainDateField String any valid text
published If the dataset is published or not. Boolean trueor false
env Environment to which the dataset belongs. Multiple values can be combined using , as a separator. Does not support regexes. String any valid text. Defaults to production.
geoInfo If it contains interceptable geographical info Boolean trueor false
protected If the dataset is protected. Boolean trueor false
taskId Id of the latest task associated with this dataset. Typically only present in document connectorType datasets String any valid text
legend.lat String any valid text
legend.long String any valid text
legend.date Array any valid text
legend.region Array any valid text
legend.country Array any valid text
legend.nested Array any valid text
legend.integer Array any valid text
legend.short Array any valid text
legend.byte Array any valid text
legend.double Array any valid text
legend.byte Array any valid text
legend.float Array any valid text
legend.half_float Array any valid text
legend.scaled_float Array any valid text
legend.boolean Array any valid text
legend.binary Array any valid text
legend.text Array any valid text
legend.keyword Array any valid text
clonedHost.hostProvider String any valid text
clonedHost.hostUrl String any valid text
clonedHost.hostId String any valid text
clonedHost.hostType String any valid text
clonedHost.hostPath String any valid text
widgetRelevantProps Array any valid text
layerRelevantProps Array any valid text
subscribable If the dataset is subscribable (i.e. contains a non-empty object in the subscribable field) Boolean true or false
user.role Filter results by the role of the owner of the dataset. If the requesting user does not have the ADMIN role, this filter is ignored. String ADMIN, MANAGER or USER
vocabulary[name] Filter returned datasets by vocabulary tags. Does not support regexes. String any valid text
collection Filter returned datasets collection id. Does not support regexes. String any valid text
favourite Filter by favourited datasets. See this section for more info. Does not support regexes. String any valid text

Please keep in mind the following:

Sorting

Basics of sorting

Sorting datasets

curl -X GET https://api.resourcewatch.org/v1/dataset?sort=name

Sorting datasets by multiple criteria

curl -X GET https://api.resourcewatch.org/v1/dataset?sort=name,description

Sort by name descending, description ascending

curl -X GET https://api.resourcewatch.org/v1/dataset?sort=-name,+description

Sorting datasets by the role of the user who owns the dataset

curl -X GET https://api.resourcewatch.org/v1/dataset?sort=user.role

The API currently supports sorting by means of the sort query parameter. Sorting can be done using any field from the dataset model, as well as user.name and user.role (sorting by user data is restricted to ADMIN users). Sorting by nested fields is not supported at the moment.

Multiple sorting criteria can be used, separating them by commas.

You can also specify the sorting order by prepending the criteria with either - for descending order or + for ascending order. By default, ascending order is assumed.

Special sorting criteria

Sorting datasets with special criteria

curl -X GET https://api.resourcewatch.org/v1/dataset?sort=-most-favorited
curl -X GET https://api.resourcewatch.org/v1/dataset?sort=relevance&status=saved&search=agriculture

Special search criteria must be used as sole sorting criteria, as it’s not possible to combine any of them with any other search criteria. The following criteria can be used for special sorting in datasets:

You can specify the sorting order by prepending the criteria with either - for descending order or + for ascending order. By default, ascending order is assumed.

Loads metadata and widgets associated with each dataset:

curl -X GET https://api.resourcewatch.org/v1/dataset?includes=metadata,widget
{
    "data": [
        {
            "id": "06c44f9a-aae7-401e-874c-de13b7764959",
            "type": "dataset",
            "attributes": {
                "name": "Historical Precipitation -- U.S. (Puget Sound Lowlands)",
                "slug": "Historical-Precipitation-US-Puget-Sound-Lowlands-1490086842133",
                ...
                "metadata": [
                    {  

                        "id": "57a2251d5cd6980a00e054d9",
                        "type": "metadata",
                        "attributes": { ... }
                    }
                ],
                "widget": [
                    {  
                        "id": "73f00267-fe34-42aa-a611-13b102f38d75",
                        "type": "widget",
                        "attributes": { ... }
                    }
                ]
            }
        }
    ],
    "links": {
        "self": "http://api.resourcewatch.org/v1/dataset?includes=widget%2Cmetadata&page[number]=1&page[size]=10",
        "first": "http://api.resourcewatch.org/v1/dataset?includes=widget%2Cmetadata&page[number]=1&page[size]=10",
        "last": "http://api.resourcewatch.org/v1/dataset?includes=widget%2Cmetadata&page[number]=223&page[size]=10",
        "prev": "http://api.resourcewatch.org/v1/dataset?includes=widget%2Cmetadata&page[number]=1&page[size]=10",
        "next": "http://api.resourcewatch.org/v1/dataset?includes=widget%2Cmetadata&page[number]=2&page[size]=10"
    },
    "meta": {
        "total-pages": 223,
        "total-items": 2228,
        "size": 10
    }
}

Loading layers for the given dataset

curl -X GET http://api.resourcewatch.org/dataset?includes=layer

Loading the information about the user who authored the dataset

curl -X GET https://api.resourcewatch.org/v1/dataset?includes=user

When fetching datasets, you can request additional entities to be loaded. The following entities are available:

Note: If you include related entities (e.g. layers) with query filters, the filters will not cascade to the related entities.

Getting a dataset by id or slug

Getting a dataset by id:

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

Getting a dataset by slug:

curl -X GET https://api.resourcewatch.org/v1/dataset/Timber-Production-RDC

Response (equal for both cases):

{
    "data": {
        "id": "51943691-eebc-4cb4-bdfb-057ad4fc2145",
        "type": "dataset",
        "attributes": {
            "name": "Timber Production RDC",
            "slug": "Timber-Production-RDC",
            "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",
            "sources": [],
            "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"
        }
    }
}

If you know the id or the slug of a dataset, then you can access it directly. Both id and slug are case-sensitive.

Using this endpoint, you can also include related entities, in the same way you do when loading multiple datasets.

Getting a dataset by its including its relationships:

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

Getting multiple datasets by ids

This endpoint allows you to load multiple datasets by id in a single request.

Errors for getting multiple datasets by ids

Error code Error message Description
400 ids: ids can not be empty. The required ids field is missing in the request body.

Getting multiple datasets by their ids:

curl -X POST https://api.resourcewatch.org/v1/dataset/find-by-ids \
-H "Content-Type: application/json"  -d \
'{
    "ids": [
        "0706f039-b929-453e-b154-7392123ae99e",
        "0c630feb-8146-4fcc-a9be-be5adcb731c8",
    ]
}'

Response

    {
        "data": [
          {
            "id": "0706f039-b929-453e-b154-7392123ae99e",
            "type": "dataset",
            "attributes": {
              "name": "Social Vulnerability Index (2006-2010) -- U.S. (New Hampshire)",
              "slug": "Social-Vulnerability-Index-2006-2010-US-New-Hampshire-1490086842541",
              "type": "tabular",
              "subtitle": null,
              ...
            }
          },
          {
            "id": "0c630feb-8146-4fcc-a9be-be5adcb731c8",
            "type": "dataset",
            "attributes": {
              "name": "USGS Land Cover - Impervious Surface (2001) -- U.S. (Alaska)",
              "slug": "USGS-Land-Cover-Impervious-Surface-2001-US-Alaska-1490086842439",
              "type": "raster",
              "subtitle": null,
              ...
            }
          }
        ]
    }

Creating a dataset

So you are ready to create your first dataset on the RW API? Great, welcome aboard! These instruction will help you create your dataset on the RW API, so you can start sharing your data with the world and taking full advantage of all the RW API features on your projects.

Before creating a dataset, there are a few things you must know and do:

The first thing to consider when creating a dataset is where your data currently is - this will determine the Dataset provider you will need to use and, with it, a set of things you need to take into account - we’ll cover each provider in detail shortly. When building your request to the RW API to create your dataset, you will need to take into account both the general details that follow, plus the details for the provider you are using. Be sure to review both sections when creating your datasets, to avoid any pitfalls.

Creating a dataset is done using a POST request and passing the relevant data as body files. The supported body fields are as defined on the dataset reference section, but the minimum field list you must specify for all datasets is:

Additionally, depending on the data provider you will be using, other fields may be required - we’ll cover those in detail in each provider’s specific documentation.

A successful dataset creation request will return a 200 HTTP code, and the dataset details as stored on the RW API. PAy special attention to the id or the slug, as those will allow you to access your dataset later.

There’s one aspect of the dataset creation process that you need to keep in mind: it is an asynchronous process. This means that a successful call to the create dataset endpoint will start the process, but the dataset may not be immediately available to be used. The status field will tell you if the dataset creation process is in progress (status set to pending), if something went wrong (failed, in which case the errorMessage field will have a short description of what went wrong) or if the dataset is available to be used (when status is saved). The amount of time it takes for a newly created dataset to go from pending to saved depends on the provider and amount of data. Just keep in mind that you need to wait for the status to be set to saved before starting to use your datasets. You should check your dataset manually to see when the status is updated.

Errors for creating a dataset

Error code Error message Description
400 <field>: <field> can not be empty Your are missing a required field value.
400 <field>: empty or invalid <field> The provided value for <field> is invalid. This is usually happens if an invalid value type is provided, but certain fields use more advanced validation rules, that may produce this error message if validation fails (ie: on a carto dataset, the connectorUrl must contain a valid carto URL).
400 provider: must be valid Your provider value is invalid. The <list of valid providers> will contain the list of providers that are supported for the connectorType you specified.
401 Unauthorized You are not authenticated. If creating a BigQuery dataset, you may also see this message if you are authenticated. Refer to the BigQuery documentation for more details.
403 Forbidden - User does not have access to this dataset’s application You are trying to create a dataset with one or more application values that are not associated with your user account.

Carto datasets

Example of creating a dataset based on CartoDB data with the minimum fields required

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

To create a dataset connected to a Carto data source, besides the common required fields, you must provide the following required data:

Field Description Example value
connectorType The type of connector. Must be set to rest. rest
provider The provider should be set to cartodb. cartodb
connectorUrl The URL for the CartoDB table that this dataset will be using. https://wri-01.carto.com/tables/wdpa_protected_areas/table

The RW API will use the information above to directly query the Carto account specified on the connectorUrl field whenever this dataset is accessed on the RW API. This has a few implications that you should be aware of:

The tableName value of a carto-based dataset will automatically be filled with the name of the carto table corresponding to the dataset.

When creating a Carto based-dataset, the RW API will try to validate the connectorUrl by trying to connect to the corresponding Carto table - the result of this will determine if the dataset’s status will be set to saved or error.

ArcGIS feature layer

Example of creating a dataset based on ArcGIS feature layer data with the minimum fields required

curl -X POST https://api.resourcewatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
  "dataset": {
    "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."
  }
}'

To create a dataset using ArcGIS feature layer as data source, besides the common required fields, you must provide the following required data:

Field Description Example value
connectorType The type of connector. Must be set to rest. rest
provider The provider should be set to featureservice. featureservice
connectorUrl The URL for the JSON data in ArcGIS services this dataset will be using. https://services.arcgis.com/uuid/arcgis/rest/services/example/FeatureServer/0?f=json

The RW API will use the information above to directly query the ArcGIS feature layer server specified on the connectorUrl field whenever this dataset is accessed on the RW API. This has a few implications that you should be aware of:

The tableName value of a ArcGIS-based dataset will automatically be filled with the name of the ArcGIS feature layer table corresponding to the dataset.

When creating a ArcGIS-based dataset, the RW API will try to validate the connectorUrl by trying to connect to the corresponding ArcGIS Feature Layer - the result of this will determine if the dataset’s status will be set to saved or error.

Google Earth Engine

Example of creating a dataset based on Google Earth Engine data with the minimum fields required

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

To create a dataset using Google Earth Engine (GEE) as data source, besides the common required fields, you must provide the following required data:

Field Description Example value
connectorType The type of connector. Must be set to rest. rest
provider The provider should be set to gee. gee
tableName Relative path of the dataset within GEE. users/resourcewatch_wri/dataset_name

The RW API will use the information above to directly query the GEE dataset specified on the tableName field whenever this dataset is accessed on the RW API. This has a few implications that you should be aware of:

When creating a GEE-based dataset, the RW API will try to validate it by connecting to the corresponding dataset GEE - the result of this will determine if the dataset’s status will be set to saved or error.

WMS

Example of creating a dataset based on WMS data with the minimum fields required

curl -X POST 'https://api.resourcewatch.org/v1/dataset' -d \
-H 'Authorization: Bearer <your-token>'  \
-H 'Content-Type: application/json' -d \
'{
   "dataset": {
     "application": [
       "rw"
     ],
     "name": "Seasonal variability",
     "connectorType": "wms",
     "provider":"wms",
     "connectorUrl":"http://gis-gfw.wri.org/arcgis/rest/services/prep/nex_gddp_indicators/MapServer/6?f=pjson"
   }
 }
'

To create a dataset using WMS as data source, you should provide the following data:

Field Description Example value
connectorType The type of connector. Must be set to wms. wms
provider The provider should be set to wms. wms
connectorUrl URL of the server hosting the data in WMS format. https://maps.heigit.org/osm-wms/service?request=GetCapabilities&service=WMS

The RW API will use the information above to directly query the WMS dataset specified on the connectorUrl field whenever this dataset is accessed on the RW API. This has a few implications that you should be aware of:

When creating a WMS-based dataset, no validation is done - the dataset is automatically created in a saved state.

Document based datasets: JSON, CSV, TSV or XML

Creating a CSV dataset with data provided by externally hosted files:

curl -X POST https://api.resourcewatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
  "dataset": {
    "connectorType":"document",
    "provider":"csv",
    "sources": [
      "https://gfw2-data.s3.amazonaws.com/alerts-tsv/glad_headers_1.csv",
      "https://gfw2-data.s3.amazonaws.com/alerts-tsv/glad_headers_2.csv",
      "https://gfw2-data.s3.amazonaws.com/alerts-tsv/glad_headers_3.csv"
    ],
    "application":[
     "gfw"
    ],
    "name":"Glad points"
  }
}'

Creating a JSON dataset with data provided on the request body:

curl -X POST https://api.resourcewatch.org/v1/dataset \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
  "dataset": {
    "connectorType":"document",
    "provider":"json",
    "application":[
     "your", "apps"
    ],
    "data": {"myData":[
            {"name":"nameOne", "id":"random1"},
            {"name":"nameTow", "id":"random2"}
          ]},
    "name":"Example JSON Dataset"
  }
}'

This dataset hosts data from files in JSON, CSV, TSV or XML format.

Here’s a breakdown of the fields you need to specify when creating a document type dataset, besides the common required fields:

Field Description Example value
connectorType The type of connector. Must be set to document. document
provider The type of data you are uploading. Must be one of the following: csv, tsv, json or xml. csv, tsv, json or xml
connectorUrl URL from which to source data. http://gis-gfw.wri.org/arcgis/rest/services/prep/nex_gddp_indicators/MapServer/6?f=pjson
sources List of URLs from which to source data. [‘http://gis-gfw.wri.org/arcgis/rest/services/prep/nex_gddp_indicators/MapServer/6?f=pjson’,'http://gis-gfw.wri.org/arcgis/rest/services/prep/nex_gddp_indicators/MapServer/7?f=pjson’]
data JSON DATA only for json connector if connectorUrl not present. [{“key”:“value1”},{“key”:“value2”}]]

When creating a document based dataset, you have multiple ways of providing your data to the API, of which you should use only one:

The data passed in sources or connectorUrl must be available on a publicly accessible URLs, specified in the sources array field or the connectorUrl single value field. The URLs must be an accessible CSV, TSV or XML file, non-compressed - zip, tar, tar.gz, etc are not supported. sources allows you to specify multiple URLs for a single dataset, provided all files have the same format and data structure. This is particularly useful when creating very large datasets, as it will allow the creation process to be parallelized. No warranties are provided about the order in which the files or their parts are imported.

Notice: If you want to create a dataset from a file you have, but that it’s not available on a public URL, check out our docs for uploading a dataset.

Unlike with other dataset types, when the dataset is created, the data is copied from the provided source into the API’s internal Elasticsearch instance, which is the source used for subsequent queries or other operations. This has a few implications that you should be aware of:

Notice: When creating a document-based dataset, if any of the fields has a numerical name (for example, column: 3), a string named col_ will be appended to the beginning of the name of the column. This way, an uploaded column named 3 will become col_3.

Tip: If you want to periodically and automatically update your document based dataset with new data, check out the dataset automatic synchronization functionality.

When creating a document-based dataset, the RW API will start a complex process that copies your data into the API’s internal database, and perform certain indexing actions. This process is called a Task, and is given a taskId that is stored on the dataset’s field with the same name. Depending on the size of your dataset, this may take from a few seconds to a few hours to complete. The result of this import process will determine if the dataset’s status will be set to saved or error. You can follow this process by using the taskId value with the Tasks API.

Using the legend fields to define field types

By default, when creating a document based dataset, the data is ingested by the API and the field types are automatically determined by the underlying Elasticsearch dynamic mapping API. However, in some scenarios, it may be desirable to specify some or all of these mappings manually, to match each field type to its Elasticsearch equivalent.

When defining manual mappings, you don’t need to map every single field. When processing the data, if a field is found for which there isn’t a manual mapping, Elasticsearch will fallback to its dynamic mapping algorithm to try and guess that field’s type. This API only supports a single explicit mapping per field, meaning you cannot declare a given field as both text and keyword for example.

Field mapping can only be defined on dataset creation. Should you want to change these mappings, you can only do so by creating a new dataset with the new mapping structure.

The legend field allows explicitly identifying the following mappings:

Mapping Notes
lat If lat and long are both provided, a the_geom mapping is added
long If lat and long are both provided, a the_geom mapping is added
date Name of columns with date values (ISO Format)
country Name of columns with country values (ISO3 code)
region Name of columns with region values (ISO3 code)
nested Nested objects need to be explicitly identified in order to be indexed.
integer In beta, not fully supported
short In beta, not fully supported
byte In beta, not fully supported
double In beta, not fully supported
float In beta, not fully supported
half_float In beta, not fully supported
scaled_float In beta, not fully supported
boolean In beta, not fully supported
binary In beta, not fully supported
text In beta, not fully supported
keyword In beta, not fully supported

For more details on the characteristics of each of the basic data types, refer to the Elasticsearch documentation.

Uploading a dataset file

Upload raw data for using in a dataset

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

Example response

{
  "connectorUrl": "rw.dataset.raw/some-file.csv",
  "fields": [
    "Country (region)",
    "Positive affect",
    "Negative affect",
    "Social support",
    "Freedom",
    "Corruption",
    "Generosity"
  ]
}

Using the returned connectorUrl to create a new dataset

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

The upload endpoint allows you to create datasets on the API from local files that aren’t available online. If your file is up to 4MB in size, you can upload it to the API by using the upload endpoint. This endpoint accepts a file in the “dataset” field of your POST request, and a provider that matches your file type and extension. The supported formats/extensions are: csv, json, tsv, xml, tif, tiff and geo.tiff. The request uploads the file to the API, and returns a specially crafted connectorUrl value, and a list of fields found in your file. With this data, you can create a document type dataset by passing it to the connectorUrl value of a new document type dataset.

Errors for upload a dataset file

Error code Error message Description
400 - no file to check - A file was not provided, or was provided in the wrong request field.
400 - dataset: file dataset can not be a empty file - A file was not provided, or was provided in the wrong request field.
400 provider: provider must be in [csv,json,tsv,xml,tif,tiff,geo.tiff]. A file was not provided, or was provided in the wrong request field.
400 - dataset: file too large - Your file is larger than 4MB.
400 - dataset: file is bad file type. - The provider value must match the extension of the uploaded file.
401 Unauthorized You need to be logged in to be able to upload a file.

Updating a dataset

There are multiple options to update a dataset, depending on what modification you are trying to achieve, and the underlying data provider of the dataset itself. This section covers the different endpoints that allow you to modify a dataset, their details, and helps you pick the option that best fits your scenario. We recommend reviewing all of them before proceeding, so you can find the endpoint that best matches your needs.

Updating the fields of a dataset

Example request for updating the name of a dataset

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

In order to modify the fields of a dataset, you can use the patch dataset endpoint. This endpoint allows you to modify most of your dataset’s details, like the name or publishing status, but can also be used to modify internal fields of a dataset, like connectorType. When making these changes, be mindful that some of these fields are critical to the correct behavior of the dataset, and providing incorrect values may break your dataset. There are other endpoints documented in this page that allow you to perform certain update-like operations (ie. update data on a document-type dataset), so refer to those first before using this endpoint. Also important to keep in mind is the fact that this endpoint does not perform validation on things like connectorUrl/sources URLs.

All the fields in the dataset reference can be modified, except the following:

Additionally, certain fields have special behavior associated with them:

When passing new values for Object type fields, the new value will fully overwrite the previous one. It’s up to you, as an API user, to build any merging logic into your application.

To perform this operation, the following conditions must be met:

Use this endpoint when:

Errors for updating the fields of a dataset

Error code Error message Description
401 Unauthorized You need to be logged in to be able to update a dataset.
403 Forbidden You need to either have the ADMIN role, or have role MANAGER and be the dataset’s owner (through the userId field of the dataset).
403 Forbidden You are trying to update a dataset with one or more application values that are not associated with your user account.
404 Dataset with id doesn’t exist A dataset with the provided id does not exist.

Concatenate and append data to a document based dataset

Concatenate data using external data source:

curl -X POST https://api.resourcewatch.org/v1/dataset/:dataset_id/concat \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "provider": "json",
    "sources": ["<csv1Url>", "<csv2Url>", "<csv3Url>"],
    "dataPath": "data... etc"
}'

Append data using external data source:

curl -X POST https://api.resourcewatch.org/v1/dataset/:dataset_id/append \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
    "provider": "json",
    "sources": ["<csvUrl>"],
    "dataPath": "data... etc"
}'

Concatenate data using JSON array in post body:

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

Using these endpoints, you can add more data to an already existing dataset. They are exclusively available for document based datasets - you’ll get a 404 error if you use them on a dataset of a different type. You can either provide the URL for the file containing the data you wish to add, or simply provide that data in the body of your request, as a JSON object.

These process are asynchronous and not instantaneous. Immediately when triggered, these requests will cause the dataset’s status to be set to pending, meaning you will not be able to issue new overwrite, concatenate or append requests. Once the request has been fully processed, the status will be automatically set to saved. Depending on factors like API load or the size of the data being uploaded, this may take from a few minutes to a few hours to occur. The API does not issue any notification when the asynchronous operation is finished.

In order to perform these operation, the following conditions must be met:

While they ultimately achieve a very similar end result, concatenate and append rely on different internal processes, each with its own characteristics.

Here’s a more detailed description of the request’s body fields:

Field Description Type Values Required
provider Dataset provider this include inner connectors and 3rd party ones String A valid dataset provider Yes
sources List of URLs from which to source data Array URL array Yes, unless JSON data is provided using the data field
data JSON DATA only for json connector if connectorUrl not present Array [{},{},{}] Yes for JSON if sources is not present
dataPath Path to the data in a JSON file-based datasets String No

Tip: If you want to periodically and automatically concatenate data to your document based dataset, check out the dataset automatic synchronization functionality.

Use this endpoint when:

Errors for concatenating and appending data to a document based dataset

Error code Error message Description
401 Dataset is not in saved status The dataset’s status value is not set to saved. Refer to dataset reference for more details on this field and its values.
401 Unauthorized You need to be logged in to be able to update a dataset.
403 Forbidden You need to either have the ADMIN role, or have role MANAGER and be the dataset’s owner (through the userId field of the dataset).
403 Forbidden You are trying to update a dataset with one or more application values that are not associated with your user account.
404 Endpoint not found A dataset with the provided id does not exist, or does not have connectorType with value document.
409 Dataset locked. Overwrite false. The dataset you’re trying to modify has overwrite value set to false, to explicitly prevent data modifications.

Overwrite data for a document based dataset

Overwrite data using external data source:

curl -X POST https://api.resourcewatch.org/v1/dataset/:dataset_id/data-overwrite \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
'{
   "sources": ["<url of the data source>"],
   "provider": "csv"
}'

Overwrite data using JSON array in post body:

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

Using this endpoint, you can add or completely replace the data of an already existing dataset. It’s exclusively available for document based datasets - you’ll get a 404 error if you use it on a dataset of a different type. All previously existing data will be permanently deleted. You can either provide the URL(s) for the file(s) containing the data you wish to add, or simply provide that data in the body of your request, as a JSON object. There are no requirements regarding similarity of the data structure between existing and new data - your overwrite data can have a completely different data schema.

This process is asynchronous and not instantaneous. Immediately when triggered, this request will cause the dataset’s status to be set to pending, meaning you will not be able to issue new overwrite or concat requests, and will not yet be able to access the new data yet. Once the request has been fully processed, the status will be automatically set to saved and the new data will be accessible. Depending on factors like API load or the size of the data being uploaded, this may take from a few minutes to a few hours to occur. The API does not issue any notification when the asynchronous operation is finished.

In order to perform this operation, the following conditions must be met:

Here’s a more detailed description of the request’s body fields:

Field Description Type Values Required
provider Dataset provider this include inner connectors and 3rd party ones String A valid dataset provider Yes
sources List of URLs from which to source data Array URL array Yes, unless JSON data is provided using the data field
data JSON DATA only for json connector if connectorUrl not present Array [{},{},{}] Yes for JSON if sources is not present
legend The schema of the new data. If none is provided, a guessing mechanism will be used. The existing legend value of the dataset will be ignored and overwritten in all overwrite operations. See the legend section above for more details. Object No

Tip: If you want to periodically and automatically overwrite the data on your document based dataset, check out the dataset automatic synchronization functionality.

Errors for overwriting data for a document based dataset

Error code Error message Description
401 Dataset is not in saved status The dataset’s status value is not set to saved. Refer to dataset reference for more details on this field and its values.
401 Unauthorized You need to be logged in to be able to update a dataset.
403 Forbidden You need to either have the ADMIN role, or have role MANAGER and be the dataset’s owner (through the userId field of the dataset).
403 Forbidden You are trying to update a dataset with one or more application values that are not associated with your user account.
404 Endpoint not found A dataset with the provided id does not exist, or does not have connectorType with value document.
409 Dataset locked. Overwrite false. The dataset you’re trying to modify has overwrite value set to false, to explicitly prevent data modifications.

Use this endpoint when:

Cloning a dataset

Example request for cloning a dataset

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

This endpoint allows you to create a new, json based dataset, from the result of a RW API endpoint call. The basic usage example would be to create a new dataset based on a custom query to an existing dataset - this is illustrated in the example curl call in this section. Other use cases could be converting the result of an analysis endpoint into a dataset, or capturing the result of a query to a REST based dataset (cartodb, arcgis, etc) to an internal json representation of the same data, that is kept in the API database.

In order to perform this operation, the following conditions must be met:

The request requires two fields to be present:

Additionally, you can optionally specify these fields:

For the fields in the following list, values will be copied from the original dataset to the new one, unless specified:

Datasets created through a cloning operation will have a specific clonedHost object, with additional data. Refer to dataset reference for more details on the content of this field.

The dataset cloning requests accepts an optional full boolean query parameter that, when set to true, will clone of vocabulary-related data and metadata from the original dataset to the new one.

Errors for cloning a dataset

Error code Error message Description
400 : can not be empty. The required field identified in the error message is missing in the request body.
400 - application: must be a non-empty array - application must be specified as an array.
401 Unauthorized You need to be logged in to be able to clone a dataset.
403 Forbidden You need to either have the ADMIN role, or have role MANAGER and be the dataset’s owner (through the userId field of the dataset).
403 Forbidden - User does not have access to this dataset’s application You specified an application in your request body that is not associated with your user account.
404 Dataset with id doesn’t exist A dataset with the provided id does not exist.

Deleting a dataset

Use this endpoint if you wish to delete a dataset. Deleting a dataset of type document (connectorType with value document) will cause the API’s internal copy of said data to be deleted. Dataset types that proxy data from an external source (ie. carto, gee, etc) will be deleted without modifying said external source.

When deleting a dataset that is associated with multiple application values, the user issuing the request must be associated with all of them in order for the dataset to be deleted. If that’s not the case, the application values associated with the user will be removed from the dataset’s application list, and no further action will be taken - the dataset itself and its associated resources will continue to exist. The dataset is only actually deleted if the user has access to all of the application to which the dataset belongs.

Besides deleting the dataset itself, this endpoint also deletes graph vocabularies, layers, widgets and metadata related to the dataset itself. These delete operations are issued in this order, and prior to deleting the dataset itself, but are not atomic - if one of them fails (for example, if attempting to delete a protected resource), the following ones are canceled, but the already deleted elements are not restored.

In order to delete a dataset, the following conditions must be met:

Example request for deleting a dataset

curl -X DELETE https://api.resourcewatch.org/v1/dataset/<dataset-id> \
-H "Authorization: Bearer <your-token>"
-H "Content-Type: application/json"
Error code Error message Description
400 Dataset is protected You are attempting to delete a dataset that has protected set to prevent deletion.
401 Unauthorized You need to be logged in to be able to delete a dataset.
403 Forbidden You need to either have the ADMIN role, or have role MANAGER and be the dataset’s owner (through the userId field of the dataset)
403 Forbidden You are trying to delete a dataset with one or more application values that are not associated with your user account.
404 Dataset with id doesn’t exist A dataset with the provided id does not exist.

Dataset automatic synchronization

curl -X POST https://api.resourcewatch.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>"
    }
}'

Certain datasets contain data that evolves frequently over time, and you, as the creator of this dataset, what to ensure that it’s up-to-date. As we’ve seen before, if your data is hosted on one of the supported 3rd party data providers, like Carto or Arcgis, your data will be proxied, so users of the RW API will always see the latest version of your data. However, if you uploaded your data from a file, your data is copied to the RW API database at the time of the dataset’s creation, so keeping it up-to-date requires a different approach. It’s with scenario in mind that the RW API offers the automatic synchronization mechanism.

The automatic synchronization mechanism is available for document based datasets only, and you can configure it when creating or updating a dataset. When enabled, it will schedule an automatic, periodic task, that will update your document based dataset’s data, based on data from an URL you provide. This means that, once configured, you just have to make sure the automatic synchronization mechanism can find the newest version of the data at the specified URL, and the RW API will take care of the actual data update process for you.

To configure automatic synchronization on dataset creation or update, you need to pass a sync object on your calls to the respective endpoints, next to the other fields. See the included example for a clearer idea of how creating a dataset with automatic synchronization looks like.

There are 3 fields, all required, that you need to specify inside the sync object:

Internally, the automatic synchronization mechanism will call either the dataset concatenation or dataset overwrite endpoint. If that internal request fails - for example, if overwrite is set to false - the sync process will fail silently. If you have the ADMIN role, you can use the /v1/task endpoint to see scheduled tasks and their error output, but otherwise this failure will be invisible to end users.

On the other hand, if the request goes through, but the concatenation/overwrite process fails - for example, if the URL provided is not available - then your dataset status will be set to error and the errorMessage field will give you a simple description of what happened.

To see the details (including the date) of the last operation performed on the dataset, use the link in the taskId field.

Flush dataset cache

Flush dataset’s cache

curl -X POST https://api.resourcewatch.org/v1/0c630feb-8146-4fcc-a9be-be5adcb731c8/flush \
-H "Authorization: Bearer <your-token>"

Response:

OK

Flushes the cache for the specified dataset. Take into account that only the dataset itself, query results and fields will be flushed. Any other relation, like metadata, layers or widgets linked to the specified dataset will not be affected by this action.

In order to flush a dataset’s cache, the following conditions must be met:

Errors for flushing a dataset’s cache

Error code Error message Description
401 Unauthorized You need to be logged in to be able to delete a dataset.
403 Forbidden You need to either have the ADMIN role, or have role MANAGER and be the dataset’s owner (through the userId field of the dataset)
403 Forbidden You are trying to delete a dataset with one or more application values that are not associated with your user account.
404 Dataset with id doesn’t exist A dataset with the provided id does not exist.

Recover

Recover dataset

curl -X POST https://api.resourcewatch.org/v1/0c630feb-8146-4fcc-a9be-be5adcb731c8/recover \
-H "Authorization: Bearer <your-token>"

Response:

OK

Resets a dataset’s status to saved and clears its errors. Keep in mind that this does NOT modify the dataset in any other way - if the underling dataset’s data was inconsistent for any reason, this endpoint will not change it, and it’s up to you to fix it using a data-overwrite or other endpoints.

In order to recover a dataset, the user must be logged in and have the ADMIN role.

Errors for recovering a dataset’s cache

Error code Error message Description
401 Unauthorized You need to be logged with to be able to delete a dataset.
403 Forbidden You need to have the ADMIN role.
404 Dataset with id doesn’t exist A dataset with the provided id does not exist.

Dataset reference

This section gives you a complete view at the properties that are maintained as part of dataset. When interacting with a dataset (on get, on create, etc) you will find most of these properties available to you, although they may be organized in a slightly different structure (ie: on get, everything but the id is nested inside an attributes object).

You can find more details in the source code.

Filter Type Required Default value Description
id String Yes (autogenerated) Unique Id of the dataset. Auto generated on creation. Cannot be modified by users.
name String Yes Name of the dataset.
slug String Yes (autogenerated) Slug of the dataset. Auto generated on creation. Cannot be modified by users.
type String No null Type of the dataset.
subtitle String No null Subtitle of the dataset.
application Array Yes Applications associated with this dataset.
applicationConfig Object No Key-value storage of application-specific data. Use the application value as key and a JSON Object as the value to store complex, extensible data.
dataPath String No null Path to the data in a JSON file-based datasets.
attributesPath String No null
connectorType String Yes Type of connector. wms for WMS-based datasets, rest for datasets that rely on external data sources (carto, arcgis, etc) or document for file-based datasets (JSON, CSV, etc).
provider String Yes Dataset provider.
userId String Yes (autopopulated) Id of the user who created the dataset. Set automatically on creation. Cannot be modified by users.
connectorUrl String No null Path to the source of the data. On datasets with document connectorType, sources should be used instead.
sources Array No null Path to the source files of the data. Only used on datasets with document connectorType.
tableName String No null Additional value used to locate the dataset within a given underlying provider. Refer to the documentation of the different connector for more details.
status String No pending Status of the dataset. saved means the dataset is available to use, pending means an operation is ongoing and the dataset is temporarily unavailable, error means the dataset is in an invalid state and requires further action before becoming available.
overwrite Boolean No false If the data can be overwritten (only for being able to update dataset)
errorMessage String No null If this dataset is in error state, this field may contain additional details about the error.
mainDateField String No null
published Boolean Yes true If the dataset is published or not.
env String Yes production Environment to which the dataset belongs.
geoInfo Boolean Yes false If it contains interceptable geographical info
protected Boolean Yes false If the dataset is protected. A protected dataset cannot be deleted.
taskId String No null Id of the latest task associated with this dataset. Typically only present in document connectorType datasets
subscribable Object No Information about the dataset being subscribable for alerts. More info about this can be found on the Subscriptions section of the docs.
legend.lat String No Dataset field representing a latitude value.
legend.long String No Dataset field representing a longitude value.
legend.* Array No Different keys corresponding to data types. Each key may have an array of strings, referencing dataset fields that match that data type. Used functionally for document-based datasets, but may also be set by the user as reference for other types. See this section for more details.
clonedHost.hostProvider String No When cloning a dataset, this will retain the provider value of the original dataset.
clonedHost.hostUrl String No When cloning a dataset, this will retain the connectorUrl value of the original dataset.
clonedHost.hostId String No When cloning a dataset, this will retain the Id value of the original dataset.
clonedHost.hostType String No When cloning a dataset, this will retain the connectorType value of the original dataset.
clonedHost.hostPath String No When cloning a dataset, this will retain the tableName value of the original dataset.
widgetRelevantProps Array No Group of relevant props of a widget.
layerRelevantProps Array No Group of relevant props of a layer.
dataLastUpdated Date No User defined date of when a dataset was last updated.
userName String No (autogenerated) null Name of the user who created the dataset. This value is used only internally, and is never directly exposed through the API. Cannot be modified by users.
userRole String No (autogenerated) null Role of the user who created the dataset. This value is used only internally, and is never directly exposed through the API. Cannot be modified by users.
createdAt Date No (autogenerated) Automatically maintained date of when the dataset was created. Cannot be modified by users.
updatedAt Date No (autogenerated) Automatically maintained date of when the dataset was last updated. Cannot be modified by users.

Widget

What is a Widget?

A widget is a graphic representation of a Dataset’s data. Most of them are defined with Vega grammar but we can also find other custom definitions. Here are the RW widgets definitions.

Widgets contain the following fields:

Field Description Type
userId Id of the owner Text
application Application to which the dataset belongs Array
slug Unique identifier of the widget Text
name Name of the widget Url
description Description of the widget Array
source Publisher of the original code Text
sourceUrl Link to publisher page Url
layerId UuId of the relationship with layer String
dataset UuId of the dataset that the widget belongs Text
authors Name of the authors Text
queryUrl Url with the data of the chart shows Text
widgetConfig Custom configuration Object
template If it’s a template (base schema to create other widgets) Boolean
default If it’s a default widget for the dataset that it belongs Boolean
protected If it’s a protected widget (not is possible to delete if it’s true) Boolean
published If it’s available to use Text
freeze If the data is frozen Boolean
verified If it’s verified by other user Text
env Environment can be one of production or preproduction. By default, it’s set to “production” unless specified otherwise on creation/update Text
thumbnailUrl Url of the widget’s thumbnail, if one exists Text
createdAt Date in which the widget was created Date
updatedAt Date in which the widget was last updated Date

What is Vega?

Vega is a visualization grammar; a declarative format for creating, saving and sharing interactive visualization designs. This wiki contains documentation and learning materials for getting up and running with Vega. More info

How obtain a single widget

curl -X GET https://api.resourcewatch.org/v1/widget/51851e22-1eda-4bf5-bbcc-cde3f9a3a943

Example response:

{
    "data": {
        "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
        "type": "widget",
        "attributes": {
            "name": "Example Carto Dataset6",
            "dataset": "be76f130-ed4e-4972-827d-aef8e0dc6b18",
            "slug": "example-carto-dataset6",
            "userId": "5820ad9469a0287982f4cd18",
            "description": null,
            "source": null,
            "sourceUrl": null,
            "authors": null,
            "application": [
                "rw"
            ],
            "verified": false,
            "default": false,
            "protected": false,
            "defaultEditableWidget": false,
            "published": true,
            "freeze": false,
            "env": "production",
            "queryUrl": null,
            "widgetConfig": "{}",
            "template": false,
            "layerId": null,
            "createdAt": "2017-02-08T15:30:34.505Z",
            "updatedAt": "2017-02-08T15:30:34.505Z"
        }
    }
}

Customize the query url of a widget

The queryUrl query parameter can be set if the user needs to modify the final url that will be requested. All parameters indicated in the queryUrl will be pass to the microservice.

curl -X GET https://api.resourcewatch.org/v1/widget/049f074a-3528-427d-922b-3c2320e9caf6?queryUrl=/v1/query?sql=Select%20*%20from%20data&geostore=ungeostore

When loading widget data, you can optionally pass an includes query argument to load additional data.

Vocabulary

Loads related vocabularies. If none are found, an empty array is returned.

curl -X GET https://api.resourcewatch.org/v1/widget/51851e22-1eda-4bf5-bbcc-cde3f9a3a943?includes=vocabulary

Example response:

{
    "data": {
        "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
        "type": "widget",
        "attributes": {
            "name": "Example Carto Dataset6",
            "dataset": "be76f130-ed4e-4972-827d-aef8e0dc6b18",
            "slug": "example-carto-dataset6",
            "userId": "5820ad9469a0287982f4cd18",
            "description": null,
            "source": null,
            "sourceUrl": null,
            "authors": null,
            "application": [
                "rw"
            ],
            "verified": false,
            "default": false,
            "protected": false,
            "defaultEditableWidget": false,
            "published": true,
            "freeze": false,
            "env": "production",
            "queryUrl": null,
            "widgetConfig": "{}",
            "template": false,
            "layerId": null,
            "createdAt": "2017-02-08T15:30:34.505Z",
            "updatedAt": "2017-02-08T15:30:34.505Z",
            "vocabulary": []
        }
    }
}

User

Loads the name and email address of the author of the widget. If you request this issue as an authenticated user with ADMIN role, you will additionally get the author’s role.

If the data is not available (for example, the user has since been deleted), no user property will be added to the widget object.

curl -X GET https://api.resourcewatch.org/v1/widget/51851e22-1eda-4bf5-bbcc-cde3f9a3a943?includes=user

Example response:

{
    "data": {
        "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
        "type": "widget",
        "attributes": {
            "name": "Example Carto Dataset6",
            "dataset": "be76f130-ed4e-4972-827d-aef8e0dc6b18",
            "slug": "example-carto-dataset6",
            "userId": "5820ad9469a0287982f4cd18",
            "description": null,
            "source": null,
            "sourceUrl": null,
            "authors": null,
            "application": [
                "rw"
            ],
            "verified": false,
            "default": false,
            "protected": false,
            "defaultEditableWidget": false,
            "published": true,
            "freeze": false,
            "env": "production",
            "queryUrl": null,
            "widgetConfig": "{}",
            "template": false,
            "layerId": null,
            "createdAt": "2017-02-08T15:30:34.505Z",
            "updatedAt": "2017-02-08T15:30:34.505Z",
            "user": {
              "name": "John Sample",
              "email": "john.sample@vizzuality.com"
            }
        }
    }
}

Metadata

Loads the metadata available for the widget. If none are found, an empty array is returned.

curl -X GET https://api.resourcewatch.org/v1/widget/51851e22-1eda-4bf5-bbcc-cde3f9a3a943?includes=metadata

Example response:

{
    "data": {
        "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
        "type": "widget",
        "attributes": {
            "name": "Example Carto Dataset6",
            "dataset": "be76f130-ed4e-4972-827d-aef8e0dc6b18",
            "slug": "example-carto-dataset6",
            "userId": "5820ad9469a0287982f4cd18",
            "description": null,
            "source": null,
            "sourceUrl": null,
            "authors": null,
            "application": [
                "rw"
            ],
            "verified": false,
            "default": false,
            "protected": false,
            "defaultEditableWidget": false,
            "published": true,
            "freeze": false,
            "env": "production",
            "queryUrl": null,
            "widgetConfig": "{}",
            "template": false,
            "layerId": null,
            "createdAt": "2017-02-08T15:30:34.505Z",
            "updatedAt": "2017-02-08T15:30:34.505Z",
            "metadata": [
              {
                "id": "5aeb1c74a096b50010f3843f",
                "type": "metadata",
                "attributes": {
                  "dataset": "86777822-d995-49cd-b9c3-d4ea4f82c0a3",
                  "application": "rw",
                  "resource": {
                    "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
                    "type": "widget"
                  },
                  "language": "en",
                  "info": {
                    "caption": "t",
                    "widgetLinks": []
                  },
                  "createdAt": "2018-05-03T14:28:04.482Z",
                  "updatedAt": "2018-06-07T11:30:40.054Z",
                  "status": "published"
                }
              }
            ]
          }
        }
    }
}

Requesting multiple additional entities

You can request multiple related entities in a single request using commas to separate multiple keywords

curl -X GET https://api.resourcewatch.org/v1/widget/51851e22-1eda-4bf5-bbcc-cde3f9a3a943?includes=metadata,user,vocabulary

How to obtain all widgets

To obtain all widgets:

curl -X GET https://api.resourcewatch.org/v1/widget

Example response:

{
   "data":[
      {
         "id":"8f67fadd-d8df-4a28-82dd-a22a337d71b9",
         "type":"widget",
         "attributes":{
            "userId":"5858f37140621f11066fb2f7",
            "application":[
               "aqueduct"
            ],
            "slug":"percentage-of-country-s-population-is-at-high-risk-of-hunger",
            "name":"Percentage of country's population at high risk of hunger.",
            "description":"",
            "source":"",
            "sourceUrl":"",
            "layerId":null,
            "dataset":"f1d24950-c764-4f90-950a-4541f798eb95",
            "authors":"",
            "queryUrl":"query/f1d24950-c764-4f90-950a-4541f798eb95?sql=select * from crops",
            "widgetConfig":{
                ...
            },
            "template":false,
            "default":true,
            "published":true,
            "freeze": false,
            "verified":false
         }
      }
   ],
   "links":{
      "first":"https://api.resourcewatch.org/v1/widget?page%5Bnumber%5D=1",
      "prev":"https://api.resourcewatch.org/v1/widget?page%5Bnumber%5D=1",
      "next":"https://api.resourcewatch.org/v1/widget?page%5Bnumber%5D=2&page%5Bsize%5D=10",
      "last":"https://api.resourcewatch.org/v1/widget?page%5Bnumber%5D=64&page%5Bsize%5D=10",
      "self":"https://api.resourcewatch.org/v1/widget?page%5Bnumber%5D=1&page%5Bsize%5D=10"
   },
   "meta": {
      "total-pages": 38,
      "total-items": 372,
      "size": 10
   }
}

Available filters parameters:

Field Description Type
name Filter the widgets whose name contains the filter text Text
dataset Filter the widgets by dataset uuid Text
sort Sort json response by specific attributes Text
published Filter widgets on published status (true, false) Boolean
freeze Filter widgets on freeze status (true, false) Boolean
verified Filter by verified status (true, false) Boolean
template Filter by template status (true, false) Boolean
default Filter by default status (true, false) Boolean
app Filter widgets on application (prep, gfw, etc..) Text
env Environment can be one of production or preproduction Text
userId Filter widgets created by a specific user Text
favourite Filter favourited widgets of an user Boolean
collection Filter widgets based on an user collection Text
user.role The role of the user who created the layer. If the requesting user does not have the ADMIN role, this filter is ignored. ADMIN, MANAGER or USER

Return the widgets filtered whose name contains glad

curl -X GET https://api.resourcewatch.org/v1/widget?name=glad

Return the widgets filtered by dataset

curl -X GET https://api.resourcewatch.org/v1/widget?dataset=d02df2f6-d80c-4274-bb6f-f062061655c4
curl -X GET https://api.resourcewatch.org/v1/dataset/d02df2f6-d80c-4274-bb6f-f062061655c4/widget

Sort by name

curl -X GET https://api.resourcewatch.org/v1/widget?sort=name

Filter widgets by published status

curl -X GET https://api.resourcewatch.org/v1/widget?published=false

Filter widgets by verified status

curl -X GET https://api.resourcewatch.org/v1/widget?verified=false

Return the widgets filtered by template

curl -X GET https://api.resourcewatch.org/v1/widget?template=true

Filter widgets by default option

curl -X GET https://api.resourcewatch.org/v1/widget?default=true

Return widgets whose applications contain rw

curl -X GET https://api.resourcewatch.org/v1/widget?app=rw

Pagination params

Field Description Type
page[size] Number elements per page. There’s a limit of 100 to the size of each page, which is not being enforced at the moment, but queries for larger page sizes are not supported. This means future requests may fail if not respecting the page size limit. Number
page[number] Number of page Number

Return the widgets from page 2, with 5 elements per page

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

Sorting

The API currently supports sorting by means of the sort parameter. Sorting can be done using any field from the widget, as well as user.name and user.role (sorting by user data is restricted to ADMIN users).

Sorting by nested fields is not supported at the moment.

Sorting widgets

curl -X GET https://api.resourcewatch.org/v1/widget?sort=name

Multiple sorting criteria can be used, separating them by commas.

Sorting widgets by multiple criteria

curl -X GET https://api.resourcewatch.org/v1/widget?sort=name,slug

You can specify the sorting order by prepending the criteria with either - or +. By default, asc order is assumed.

Explicit order of sorting

curl -X GET https://api.resourcewatch.org/v1/widget?sort=-name,+slug

Sorting widgets by the role of the user who owns the widget

curl -X GET https://api.resourcewatch.org/v1/widget?sort=user.role

When loading widget data, you can optionally pass an includes query argument to load additional data.

Vocabulary

Loads related vocabularies. If none are found, an empty array is returned.

curl -X GET https://api.resourcewatch.org/v1/widget?includes=vocabulary

Example response:

{
    "data": [{
        "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
        "type": "widget",
        "attributes": {
            "name": "Example Carto Dataset6",
            "dataset": "be76f130-ed4e-4972-827d-aef8e0dc6b18",
            "slug": "example-carto-dataset6",
            "userId": "5820ad9469a0287982f4cd18",
            "description": null,
            "source": null,
            "sourceUrl": null,
            "authors": null,
            "application": [
                "rw"
            ],
            "verified": false,
            "default": false,
            "protected": false,
            "defaultEditableWidget": false,
            "published": true,
            "freeze": false,
            "env": "production",
            "queryUrl": null,
            "widgetConfig": "{}",
            "template": false,
            "layerId": null,
            "createdAt": "2017-02-08T15:30:34.505Z",
            "updatedAt": "2017-02-08T15:30:34.505Z",
            "vocabulary": []
        }
    }]
}

User

Loads the name and email address of the author of the widget. If the data is not available (for example, the user has since been deleted), no user property will be added to the widget object.

curl -X GET https://api.resourcewatch.org/v1/widget?includes=user

Example response:

{
    "data": [{
        "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
        "type": "widget",
        "attributes": {
            "name": "Example Carto Dataset6",
            "dataset": "be76f130-ed4e-4972-827d-aef8e0dc6b18",
            "slug": "example-carto-dataset6",
            "userId": "5820ad9469a0287982f4cd18",
            "description": null,
            "source": null,
            "sourceUrl": null,
            "authors": null,
            "application": [
                "rw"
            ],
            "verified": false,
            "default": false,
            "protected": false,
            "defaultEditableWidget": false,
            "published": true,
            "freeze": false,
            "env": "production",
            "queryUrl": null,
            "widgetConfig": "{}",
            "template": false,
            "layerId": null,
            "createdAt": "2017-02-08T15:30:34.505Z",
            "updatedAt": "2017-02-08T15:30:34.505Z",
            "user": {
              "name": "John Sample",
              "email": "john.sample@vizzuality.com"
            }
        }
    }]
}

Metadata

Loads the metadata available for the widget. If none are found, an empty array is returned.

curl -X GET https://api.resourcewatch.org/v1/widget?includes=metadata

Example response:

{
    "data": [{
        "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
        "type": "widget",
        "attributes": {
            "name": "Example Carto Dataset6",
            "dataset": "be76f130-ed4e-4972-827d-aef8e0dc6b18",
            "slug": "example-carto-dataset6",
            "userId": "5820ad9469a0287982f4cd18",
            "description": null,
            "source": null,
            "sourceUrl": null,
            "authors": null,
            "application": [
                "rw"
            ],
            "verified": false,
            "default": false,
            "protected": false,
            "defaultEditableWidget": false,
            "published": true,
            "freeze": false,
            "env": "production",
            "queryUrl": null,
            "widgetConfig": "{}",
            "template": false,
            "layerId": null,
            "createdAt": "2017-02-08T15:30:34.505Z",
            "updatedAt": "2017-02-08T15:30:34.505Z",
            "metadata": [
              {
                "id": "5aeb1c74a096b50010f3843f",
                "type": "metadata",
                "attributes": {
                  "dataset": "86777822-d995-49cd-b9c3-d4ea4f82c0a3",
                  "application": "rw",
                  "resource": {
                    "id": "51851e22-1eda-4bf5-bbcc-cde3f9a3a943",
                    "type": "widget"
                  },
                  "language": "en",
                  "info": {
                    "caption": "t",
                    "widgetLinks": []
                  },
                  "createdAt": "2018-05-03T14:28:04.482Z",
                  "updatedAt": "2018-06-07T11:30:40.054Z",
                  "status": "published"
                }
              }
            ]
          }
        }]
    }
}

Requesting multiple additional entities

You can request multiple related entities in a single request using commas to separate multiple keywords

curl -X GET https://api.resourcewatch.org/v1/widget?includes=metadata,user,vocabulary

How to obtain a widget for a specific dataset

To obtain the widget:

curl -X GET https://api.resourcewatch.org/v1/dataset/d02df2f6-d80c-4274-bb6f-f062061655c4/widget/20ec7861-5251-40a7-9503-5ee3686a66a3
curl -X GET https://api.resourcewatch.org/v1/widget/20ec7861-5251-40a7-9503-5ee3686a66a3

Example response:

{
  "data": {
    "id": "20ec7861-5251-40a7-9503-5ee3686a66a3",
    "type": "widget",
    "attributes": {
      "userId": "57a0693b49c36b265ba3bec8",
      "application": [
        "rw"
      ],
      "slug": "estimated-c02-emission",
      "name": "Estimated C02 emission",
      "description": null,
      "source": "",
      "sourceUrl": null,
      "layerId": null,
      "dataset": "d02df2f6-d80c-4274-bb6f-f062061655c4",
      "authors": null,
      "queryUrl": "query/d02df2f6-d80c-4274-bb6f-f062061655c4?sql=select country, rank, iso3, total from estimated_co2_emission_filtered",
      "widgetConfig": {
        "data": [ ... ],
        "marks": [ ... ],
        "scales": [ ... ],
        "padding": {
          "top": 40,
          "left": 20,
          "right": 20,
          "bottom": 0
        }
      },
      "template": false,
      "default": false,
      "published": true,
      "verified": false
    }
  },
  "meta": {
    "status": "saved",
    "published": true,
    "verified": false,
    "updated_at": "2017-01-17T17:50:45.655Z",
    "created_at": "2016-06-06T15:12:38.749Z"
  }
}

Create a Widget

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

Field Description Type Values Required
name Name of the widget Text Any Text Yes
description Description of the dataset Text Any text No
source Publisher of the original code Text Any text No
sourceUrl Link to publisher page Text Any url No
application Application to which the widget belongs Array gfw, forest-atlas, rw, prep, aqueduct, data4sdg Yes
authors Name of the authors Text Any text No
queryUrl Url with the data of the chart shows Text Any valid query No
widgetConfig Vega configuration Object Valid object No
published If it’s available to use Boolean true - false No
freeze If the data is frozen Boolean true - false No
protected If it’s a protected widget (not is possible to delete if it’s true) Boolean true - false No
verified If it’s verified by other user Boolean true - false No
template If it’s a template Boolean true - false No
default If it’s default for dataset Boolean true - false No
layerId UuId of the relationship with layer Text Uuid of layer No
dataset UuId of the dataset Text Uuid of Dataset No
env Environment of the Widget. Set to ‘production’ by default String Valid string No

It is possible to create a widget that has a different env property to its parent dataset.

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

curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset_id>/widget \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "widget": {
      "application":[
         "your", "apps"
      ],
      "name":"Example Carto Dataset"
      "published": true
   }
}'

Update a Widget

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

Field Description Type Values Required
name Name of the widget Text Any Text Yes
description Description of the dataset Text Any text No
source Publisher of the original code Text Any text No
sourceUrl Link to publisher page Text Any url No
application Application to which the widget belongs Array gfw, forest-atlas, rw, prep, aqueduct, data4sdg Yes
authors Name of the authors Text Any text No
queryUrl Url with the data of the chart shows Text Any valid query No
widgetConfig Vega configuration Object Valid object No
published If it’s available to use Boolean true - false No
freeze If the data is frozen Boolean true - false No
verified If it’s verified by other user Boolean true - false No
template If it’s a template Boolean true - false No
default If it’s default for dataset Boolean true - false No
layerId UuId of the relationship with layer Text Uuid of layer No
dataset UuId of the dataset Text Uuid of Dataset No
env Environment Text production or preproduction Yes

A user with role USER can update their own widgets, based on the userId field. A user with ADMIN role can update any widget.

To update a widget, you have to do a PATCH request with the following body:

curl -X PATCH https://api.resourcewatch.org/v1/dataset/<dataset_id>/widget/<widget_id> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "widget": {
      "application":[
         "your", "apps"
      ],
      "name":"New Example Carto Dataset Name",
      "widgetConfig": {}
   }
}'

Clone a Widget

You can clone an existing widget as long as you have permissions to the applications associated with it. Basic usage requires no body params, but you can optionally pass a new name or description to be used in the creation of the new widget.

To clone a widget, you should use one of the following POST requests:

curl -X POST https://api.resourcewatch.org/v1/widget/<widget_id>/clone \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"
curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset_id>/widget/<widget_id>/clone \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"

You can optionally set a new name or description:

curl -X POST https://api.resourcewatch.org/v1/widget/<widget_id>/clone \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "name for the cloned widget",
   "description": "
   "name": "name for the cloned widget", for the cloned widget",
}'
curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset_id>/widget/<widget_id>/clone \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "name for the cloned widget",
   "description": "
   "name": "name for the cloned widget", for the cloned widget",
}'

Cloning widgets from other microservices

When cloning a widget, the newly created clone will take the userId of the originating request. If you call this endpoint as an authenticated user from your custom application, that means it will get that authenticated user’s userId. However, if invoked from another API microservice, that userId is no longer available. In this scenario, when the request to clone is originated internally, you can optionally pass a userÌd body value that will be set as the userId of the newly created widget.

curl -X POST https://api.resourcewatch.org/v1/widget/<widget_id>/clone \
-H "Authorization: Bearer <microservice-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "userId": "123456789",
}'

Delete a Widget

Who can delete Widgets?

curl -X DELETE https://api.resourcewatch.org/v1/dataset/<dataset_id>/widget/<widget_id> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"

Layer

What is a Layer?

A layer is a geographical representation of a Dataset’s data.

Layer contains the following fields:

Field Description Type
userId Id of the owner Text
application Application to which the dataset belongs Array
iso The 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
protected If it’s a protected layer (not is possible to delete if it’s true) Boolean
published Is the layer published? Boolean
env environment in witch the layer was published, one of staging, preproduction or production Text

How obtain all layers

To obtain all layers:

curl -X GET https://api.resourcewatch.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",
          "env": "production",
          "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://api.resourcewatch.org/v1/layer?page%5Bnumber%5D=1",
      "prev":"https://api.resourcewatch.org/v1/layer?page%5Bnumber%5D=1",
      "next":"https://api.resourcewatch.org/v1/layer?page%5Bnumber%5D=2&page%5Bsize%5D=10",
      "last":"https://api.resourcewatch.org/v1/layer?page%5Bnumber%5D=64&page%5Bsize%5D=10",
      "self":"https://api.resourcewatch.org/v1/layer?page%5Bnumber%5D=1&page%5Bsize%5D=10"
   },
   "meta": {
      "total-pages": 63,
      "total-items": 628,
      "size": 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
env Environment in witch the layer was published, one of staging, preproduction or production. Defaults to production Text
user.role The role of the user who created the layer. If the requesting user does not have the ADMIN role, this filter is ignored. ADMIN, MANAGER or USER

Return the layers filtered by those whose name contains emissions

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

Return the layers filtered by dataset

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

Sort by name

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

Filter layers by status

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

Filter layers by published status

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

Filter layers by environment

If no env is specified, production is used as default.

curl -X GET https://api.resourcewatch.org/v1/layer?env=staging

Return the layers filtered by those whose applications contain rw

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

Pagination params

Field Description Type
page[size] Number elements per page. There’s a limit of 100 to the size of each page, which is not being enforced at the moment, but queries for larger page sizes are not supported. This means future requests may fail if not respecting the page size limit. Number
page[number] Number of page Number

Return the layers of page 2 with 5 elements per page

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

Sorting

The API currently supports sorting by means of the sort parameter. Sorting can be done using any field from the layer, as well as user.name and user.role (sorting by user data is restricted to ADMIN users).

Sorting by nested fields is not supported at the moment.

Sorting layers

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

Multiple sorting criteria can be used, separating them by commas.

Sorting layers by multiple criteria

curl -X GET https://api.resourcewatch.org/v1/layer?sort=name,slug

You can specify the sorting order by prepending the criteria with either - or +. By default, asc order is assumed.

Explicit order of sorting

curl -X GET https://api.resourcewatch.org/v1/layer?sort=-name,+slug

Sorting layers by the role of the user who owns the layer

curl -X GET https://api.resourcewatch.org/v1/layer?sort=user.role

When loading layer data, you can optionally pass an includes query argument to load additional data.

Vocabulary

Loads related vocabularies. If none are found, no vocabulary property will be added to the layer object.

curl -X GET https://api.resourcewatch.org/v1/layer?includes=vocabulary

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",
          "env": "production",
          "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": {},
          "vocabulary": []
        }
      }
   ]
}

User

Loads the name and email address of the author of the layer. If you request this issue as an authenticated user with ADMIN role, you will additionally get the author’s role.

If the data is not available (for example, the user has since been deleted), no user property will be added to the layer object.

curl -X GET https://api.resourcewatch.org/v1/layer?includes=user

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",
          "env": "production",
          "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": {},
          "user": {
              "name": "John Doe",
              "email": "john.doe@vizzuality.com"
          }
        }
      }
   ]
}

Requesting multiple additional entities

You can request multiple related entities in a single request using commas to separate multiple keywords

curl -X GET https://api.resourcewatch.org/v1/layer?includes=user,vocabulary

How obtain specific layers

To obtain the layer:

curl -X GET https://api.resourcewatch.org/v1/dataset/11de2bc1-368b-42ed-a207-aaff8ece752b/layer/e5c3e7c5-19ae-4ca0-a461-71f1f67aa553
curl -X GET https://api.resourcewatch.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",
      "env": "production",
      "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"
  }
}

You can load related user and vocabulary data in the same request. See this section for more details.

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, rw definition example 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
dataset UuId of the dataset Text Uuid of Dataset No
protected If it’s a protected layer (not is possible to delete if it’s true) Boolean true-false No
env Environment of the Layer. Set to ‘production’ by default String Valid string No

It is possible to create a layer that has a different env property to its parent dataset.

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

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

The following structure was previously supported but should now be considered deprecated:

curl -X POST https://api.resourcewatch.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 The isos to which the layer belongs Array BRA, ES No
dataset UuId of the dataset Text Uuid of Dataset No
env The environment to which the layer belongs Text Any Text No

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

curl -X PATCH https://api.resourcewatch.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

In order to perform this operation, the following conditions must be met:

curl -X DELETE https://api.resourcewatch.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 datasets, you can send queries to the API using a syntax very similar to SQL. Using these endpoints, you can also download the results of a particular query. If you are new to the RW API, or want to learn more about the concept of a querying datasets, we strongly encourage you to read the query concept documentation first. It gives you a brief and clear description of what a query is, and what it is useful for.

Please note that some SQL features might not be supported. Check here for a reference of the SQL features’ support for each dataset provider.

Note: This section is currently a work in progress and, for the moment it only covers querying CartoDB and document-based datasets. The remaining providers should follow in the next versions.

Querying datasets

Structure of the endpoint for executing a query:

curl -i -X GET 'https://api.resourcewatch.org/v1/query/<dataset.id>?sql=SELECT * FROM <dataset.tableName>'

In order to query a dataset, you’ll need two pieces of information:

The dataset documentation covers different ways that you can use to browse the existing dataset catalog or upload your own, all of which will give you the details of a dataset, including the dataset id you’ll need to query it.

The SQL query will have to be custom built by you to fit your needs, but a good starting point for newcomers would be something like SELECT * FROM <dataset.tableName> limit 10.

Notice: the limit parameter restricts our results to 10 rows, and is not required. However, for our learning purposes, this is useful, as it keeps the API responses small and fast.

Most of the SQL query is up to you to define, based on your needs and the support provided for the dataset type you are using. The FROM clause, however, does use a special value - the dataset’s tableName value, which you can also get from the dataset documentation described above.

Example endpoint for executing a query:

curl -i -X GET 'https://api.resourcewatch.org/v1/query/098b33df-6871-4e53-a5ff-b56a7d989f9a?sql=SELECT cartodb_id, iso, name_0, name_1, type_1 FROM gadm28_adm1 limit 10'

With both pieces of information at hand, you can now send your query to the API and get the response. The example cURL to the side shows how that would look like.

Query response body

Example response:

{
    "data": [
        {
            "cartodb_id": 1830,
            "iso": "MEX",
            "name_0": "Mexico",
            "name_1": "Ciudad de México",
            "type_1": "Distrito Federal"
        },
        {
            "cartodb_id": 1109,
            "iso": "HTI",
            "name_0": "Haiti",
            "name_1": "L'Artibonite",
            "type_1": "Département"
        },
        ...
    ],
    "meta": {
        "cloneUrl": {
            "http_method": "POST",
            "url": "/dataset/098b33df-6871-4e53-a5ff-b56a7d989f9a/clone",
            "body": {
                "dataset": {
                    "datasetUrl": "/query/098b33df-6871-4e53-a5ff-b56a7d989f9a?sql=SELECT%20*%20FROM%20gadm28_adm1%20limit%2010",
                    "application": [
                        "your",
                        "apps"
                    ]
                }
            }
        }
    }
}

The following table describes the response body fields:

Field Type Description
data Array Array of objects that correspond to the result of the query execution. The data structure varies according to SELECT clause of your query, or the structure of dataset being queried.
meta Object Object with metadata regarding the query executed.
meta.cloneUrl Object Object with information for creating a new dataset from the current query execution.
meta.cloneUrl.http_method String The HTTP method that should be used for the request to create a new dataset from the current query execution. Read the documentation on cloning a dataset for more info.
meta.cloneUrl.url String The API endpoint path that should be used for the request to create a new dataset from the current query execution.
meta.cloneUrl.body Object The body request data that should be provided for creating a new dataset from the current query execution.

Query endpoint parameters

Example of requesting the query results as CSV data:

curl -i -X GET 'https://api.resourcewatch.org/v1/query/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date from gadm28_adm1 limit 2&format=csv'

Example response:

"alert__date",
"_id"
"2019-04-12",
"AW6O0fqMLu2ttL7ZDM4P"
"2015-08-22",
"AW6O0fqMLu2ttL7ZDM4T"

Example of requesting to freeze the query results:

curl -i -X GET 'https://api.resourcewatch.org/v1/query/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date from gadm28_adm1 limit 2&freeze=true' \
-H "Authorization: Bearer <your-token>"

Example response:

{
    "url": "https://storage.googleapis.com/query-freeze/1589458072773.json"
}

The following parameters can be provided as query parameters, in order to customize the output of the response returned:

Query parameter Description Type Required
sql The SQL query to be executed. This parameter changes the data returned in the query response body. String Yes
format The format of the returned response. By default, JSON format is assumed (json), but you can also request the response as CSV (csv), in which case the returned response will contain the CSV contents of the response. This parameter will only be considered for document-based datasets. String No
freeze The freeze parameter, when provided as true, will create a file with the results of the execution of the query and return the URL for that file. Please note that you should be authenticated in order to request freezing the results of query executions. Boolean No

Alternative ways for querying datasets

While the GET request described above is the recommended way of querying datasets, there are other ways to query the RW API datasets that may be more suited for specific use cases.

Using the dataset slug instead of the id

Example query not using the dataset id in the request path, and using the dataset slug in the FROM clause:

curl -i -X GET 'https://api.resourcewatch.org/v1/query/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date from gadm28_adm1 limit 2'
curl -i -X GET 'https://api.resourcewatch.org/v1/query/Glad-Alerts-Daily-Geostore-User-Areas_3?sql=SELECT alert__date from gadm28_adm1 limit 2'

When referencing a dataset’s id in a query, you have the option to use the dataset’s slug instead, obtaining the same result. This is also applicable to the alternative query methods described in the sections below.

POST requests

The same query executed as GET, and as a POST request providing the SQL as request body param:

curl -i -X GET 'https://api.resourcewatch.org/v1/query/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date from gadm28_adm1 limit 2'
curl -i -X POST 'https://api.resourcewatch.org/v1/query/9be3bf63-97fc-4bb0-b913-775ccae3cf9e' \
-H 'Content-Type: application/json' \
-d '{
    "sql": "SELECT alert__date from gadm28_adm1 limit 2"
}'

Using the GET request is the recommended approach, as it allows HTTP caching of your result - subsequent requests for the same query will see a great performance increase, even if they are made by a different application or client.

Alternatively, you can also query a dataset using a POST request. POST requests are not cached, so you will not benefit from these speed improvements. However, GET requests can sometimes hit URL length restrictions, should your query string be too long. Using a POST request is the recommended solution for these cases. See the example on the side to see how you can query a dataset with a POST request.

Dataset id as the FROM clause

Three different but equivalent syntaxes for the same query:

curl -i -X GET 'https://api.resourcewatch.org/v1/query/098b33df-6871-4e53-a5ff-b56a7d989f9a?sql=SELECT cartodb_id, iso, name_0, name_1, type_1 FROM gadm28_adm1 limit 10'

curl -i -X GET 'https://api.resourcewatch.org/v1/query?sql=SELECT cartodb_id, iso, name_0, name_1, type_1 FROM 098b33df-6871-4e53-a5ff-b56a7d989f9a limit 10'

curl -i -X POST 'https://api.resourcewatch.org/v1/query' \
-H 'Content-Type: application/json' \
-d '{
    "sql": "SELECT cartodb_id, iso, name_0, name_1, type_1 FROM 098b33df-6871-4e53-a5ff-b56a7d989f9a limit 10"
}'

The examples we’ve seen so far expect the URL to have the /query/<dataset id or slug>?sql=SELECT * FROM <dataset.tableName> format. However, you can also use the equivalent /query?sql=SELECT * FROM <dataset id> syntax. You can also use this alternative syntax with POST requests.

Redundant FROM clause (document based datasets only)

Example query providing a document-based dataset id in the request path or as the FROM clause:

curl -i -X GET 'https://api.resourcewatch.org/v1/query?sql=SELECT alert__date FROM 9be3bf63-97fc-4bb0-b913-775ccae3cf9e limit 10'
curl -i -X GET 'https://api.resourcewatch.org/v1/query/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date FROM data limit 10'

When querying a document based dataset using either GET or POST /query/<dataset id or slug> request, the FROM clause is required but ignored, meaning you don’t have to provide the dataset’s tableName as you normally would. The example on the side illustrates this.

Downloading data from a dataset

Structure of the endpoint for downloading the results of a query:

curl -i -X GET 'https://api.resourcewatch.org/v1/download/<dataset.id>?sql=SELECT * FROM <dataset.tableName>'

Example endpoint for downloading the results of a query:

curl -i -X GET 'https://api.resourcewatch.org/v1/download/098b33df-6871-4e53-a5ff-b56a7d989f9a?sql=SELECT cartodb_id, iso, name_0, name_1, type_1 FROM gadm28_adm1 limit 10'

The download endpoint allows you to download the results of the execution of a query over a dataset. This endpoint is greatly based on the query datasets endpoint, so we strongly suggest you read that section of the documentation.

Note: Some dataset providers do not support downloading query results. You can download query results for the following dataset providers:

Like when querying datasets, in order to download the results of the execution of query, you’ll need two pieces of information:

The dataset documentation covers different ways that you can use to browse the existing dataset catalog or upload your own, all of which will give you the details of a dataset, including the dataset id you’ll need to query it.

The SQL query will have to be custom built by you to fit your needs, but a good starting point for newcomers would be something like SELECT * FROM <dataset.tableName> limit 10.

Notice: the limit parameter restricts our results to 10 rows, and is not required. However, for our learning purposes, this is useful, as it keeps the API responses small and fast.

As with the query endpoint, the FROM clause should reference the dataset’s tableName value, which you can also get from the dataset documentation described above. And also, don’t forget that you can check the support provided for the dataset type you are using if you are having trouble writing your SQL query.

Download response body

Example of downloading query results (by default, CSV data is assumed):

curl -i -X GET 'https://api.resourcewatch.org/v1/download/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date, alert__count from gadm28_adm1 limit 2'

Example CSV response:

"alert__date",
"alert__count",
"_id"
"2019-04-12",
5,
"AW6O0fqMLu2ttL7ZDM4P"
"2015-08-22",
6,
"AW6O0fqMLu2ttL7ZDM4T"

Example of downloading query results requesting format as JSON:

curl -i -X GET 'https://api.resourcewatch.org/v1/download/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date, alert__count from gadm28_adm1 limit 2&format=json'

Example JSON response:

{
    "data": [
        {
            "alert__date": "2019-04-12",
            "alert__count": 5,
            "_id": "AW6O0fqMLu2ttL7ZDM4P"
        },
        {
            "alert__date": "2015-08-22",
            "alert__count": 6,
            "_id": "AW6O0fqMLu2ttL7ZDM4T"
        }
    ]
}

The response body of executing the download endpoint will contain the data to be downloaded. You can use the format query parameter to customize the format of the data returned. By default, format=csv will be assumed, so you will receive the corresponding query results the actual CSV data in the response body. If you provide format=json, the returned result will be a JSON object with a data index containing the results of the execution of the query provided.

Download execution errors

Calling the download endpoint might sometimes result in an error being returned. The following table describes the possible errors that can occur when downloading query execution results:

Error code Error message Description
400 SQL or FS required The required sql field is missing either as query string parameter or in the request body.
400 - format: format must be in [json,csv]. - If provided, format must be either csv or json.
500 Internal server error The error message might vary in this case.

Download endpoint parameters

Example of requesting to freeze the download results:

curl -i -X GET 'https://api.resourcewatch.org/v1/download/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date from gadm28_adm1 limit 2&freeze=true' \
-H "Authorization: Bearer <your-token>"

Example response:

{
    "url": "https://storage.googleapis.com/query-freeze/1589458072773.json"
}

You can use the following query parameters to customize the output of the download query execution results endpoint:

Query parameter Description Type Required
sql The SQL query to be executed. This parameter changes the data returned in the query response body. String Yes
format The format of the returned response. By default, CSV format is assumed (csv), but you can also request the response as JSON (json). Check the section on the download endpoint response body for some examples of how the format query parameter can be used. String No
freeze The freeze parameter, when provided as true, will create a file with the results of the execution of the query and return the URL for that file. Please note that you should be authenticated in order to request freezing the results of query executions. Boolean No

Alternative ways for downloading query execution results

As in the case of querying datasets, there are some alternative ways that you can use for downloading query execution results. While the GET request described above is the recommended way of downloading query results, there are other ways to download query results that may be more suited for specific use cases.

Using the dataset slug instead of the id

Example request for downloading the query execution results not using the dataset id in the request path, and using the dataset slug in the FROM clause:

curl -i -X GET 'https://api.resourcewatch.org/v1/download/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date from gadm28_adm1 limit 2'
curl -i -X GET 'https://api.resourcewatch.org/v1/download/Glad-Alerts-Daily-Geostore-User-Areas_3?sql=SELECT alert__date from gadm28_adm1 limit 2'

When referencing a dataset’s id in th SQL query, you have the option to use the dataset’s slug instead, obtaining the same result. This is also applicable to the alternative download methods described in the sections below.

POST requests

The same download request executed as GET, and as a POST request providing the SQL as request body param:

curl -i -X GET 'https://api.resourcewatch.org/v1/download/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date from gadm28_adm1 limit 2'
curl -i -X POST 'https://api.resourcewatch.org/v1/download/9be3bf63-97fc-4bb0-b913-775ccae3cf9e' \
-H 'Content-Type: application/json' \
-d '{
    "sql": "SELECT alert__date from gadm28_adm1 limit 2"
}'

Using the GET request is the recommended approach, as it allows HTTP caching of your result - subsequent requests for the same download endpoint call will see a great performance increase, even if they are made by a different application or client.

Alternatively, you can also download the query results using a POST request. POST requests are not cached, so you will not benefit from these speed improvements. However, GET requests can sometimes hit URL length restrictions, should your SQL query string be too long. Using a POST request is the recommended solution for these cases. See the example on the side to see how you can download the query execution results with a POST request.

Dataset id as the FROM clause

Three different but equivalent syntaxes for the same call to the download endpoint:

curl -i -X GET 'https://api.resourcewatch.org/v1/download/098b33df-6871-4e53-a5ff-b56a7d989f9a?sql=SELECT cartodb_id, iso, name_0, name_1, type_1 FROM gadm28_adm1 limit 10'

curl -i -X GET 'https://api.resourcewatch.org/v1/download?sql=SELECT cartodb_id, iso, name_0, name_1, type_1 FROM 098b33df-6871-4e53-a5ff-b56a7d989f9a limit 10'

curl -i -X POST 'https://api.resourcewatch.org/v1/download' \
-H 'Content-Type: application/json' \
-d '{
    "sql": "SELECT cartodb_id, iso, name_0, name_1, type_1 FROM 098b33df-6871-4e53-a5ff-b56a7d989f9a limit 10"
}'

The examples we’ve seen so far expect the URL to have the /download/<dataset id or slug>?sql=SELECT * FROM <dataset.tableName> format. However, you can also use the equivalent /download?sql=SELECT * FROM <dataset id> syntax. This alternative syntax is also available for POST requests.

Redundant FROM clause (document-based datasets only)

Example download providing a document-based dataset id in the request path or as the FROM clause:

curl -i -X GET 'https://api.resourcewatch.org/v1/download?sql=SELECT alert__date FROM 9be3bf63-97fc-4bb0-b913-775ccae3cf9e limit 10'
curl -i -X GET 'https://api.resourcewatch.org/v1/download/9be3bf63-97fc-4bb0-b913-775ccae3cf9e?sql=SELECT alert__date FROM data limit 10'

When downloading the query results for a document based dataset using either GET or POST /download/<dataset id or slug> request, the FROM clause is required but ignored, meaning you don’t have to provide the dataset’s tableName as you normally would. The example on the side illustrates this.

Supported SQL syntax reference

CartoDB datasets

This section describes the SQL support for querying datasets with provider cartodb.

Supported Feature Example URL
YES SELECT: Selecting all columns using wildcard SELECT * FROM edi LIMIT 5
YES SELECT: Count all rows SELECT count(*) FROM edi
YES SELECT: Selecting specific columns SELECT region, overall_score FROM edi LIMIT 5
YES SELECT: Selecting DISTINCT values for specific columns SELECT DISTINCT(region) FROM edi LIMIT 5
NO SELECT: Selecting columns AND counting all rows SELECT region, count(*) FROM edi LIMIT 5
YES SELECT: Aliasing aggregate function results such as AVG in SELECT SELECT AVG(overall_score) as alias FROM edi LIMIT 5
YES SELECT: Usage of aggregate functions (AVG) in SELECT SELECT AVG(overall_score) FROM edi LIMIT 5
YES SELECT: Usage of aggregate functions (MAX) in SELECT SELECT MAX(overall_score) FROM edi LIMIT 5
YES SELECT: Usage of aggregate functions (MIN) in SELECT SELECT MIN(overall_score) FROM edi LIMIT 5
YES SELECT: Usage of aggregate functions (SUM) in SELECT SELECT SUM(overall_score) FROM edi LIMIT 5
YES FROM: Using dataset id in FROM statement SELECT * FROM 0b9f0100-ce5b-430f-ad8f-3363efa05481 LIMIT 5
YES FROM: Using dataset slug in FROM statement SELECT * FROM Environmental-Democracy-Index-1490086842552 LIMIT 5
YES FROM: Using dataset tableName in FROM statement SELECT * FROM edi LIMIT 5
YES WHERE: Greater than filtering SELECT * FROM edi WHERE overall_score > 2 LIMIT 5
YES WHERE: Greater than or equal filtering SELECT * FROM edi WHERE overall_score >= 2 LIMIT 5
YES WHERE: Equality filtering SELECT * FROM edi WHERE overall_score = 2.1 LIMIT 5
YES WHERE: Lower than filtering SELECT * FROM edi WHERE overall_score < 2.2 LIMIT 5
YES WHERE: Lower than or equal filtering SELECT * FROM edi WHERE overall_score <= 2.2 LIMIT 5
YES WHERE: Conjunction (AND) filtering SELECT * FROM edi WHERE overall_score <= 2.2 AND justice_pillar_score > 1 LIMIT 5
YES WHERE: Disjunction (OR) filtering SELECT * FROM edi WHERE overall_score <= 2.2 OR justice_pillar_score > 1 LIMIT 5
YES WHERE: BETWEEN filtering SELECT * FROM edi WHERE overall_score BETWEEN 2 AND 2.2 LIMIT 5
YES WHERE: LIKE filtering SELECT * FROM edi WHERE region LIKE ‘Europ%’ LIMIT 5
YES GROUP BY: Group results by a single column SELECT region FROM edi GROUP BY region LIMIT 5
YES GROUP BY: Group results by multiple columns SELECT region, overall_score FROM edi GROUP BY region, overall_score LIMIT 5
YES GROUP BY: Aggregate functions used with GROUP BY statements SELECT region, COUNT(*) as count FROM edi GROUP BY region LIMIT 5
NO GROUP BY: Special grouping by range function SELECT count(*) FROM edi GROUP BY range(overall_score, 0,1,2,3,4) LIMIT 5
YES ORDER BY: Ordering results by one column SELECT region FROM edi ORDER BY region LIMIT 5
YES ORDER BY: Ordering results by one column descending SELECT region FROM edi ORDER BY region DESC LIMIT 5
YES ORDER BY: Ordering results by multiple column SELECT region, overall_score FROM edi ORDER BY region, overall_score LIMIT 5
YES ORDER BY: Ordering results by multiple column descending SELECT region, overall_score FROM edi ORDER BY region, overall_score DESC LIMIT 5
YES LIMIT: Limit the number of returned results SELECT region FROM edi LIMIT 5
NO OFFSET: Offset the returned results SELECT region FROM edi LIMIT 5 OFFSET 10
NO OFFSET: Offset the returned results using short syntax SELECT region FROM edi LIMIT 5, 10

Note: This table was generated automatically with the help of this repository. If you are maintaining the docs, please do not edit manually these tables.

Document-based datasets

This section describes the SQL support for querying datasets with connector type document and providers csv, tsv, json or xml.

Supported Feature Example URL
YES SELECT: Selecting all columns using wildcard SELECT * FROM data LIMIT 5
YES SELECT: Count all rows SELECT count(*) FROM data
YES SELECT: Selecting specific columns SELECT bra_biome__name, alert__count FROM data LIMIT 5
NO SELECT: Selecting DISTINCT values for specific columns SELECT DISTINCT(bra_biome__name) FROM data LIMIT 5
YES SELECT: Selecting columns AND counting all rows SELECT bra_biome__name, count(*) FROM data LIMIT 5
YES SELECT: Aliasing aggregate function results such as AVG in SELECT SELECT AVG(alert__count) as alias FROM data LIMIT 5
YES SELECT: Usage of aggregate functions (AVG) in SELECT SELECT AVG(alert__count) FROM data LIMIT 5
YES SELECT: Usage of aggregate functions (MAX) in SELECT SELECT MAX(alert__count) FROM data LIMIT 5
YES SELECT: Usage of aggregate functions (MIN) in SELECT SELECT MIN(alert__count) FROM data LIMIT 5
YES SELECT: Usage of aggregate functions (SUM) in SELECT SELECT SUM(alert__count) FROM data LIMIT 5
YES FROM: Using dataset id in FROM statement SELECT * FROM 9be3bf63-97fc-4bb0-b913-775ccae3cf9e LIMIT 5
YES FROM: Using dataset slug in FROM statement SELECT * FROM Glad-Alerts-Daily-Geostore-User-Areas_3 LIMIT 5
YES FROM: Using dataset tableName in FROM statement SELECT * FROM data LIMIT 5
YES WHERE: Greater than filtering SELECT * FROM data WHERE alert__count > 2 LIMIT 5
YES WHERE: Greater than or equal filtering SELECT * FROM data WHERE alert__count >= 2 LIMIT 5
YES WHERE: Equality filtering SELECT * FROM data WHERE alert__count = 5 LIMIT 5
YES WHERE: Lower than filtering SELECT * FROM data WHERE alert__count < 8 LIMIT 5
YES WHERE: Lower than or equal filtering SELECT * FROM data WHERE alert__count <= 8 LIMIT 5
YES WHERE: Conjunction (AND) filtering SELECT * FROM data WHERE alert__count <= 8 AND alert_area__ha > 0.1 LIMIT 5
YES WHERE: Disjunction (OR) filtering SELECT * FROM data WHERE alert__count <= 8 OR alert_area__ha > 0.1 LIMIT 5
YES WHERE: BETWEEN filtering SELECT * FROM data WHERE alert__count BETWEEN 2 AND 8 LIMIT 5
NO WHERE: LIKE filtering SELECT * FROM data WHERE bra_biome__name LIKE 'Amaz%’ LIMIT 5
YES GROUP BY: Group results by a single column SELECT bra_biome__name FROM data GROUP BY bra_biome__name LIMIT 5
YES GROUP BY: Group results by multiple columns SELECT bra_biome__name, alert__count FROM data GROUP BY bra_biome__name, alert__count LIMIT 5
YES GROUP BY: Aggregate functions used with GROUP BY statements SELECT bra_biome__name, COUNT(*) as count FROM data GROUP BY bra_biome__name LIMIT 5
YES GROUP BY: Special grouping by range function SELECT count(*) FROM data GROUP BY range(alert__count, 0,1,2,3,4) LIMIT 5
YES ORDER BY: Ordering results by one column SELECT bra_biome__name FROM data ORDER BY bra_biome__name LIMIT 5
YES ORDER BY: Ordering results by one column descending SELECT bra_biome__name FROM data ORDER BY bra_biome__name DESC LIMIT 5
YES ORDER BY: Ordering results by multiple column SELECT bra_biome__name, alert__count FROM data ORDER BY bra_biome__name, alert__count LIMIT 5
YES ORDER BY: Ordering results by multiple column descending SELECT bra_biome__name, alert__count FROM data ORDER BY bra_biome__name, alert__count DESC LIMIT 5
YES LIMIT: Limit the number of returned results SELECT bra_biome__name FROM data LIMIT 5
YES OFFSET: Offset the returned results SELECT bra_biome__name FROM data LIMIT 5 OFFSET 10
NO OFFSET: Offset the returned results using short syntax SELECT bra_biome__name FROM data LIMIT 5, 10

Note: This table was generated automatically with the help of this repository. If you are maintaining the docs, please do not edit manually these tables.

Troubleshooting SQL queries for document-based datasets

This SQL syntax supported when running queries for document-based datasets has some known limitations:

You can read more about the limitations of using SQL with document-based datasets here.

Rasdaman datasets

SQL-like queries can be employed for accessing data stored in Rasdaman datasets. Subsets on the original axes of the data may be provided in the WHERE statement. So far, only operations that result in a single scalar can be obtained from Rasdaman - averages, minimums, maximums.

curl -XGET https://api.resourcewatch.org/v1/query?sql=SELECT avg(Green) from 18c0b71d-2f55-4a45-9e5b-c35db3ebfe94 where Lat > 0 and  Lat < 45 \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>'

NEX-GDDP datasets

A SQL wrapper is offered for accessing the NASA NEX-GDDP dataset with sql-like statements. The API stores calculated indexes over the original data, and several views over the data are available. These can be accessed in the following ways:

Spatial aggregates over a layer

Access spatial aggregates over the data by listing all dataset data for a particular year:

curl -i -XGET 'https://api.resourcewatch.org/v1/query/b99c5f5e-00c6-452e-877c-ced2b9f0b393?sql=SELECT * from nexgddp-historical-ACCESS1_0-prmaxday where year = 1960'

Access particular aggregates:

curl -i -XGET 'https://api.resourcewatch.org/v1/query/b99c5f5e-00c6-452e-877c-ced2b9f0b393?sql=SELECT avg, min from nexgddp-historical-ACCESS1_0-prmaxday where year = 1960'

Calculate statistics for a range of years:

curl -i -XGET 'https://api.resourcewatch.org/v1/query/b99c5f5e-00c6-452e-877c-ced2b9f0b393?sql=SELECT * from nexgddp-historical-ACCESS1_0-prmaxday where year between 1960 and 1962'

You can delimit an area of interest by providing a geostore id as a parameter:

curl -i -XGET 'https://api.resourcewatch.org/v1/query/b99c5f5e-00c6-452e-877c-ced2b9f0b393?sql=SELECT * from nexgddp-historical-ACCESS1_0-prmaxday where year between 1960 and 1962&geostore=0279093c278a64f4c3348ff63e4cfce0'

Jiminy

Example jiminy GET request providing the SQL as query param:

curl -X GET 'https://api.resourcewatch.org/v1/jiminy?sql=SELECT col_1, col_2 FROM <dataset.id> limit <number>' \
-H "Content-Type: application/json"

Example jiminy POST request providing the SQL in the request body:

curl -X POST 'https://api.resourcewatch.org/v1/jiminy' \
-H "Content-Type: application/json" \
-d '{
   "sql": "SELECT col_1, col_2 FROM <dataset.id> limit <number>"
  }'

Example with real data:

curl -X GET 'https://api.resourcewatch.org/v1/jiminy?sql=SELECT iso, name_0, name_1, type_1 FROM 098b33df-6871-4e53-a5ff-b56a7d989f9a limit 10' \
-H "Content-Type: application/json"

The jiminy endpoint of the RW API makes use of the Jiminy library in order to infer which type of charts can be obtained from a the execution of a SQL query on a given dataset. For a better understanding of this endpoint, it is recommended to read beforehand on how to query datasets.

To use this endpoint and infer the charts that you can build from a result set, you must provide a valid SQL query. This query should contain the name of the columns for which you want to infer the chart types - the usage of the wildcard selector (SELECT *) in the SQL query is not supported by this endpoint.

Note: You must set a limit value to the SQL query provided. If you do not set it and the dataset contains a lot of data, this endpoint will try to obtain all data at once, which can result in performance issues.

Likewise with query and download endpoints, you can either provide the SQL as query param in a GET request, or in the body of the request as a POST request - read more here. Using the GET request is the recommended approach, as it allows HTTP caching of your result - subsequent requests for the same jiminy endpoint call will see a great performance increase, even if they are made by a different application or client. Alternatively, you can also call the jiminy endpoint using a POST request. POST requests are not cached, so you will not benefit from these speed improvements. However, GET requests can sometimes hit URL length restrictions, should your SQL query string be too long. Using a POST request is the recommended solution for these cases.

Jiminy response body

Example of successful response:

{
    "data": {
        "general": [
            "bar",
            "pie",
            "scatter"
        ],
        "byColumns": {
            "iso": [
                "bar",
                "pie"
            ],
            "name_0": [
                "bar",
                "pie"
            ],
            "name_1": [
                "bar",
                "pie"
            ],
            "type_1": [
                "bar",
                "pie"
            ]
        },
        "byType": {
            "bar": {
                "general": [
                    "iso",
                    "name_0",
                    "name_1",
                    "type_1"
                ],
                "columns": {
                    "iso": [],
                    "name_0": [],
                    "name_1": [],
                    "type_1": []
                }
            },
            "line": {
                "general": [],
                "columns": {
                    "iso": [],
                    "name_0": [],
                    "name_1": [],
                    "type_1": []
                }
            },
            "pie": {
                "general": [
                    "iso",
                    "name_0",
                    "name_1",
                    "type_1"
                ],
                "columns": {
                    "iso": [],
                    "name_0": [],
                    "name_1": [],
                    "type_1": []
                }
            },
            "scatter": {
                "general": [
                    "iso",
                    "name_0",
                    "name_1",
                    "type_1"
                ],
                "columns": {
                    "iso": [
                        "name_0",
                        "name_1",
                        "type_1"
                    ],
                    "name_0": [
                        "iso",
                        "name_1",
                        "type_1"
                    ],
                    "name_1": [
                        "iso",
                        "name_0",
                        "type_1"
                    ],
                    "type_1": [
                        "iso",
                        "name_0",
                        "name_1"
                    ]
                }
            },
            "1d_scatter": {
                "general": [],
                "columns": {
                    "iso": [],
                    "name_0": [],
                    "name_1": [],
                    "type_1": []
                }
            },
            "1d_tick": {
                "general": [],
                "columns": {
                    "iso": [],
                    "name_0": [],
                    "name_1": [],
                    "type_1": []
                }
            }
        }
    }
}

For a successful response, the response body is a JSON object containing a single index data, which describes the type of charts that can be obtained from the query provided. The following fields are usually present in the data object:

Field Type Description Example
data.general Array An array of distinct charts that can be used to represent the data of the query. ["bar", "pie"]
data.byColumns Object An object where the keys are the columns provided in the SQL query. For each the, its value is an array with the names of the charts that might be used to represent the data from the column in the key. { "iso": ["bar", "pie"], "name_0": ["bar", "pie"] },
data.byType Object An object where the keys are all the charts supported by Jiminy. The values will contain the column names of the query execution that might be used to display the chart type in the key. If the chart type was not included in the data.general field of the response body, its content will likely be empty. { "bar": { "general": ["iso", "name_0", "name_1", "type_1"], "columns": { "iso": [], "name_0": [], "name_1": [], "type_1": [] } } }

Jiminy execution errors

The jiminy endpoint might sometimes return an error response. The following table describes the possible errors that can occur when calling this endpoint:

Error code Error message Description
400 SQL o FS required The required sql field is missing either as query string parameter or in the request body.
500 Internal server error The error message might vary in this case.

Jiminy endpoint parameters

The jiminy endpoint makes use of a single query parameter, which is required for a successful call of the endpoint:

Query parameter Description Type Required
sql The SQL query which will be the basis for inferring the chart types. String Yes

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 as well as getting some information about them.

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

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

Real example

curl -X GET https://api.resourcewatch.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 a more verbose field 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://api.resourcewatch.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

Metadata is data concerning another resource available on this API. It only exists when associated with another resource - currently supported resource types are datasets, widgets or layers. Note that, although there might be several metadata per resource, each resource will have - at most - one metadata element per application and language pair. As such, the application and language attributes are required and it is mandatory to include them in when creating/updating metadata.

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

As previously discussed, a metadata entity is always associated with either a dataset, a widget or a layer resource, and the type of resource it is associated to dictates which of 3 endpoints you should use when creating a new metadata entity.

In all scenarios, you must be authenticated to be able to create a metadata entity, and meet the following requirements:

Any of these conditions are not met, the API will generate a 403 Forbidden error message.

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

Create metadata for a dataset

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

Create metadata for a widget

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

Create metadata for a layer

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

Real example

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

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",
        "createdAt": "2017-01-20T08:07:53.272Z",
        "updatedAt": "2017-01-20T08:07:53.272Z",
        "status": "published"
      }
    }
  ]
}

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://api.resourcewatch.org/v1/dataset/<dataset-id>/metadata
curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/metadata
curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/metadata

Real example

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

Updating a metadata

As previously discussed, a metadata entity is always associated with either a dataset, a widget or a layer resource, and the type of resource it is associated to dictates which of 3 endpoints you should use when updating a metadata entity.

In all scenarios, you must be authenticated to be able to update a metadata entity, and meet the following requirements:

Any of these conditions are not met, the API will generate a 403 Forbidden error message.

When updating a metadata, you must always specify both language and application, those will be used to determine which metadata entity will be updated.

Update metadata for a dataset

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

Update metadata for a widget

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

Update metadata for a layer

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

Real example

curl -X PATCH https://api.resourcewatch.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

As previously discussed, a metadata entity is always associated with either a dataset, a widget or a layer resource, and the type of resource it is associated to dictates which of 3 endpoints you should use when deleting a metadata entity.

In all scenarios, you must be authenticated to be able to delete a metadata entity, and meet the following requirements:

Any of these conditions are not met, the API will generate a 403 Forbidden error message.

When deleting a metadata, you must always specify both language and application, those will be used to determine which metadata entity will be deleted.

Delete metadata for a dataset

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

Delete metadata for a widget

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

Delete metadata for a layer

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

Real example

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

Getting all

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

Real examples

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

Finding metadata by ids

The ids property is required in the body of the request. It can be either an array of ids or a string of comma-separated ids:

Filters

The metadata list provided by the endpoint can be filtered with the following attributes:

Filter Description Accepted values
application Application associated with the metadata entity any valid text
language Language of the metadata entity any valid text

Finding metadata by ids for a dataset

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

Finding metadata by ids for a widget

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

Finding metadata by ids for a layer

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

Real example

curl -X POST https://api.resourcewatch.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"
      }
    }
  ]
}

Vocabulary (and Tags)

Resource definition

A Resource represents an external entity that will be related with a Vocabulary. The most common resources used when creating relationships with vocabulary are datasets, layers and widgets.

Tags definition

A Tag is a way to categorize a resource within a vocabulary context.

Vocabulary definition

The Vocabulary can be described as a cluster of tags.

It is currently possible to just create a Vocabulary without any tags or relationships. To do it, the only parameter that is required is the name of the Vocabulary.

Field Description Type
name The name of the Vocabulary (it has to be unique and it represents the “primaryKey”) String
application The associated application for this vocabulary String

However, the most common use case relies on the relationships creation.

Relationships

This section describes how to associate an existing or new Vocabulary to a resource.

Some important points:

Creating a Vocabulary-Resource relationship

To create a relationship between a Resource and a Vocabulary (even if the Vocabulary or the Resource doesn’t exist yet) it is only required that you set the tags that define the relationship.

Some writing operations can take a little more time than reading ones. Even if the relationships are not strong, the writing operations have to ensure consistency along entities.

Remember that you can create relationshipts between Vocabulary and datasets, widgets or layers (the supported Resources).

Creating a relationship between a Vocabulary and a Dataset

curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset-id>/vocabulary/<vocabulary-id> \
-H "Content-Type: application/json"  -d \
 '{
 "application": <application>,
   "tags": [<tags>]
  }'

Creating a relationship between a Vocabulary and a Widget

curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/vocabulary/<vocabulary-id> \
-H "Content-Type: application/json"  -d \
 '{
 "application": <application>,
   "tags": [<tags>]
  }'

Creating a relationship between a Vocabulary and a Layer

curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/vocabulary/<vocabulary-id> \
-H "Content-Type: application/json"  -d \
 '{
 "application": <application>,
   "tags": [<tags>]
  }'

Example of request with real data

curl -X POST https://api.resourcewatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/vocabulary/science
-H "Content-Type: application/json"  -d \
 '{
 "application": <application>,
   "tags": ["biology", "chemistry"]
  }'

Example of response with real data

{
  "data": [
    {
      "id": "vocabularyNameOne",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "tag1",
          "tag2",
          "tag3"
        ]
      }
    },
    {
      "id": "science",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "biology",
          "chemistry"
        ]
      }
    },
    {
      "id": "aaa",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "biology",
          "chemistry"
        ]
      }
    }
  ]
}

Updating an existing Vocabulary-Resource relationship

If a relationship has to be updated, it’s necessary to define it’s new tags. The previous tags will be deleted in benefit of the new ones.

Updating a relationship between a Vocabulary and a Dataset

curl -X PATCH https://api.resourcewatch.org/v1/dataset/<dataset-id>/vocabulary/<vocabulary-id> \
-H "Content-Type: application/json"  -d \
 '{
 "application": <application>,
   "tags": [<tags>]
  }'

Updating a relationship between a Vocabulary and a Widget

curl -X PATCH https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/vocabulary/<vocabulary-id> \
-H "Content-Type: application/json"  -d \
 '{
 "application": <application>,
   "tags": [<tags>]
  }'

Updating a relationship between a Vocabulary and a Layer

curl -X PATCH https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/vocabulary/<vocabulary-id> \
-H "Content-Type: application/json"  -d \
 '{
 "application": <application>,
   "tags": [<tags>]
  }'

Example of request with real data

curl -X PATCH https://api.resourcewatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/vocabulary/science
-H "Content-Type: application/json"  -d \
 '{
 "application": <application>,
   "tags": ["maths", "astronomy"]
  }'

Example of response with real data

{
  "data": [
    {
      "id": "vocabularyNameOne",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "tag1",
          "tag2",
          "tag3"
        ]
      }
    },
    {
      "id": "science",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "maths",
          "astronomy"
        ]
      }
    },
    {
      "id": "aaa",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "biology",
          "chemistry"
        ]
      }
    }
  ]
}

Creating several Vocabulary-Resource relationships

There is also an endpoint that allows you to create multiple relationships in the same request.

Creating multiple relationships between a Vocabulary and a Dataset

curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset-id>/vocabulary \
-H "Content-Type: application/json"  -d \
 '{
   "vocabularyOne": {
   "application": <application>,
       "tags": [<tags>]
   },
   "vocabularyTwo": {
   "application": <application>,
       "tags": [<tags>]
   }
  }'

Creating multiple relationships between a Vocabulary and a Widget

curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/vocabulary\
-H "Content-Type: application/json"  -d \
'{
  "vocabularyOne": {
  "application": <application>,
      "tags": [<tags>]
  },
  "vocabularyTwo": {
  "application": <application>,
      "tags": [<tags>]
  }
 }'

Creating multiple relationships between a Vocabulary and a Layer

curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/vocabulary \
-H "Content-Type: application/json"  -d \
'{
  "vocabularyOne": {
  "application": <application>,
      "tags": [<tags>]
  },
  "vocabularyTwo": {
  "application": <application>,
      "tags": [<tags>]
  }
 }'

Example of request with real data

curl -X POST https://api.resourcewatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/vocabulary?application=<application>
-H "Content-Type: application/json"  -d \
 '{
     "country": {
         "tags": ["Spain", "Italy", "Portugal"]
     },
     "sport": {
         "tags": ["football", "basketball", "voleyball"]
     },
     "color": {
         "tags": ["red", "green", "blue"]
     }
  }'

Example of response with real data

{
  "data": [
    {
      "id": "vocabularyNameTwo",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "tag1",
          "tag2",
          "tag3"
        ]
      }
    },
    {
      "id": "vocabularyNameOne",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "tag1",
          "tag2",
          "tag3"
        ]
      }
    },
    {
      "id": "a",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "tag1",
          "tag2",
          "tag3"
        ]
      }
    },
    {
      "id": "b",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "tag1",
          "tag2",
          "tag3"
        ]
      }
    },
    {
      "id": "newV",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "test1",
          "test2"
        ]
      }
    },
    {
      "id": "country",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "Spain",
          "Italy",
          "Portugal"
        ]
      }
    },
    {
      "id": "sport",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "football",
          "basketball",
          "voleyball"
        ]
      }
    },
    {
      "id": "color",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "red",
          "green",
          "blue"
        ]
      }
    }
  ]
}

Deleting relationships

Deleting relationships between a Vocabulary and a Dataset

curl -X DELETE https://api.resourcewatch.org/v1/dataset/<dataset-id>/vocabulary/<vocabulary-id>

Deleting relationships between a Vocabulary and a Widget

curl -X DELETE https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/vocabulary/<vocabulary-id>

Deleting relationships between a Vocabulary and a Layer

curl -X DELETE https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/vocabulary/<vocabulary-id>

Example of request with real data

curl -X DELETE https://api.resourcewatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/vocabulary/science

Example of response with real data

{
  "data": [
    {
      "id": "country",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "Spain",
          "Italy",
          "Portugal"
        ]
      }
    },
    {
      "id": "color",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "red",
          "green",
          "blue"
        ]
      }
    }
  ]
}

Getting Vocabularies associated to a Resource

You can be request all vocabularies that are associated to a particular resource.

Getting Vocabularies related with a Dataset

curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/vocabulary

Getting Vocabularies related with a Widget

curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/vocabulary

Getting Vocabularies related with a Layer

curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/vocabulary

Example of request with real data

curl -X GET https://api.resourcewatch.org/v1/dataset/942b3f38-9504-4273-af51-0440170ffc86/vocabulary

Example of response with real data

{
  "data": [
    {
      "id": "country",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "Spain",
          "Italy",
          "Portugal"
        ]
      }
    },
    {
      "id": "color",
      "type": "vocabulary",
      "attributes": {
        "tags": [
          "red",
          "green",
          "blue"
        ]
      }
    }
  ]
}

Getting a single relationship (broken now)

Getting a single relationship between a Vocabulary and a Dataset

curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/vocabulary/<vocabulary-id>

Getting a single relationship between a Vocabulary and a Widget

curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/<widget-id>/vocabulary/<vocabulary-id>

Getting a single relationship between a Vocabulary and a Layer

curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/<layer-id>/vocabulary/<vocabulary-id>

Getting resources (COMMON USE CASE)

There is also an endpoint available which accepts requests just indicating resource type and the desired vocabulary-tag matching.

It currently supports DOUBLE-OR pattern matching, meaning the API will return all resources that at least have one (or more) tags in a particular vocabulary. At the same time it will also apply an OR to the entities of other vocabulary-tag matchings.

The query has to be set in the url by the query params.

curl -X GET https://api.resourcewatch.org/v1/dataset/vocabulary/find
curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/vocabulary/find
curl -X GET https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/vocabulary/find

Example of response with real data

curl -X GET http://api.resourcewatch.org/v1/dataset/vocabulary/find?legacy=cdi,coasts

Getting all vocabularies

This endpoint is quite useful to have a quick overview of all existing vocabularies and resources.

curl -X GET https://api.resourcewatch.org/v1/vocabulary

Finding vocabularies by ids

The ids property is required in the body of the request. It can be either an array of ids or a string of comma-separated ids:

curl -X POST https://api.resourcewatch.org/v1/dataset/vocabulary/find-by-ids \
-H "Content-Type: application/json"  -d \
 '{
   "ids": [<ids>]
  }'
curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset-id>/widget/vocabulary/find-by-ids \
-H "Content-Type: application/json"  -d \
 '{
   "ids": [<ids>]
  }'
curl -X POST https://api.resourcewatch.org/v1/dataset/<dataset-id>/layer/vocabulary/find-by-ids \
-H "Content-Type: application/json"  -d \
 '{
   "ids": [<ids>]
  }'

Example of request with real data

curl -X POST https://api.resourcewatch.org/v1/dataset/vocabulary/find-by-ids \
-H "Content-Type: application/json"  -d \
 '{
    "ids": "942b3f38-9504-4273-af51-0440170ffc86, 08ff8183-48dc-457a-8924-bb4e7a87b8a8"
  }'

Example of response with real data

{
  "data": [
    {
      "type": "resource",
      "id": "08ff8183-48dc-457a-8924-bb4e7a87b8a8",
      "attributes": {
        "legacy": [
          "cdi",
          "inundation",
          "national",
          "united states",
          "local",
          "coasts",
          "flooding",
          "health"
        ]
      }
    },
    {
      "type": "resource",
      "id": "942b3f38-9504-4273-af51-0440170ffc86",
      "attributes": {
        "country": [
          "Spain",
          "Italy",
          "Portugal"
        ],
        "color": [
          "red",
          "green",
          "blue"
        ]
      }
    }
  ]
}

Vocabulary Creation

As was mentioned before, it is possible to just create a new and empty vocabulary

curl -X POST https://api.resourcewatch.org/v1/vocabulary/vocabularyName \
-H "Content-Type: application/json"  -d \
 '{
   "application": <application>,
   "name": <vocabularyName>
  }'

It is also possible to update and delete an entire vocabulary. Said that, because it’s necessary to keep consistency between entities with weak relationship, these operations are only available to SUPERADMINS.

Bulk delete of resource’s vocabulary

Deleting all Vocabulary associated with a Dataset

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

Deleting all Vocabulary associated with a Widget

curl -X DELETE https://api.resourcewatch.org/v1/dataset/datasetId/widget/:widgetId/vocabulary \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>"

Deleting all Vocabulary associated with a Layer

curl -X DELETE https://api.resourcewatch.org/v1/dataset/datasetId/layer/:layerId/vocabulary \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>"

In order to use these endpoints, you need to meet one of the following criteria:

All endpoints return 200 OK in case of success, along with the list of the deleted entities.

Geostore

What is Geostore?

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

Geostore object contains the following 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 should be 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. It is possible use 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 in 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 query with the following body:

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

Real example

curl -X POST https://api.resourcewatch.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 saves correctly and returns 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://api.resourcewatch.org/v1/geostore/admin/<ISO3>

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

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

Country list

A list of countries can be obtained from this endpoint.

curl -X GET https://api.resourcewatch.org/v1/geostore/admin/list

Example response

{
    "data": [{
        "geostoreId": "35a6d982388ee5c4e141c2bceac3fb72",
        "iso": "ESP",
        "name": "Spain"
    }, {
        "geostoreId": "8f77fe62cf15d5098ba0ee11c5126aa6",
        "iso": "FRA",
        "name": "France"
    }, {
        "geostoreId": "1d568c183033da6c17cc28c4aecf1bcf",
        "iso": "cod",
        "name": "Democratic Republic of the Congo"
    }]
}

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://api.resourcewatch.org/v1/geostore/admin/<ISO3>/<regionCode>

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

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

curl -X GET https://api.resourcewatch.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://api.resourcewatch.org/v1/geostore/wdpa/<wdpaId>

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

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

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

From land use areas

Geostore has the geojson of 4 different lands use:

Oil palm

GET https://api.resourcewatch.org/v1/geostore/use/oilpalm/<id>

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

Real example obtaining the geostore of one Oil palm area

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

Mining

GET https://api.resourcewatch.org/v1/geostore/use/mining/<id>

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

Real example obtaining the geostore of one mining area

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

Wood fiber

GET https://api.resourcewatch.org/v1/geostore/use/fiber/<id>

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

Real example obtaining the geostore of one Wood fiber area

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

Congo Basin logging roads

GET https://api.resourcewatch.org/v1/geostore/use/logging/<id>

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

Real example obtaining the geostore of Oil palm area

curl -X GET https://api.resourcewatch.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://api.resourcewatch.org/v1/geostore \
-H "Content-Type: application/json"  -d \
 '{
    "provider":{
        "type": "carto",
        "table": <tableName>,
        "user": <userName>,
        "filter": <conditions>
    }
}'

Real example

curl -X POST https://api.resourcewatch.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://api.resourcewatch.org/v1/geostore/<geostoreId>

Real example obtaining one geostore

curl -X GET https://api.resourcewatch.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

Subscription represents to which datasets and analysis a user can have access to.

Subscribable datasets

In order to create a subscription, a dataset must be prepared to accept them. This is achieved by declaring some queries in the dataset json object sent to the /v1/dataset endpoint under the subscribableproperty.

{
    "name": "dataset name",
    "application": ["app"],
    "provider": "dataset provider",
    "other": "dataset_fields",
    "subscribable": {
        "test_subscription": {
            "dataQuery": "SELECT * FROM dataset-name  WHERE \"reported_date\" >= '{{begin}}' AND \"reported_date\" <= '{{end}}' AND \"number_dead\" > 0 ORDER BY reported_date DESC LIMIT 10",
            "subscriptionQuery": "SELECT COUNT(*) FROM dataset-name WHERE \"reported_date\" >= '{begin}' AND \"reported_date\" <= '{end}' AND \"number\" > 0"
        }
    }
}

Inside the subscribable object, one (or several) sub-objects can be declared. In the provided example, the test_subscription is provided, with both a dataQuery and a subscriptionQuery. The former will be evaluated as the subscription’s content, while the latter will be evaluated to check if a subscription has changed since the last update. Both queries can contain two special keywords: {begin} and {end}. These will be substituted with ansi-formatted datetimes –with the datetime in which the subscription was last evaluated, and the datetime at the time of evaluation, respectively.

Creating a Subscription

Field Description Type Required
name Name Text No
application Application of the subscription. Set to gfw by default String No
language Language of the subscriptions (used to select the email template) en, es, fr, pt, zh Yes
resource Details on the resource that will be notified for the subscription. Object Yes
– type The type of resource to notify. If EMAIL, an email is sent to the email saved in the resource content. If URL, a POST is requested to the web-hook URL in the resource content. String Yes
– content The email or URL that will be notified (according to the type). String Yes
datasets Array of datasets of the subscription Array Yes (unless datasetsQuery is specified)
datasetsQuery Subscriptions to subscribable datasets Array Yes (unless datasets is specified)
– id Id of dataset ObjectId Yes (unless datasets is specified)
– type Type of subscription defined in the dataset Text Yes (unless datasets is specified)
– params Geographic area of the subscription Object Yes (unless datasets is specified)
env Environment of the subscription. Set to production by default String No
userId Check here for more info String No

A way to determine the area of interest for the subscriptions needs to be provided. A subscription can be created in six different ways:

With an 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 request with the following body:

curl -X POST https://api.resourcewatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
    "name": "<name>",
    "datasets": [
        "<dataset>"
    ],
    "params": {
        "geostore": "35a6d982388ee5c4e141c2bceac3fb72"
    },
    "datasetsQuery": [
        {
            "id": ":subscription_dataset_id",
            "type": "test_subscription",
            "threshold": 1
        }
    ],
    "application": "rw",
    "language": "en",
    "env": <environment>,
    "resource": {
        "type": "EMAIL",
        "content": "email@address.com"
    }
}'

In this case, a subscription is being created in reference to the subscribable field present in the previously defined dataset. After confirming the subscription the subscriptionQuery will be ran and its result will be compared against the threshold. If the query result is at least equal to the threshold, a new alert will be sent to the subscription’s email.

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://api.resourcewatch.org/v1/subscriptions \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "<name>",
   "application": "<application>",
   "env": <environment>,
   "language": "<language>",
   "resource": {
       "type": "<type>",
       "content": "<content>"
   },
   "datasets" : ["<dataset>"],
   "params": {
       "iso": {
           "country": "<iso>"
       }
   },
   "datasetsQuery": [{}]
  }'

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 request with the following body:

curl -X POST https://api.resourcewatch.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>"],
   "env": <environment>,
   "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 request with the following body:

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

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 request with the following body:

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

Subscription has 4 different lands uses:

Oil palm

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

Mining

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

Wood fiber

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

Congo Basin logging roads

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

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 request with the following body:

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

Confirm subscription

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

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

Get a subscription by its ID

You can get the data from a specific subscription using the following GET request:

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

Example

curl -X GET https://api.resourcewatch.org/v1/subscriptions/5d9c933c04c106001056d2a1 \
-H "Authorization: Bearer xxxxxx"

Response:


{
    "data":
    {
        "type": "subscription",
        "id": "5d9c933c04c106001056d2a1",
        "attributes":
        {
            "name": "",
            "createdAt": "2019-10-08T13:46:36.894Z",
            "userId": "58e22f662071c01c02f76a0f",
            "resource":
            {
                "type": "EMAIL",
                "content": "aaa@aaa.com"
            },
            "datasets":
            [
                "20cc5eca-8c63-4c41-8e8e-134dcf1e6d76"
            ],
            "params": {},
            "confirmed": false,
            "language": "en",
            "datasetsQuery":
            [
                {
                    "threshold": 1,
                    "lastSentDate": "2019-10-08T13:46:36.895Z",
                    "historical": [],
                    "type": "COUNT"
                }
            ],
            "env": "production"
        }
    }
}

Get subscriptions for a user

You can get a list of the current user’s subscriptions using the following endpoint. In order to use this endpoint, you need to be logged in.

curl -X GET https://api.resourcewatch.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": [],
            "env": "production"
         }
      }
   ]
}

This endpoint supports the following optional query parameters as filters:

Field Description Type Default value
application Application to which the subscription is associated. String ‘gfw’
env Id of geostore String 'production’

Resend confirmation

To resend the confirmation:

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

Modify a subscription

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

To modify a subscription, use the following PATCH endpoint. This endpoint requires authentication, and also you must be the owner of the subscription in order to edit it, otherwise the request will fail with 404 Not Found.

The following fields are available to be provided when modifying a subscription:

Field Description Type Required
name Name Text No
application Application of the subscription. Set to gfw by default String No
language Language of the subscriptions (used to select the email template) en, es, fr, pt, zh Yes
resource Details on the resource that will be notified for the subscription. Object Yes
– type The type of resource to notify. If EMAIL, an email is sent to the email saved in the resource content. If URL, a POST is requested to the web-hook URL in the resource content. String Yes
– content The email or URL that will be notified (according to the type). String Yes
datasets Array of datasets of the subscription Array Yes (unless datasetsQuery is specified)
datasetsQuery Subscriptions to subscribable datasets Array Yes (unless datasets is specified)
– id Id of dataset ObjectId Yes (unless datasets is specified)
– type Type of subscription defined in the dataset Text Yes (unless datasets is specified)
– params Geographic area of the subscription Object Yes (unless datasets is specified)
env Environment of the subscription. Set to production by default String No

Unsubscribe

To unsubscribe from a subscription:

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

Delete subscription

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

To delete a subscription, use the following DELETE endpoint.

If the request comes from another microservice, then it is possible to delete subscriptions belonging to other users. Otherwise, you can only delete subscriptions if you are the owner of the subscription.

Subscription statistics

Statistics endpoints require authentication by an ADMIN user.

General subscription statistics

The subscription/statistics endpoint can be used to access all data regarding the subscription notifications that have been sent.

This endpoint supports the following query parameters as filters (please note that the dates must be formatted as MM-DD-YYYY):

Field Description Type Default Example
start The start of the date range to fetch the statistics. This parameter is required. String None 01-01-2020
end The end of the date range to fetch the statistics. This parameter is required. String None 02-20-2020
application The application for which the statistics will be fetched. String 'gfw’ 'rw’
curl -X GET https://api.resourcewatch.org/v1/subscriptions/statistics?start=:start&end=:end \
-H "Authorization: Bearer <your-token>"

Response:


{
    "topSubscriptions": {
        "geostore": 1000,
        "country": 30,
        "region": 20,
        "wdpa": 10,
        "use": 1
    },
    "info": {
        "numSubscriptions": 1000,
        "totalSubscriptions": 6000,
        "usersWithSubscriptions": 1000,
        "totalEmailsSentInThisQ": 0,
        "totalEmailsSended": 0
    },
    "usersWithSubscription": 119,
    "newUsers": 210,
    "groupStatistics": {
        "glad-alerts": {
            "country": 15,
            "region": 28,
            "use": 1,
            "wdpa": 9,
            "geostore": 1305,
            "countries": {
                "CHL": 1,
                "IDN": 3,
                ...
            },
            "regions": {
                "1": 1,
                "2": 2,
                ...
            },
            "wdpas": {
                "130": 1,
                "34043": 5,
                ...
            },
            "countryTop": {
                "name": "IDN",
                "value": 3
            },
            "regionTop": {
                "nameRegion": 12,
                "nameCountry": "IDN",
                "value": 2
            },
            "wdpaTop": {
                "id": 34043,
                "value": 5
            }
        },
        "prodes-loss": {...},
        "umd-loss-gain": {...},
        "terrai-alerts": {...},
        "viirs-active-fires": {...},
        "imazon-alerts": {...},
        "forma250GFW": {...},
        "forma-alerts": {...},
        "story": {...},
        "63f34231-7369-4622-81f1-28a144d17835": {...}
    }
}

Grouped subscription statistics

The subscription/statistics-group endpoint can be used to access data regarding the subscription notifications that have been sent, grouped by the the dataset of the subscription.

This endpoint supports the following query parameters as filters (please note that the dates must be formatted as MM-DD-YYYY):

Field Description Type Default Example
start The start of the date range to fetch the statistics. This parameter is required. String None 01-01-2020
end The end of the date range to fetch the statistics. This parameter is required. String None 02-20-2020
application The application for which the statistics will be fetched. String 'gfw’ 'rw’
curl -X GET https://api.resourcewatch.org/v1/subscriptions/statistics-group?start=:start&end=:end \
-H "Authorization: Bearer <your-token>"

Response:


{
    "glad-alerts": {
        "country": 15,
        "region": 28,
        "use": 1,
        "wdpa": 9,
        "geostore": 1305,
        "countries": {
            "CHL": 1,
            "IDN": 3,
            ...
        },
        "regions": {
            "1": 1,
            "2": 2,
            ...
        },
        "wdpas": {
            "130": 1,
            "34043": 5,
            ...
        },
        "countryTop": {
            "name": "IDN",
            "value": 3
        },
        "regionTop": {
            "nameRegion": 12,
            "nameCountry": "IDN",
            "value": 2
        },
        "wdpaTop": {
            "id": 34043,
            "value": 5
        }
    },
    "prodes-loss": {...},
    "umd-loss-gain": {...},
    "terrai-alerts": {...},
    "viirs-active-fires": {...},
    "imazon-alerts": {...},
    "forma250GFW": {...},
    "forma-alerts": {...},
    "story": {...},
    "63f34231-7369-4622-81f1-28a144d17835": {...}
}

Favorites

The users can save their own favorites resources of the API.

Field Description Type
id Name Text
resourceId Id of the resource Text
resourceType Type of resource Text (dataset, layer, widget)
userId Id of the owner user Text
createdAt Creation date Date

Create Favorite

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

Field Description Type
resourceId Id of the resource Text
resourceType Type of resource Text (dataset, layer, widget)

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

curl -X POST https://api.resourcewatch.org/v1/favourite \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "resourceType":"<resourceType>",
   "resourceId": "<resourceId>"
  }'

Get favorites

This endpoint returns the favorites of the logged user.

To get all favorite of the logged user, you have to do a GET request:

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

You can also retrieve all data about the resources by including the query parameter “include=true” in the request.

curl -X GET https://api.resourcewatch.org/v1/favourite?include=true \
-H "Authorization: Bearer <your-token>"

Get favorite by id

This endpoint returns the favorite with id of the param. If the favorite belongs to other user or not exist, the endpoint returns 400.

To get the favorite by id, you have to do a GET request:

curl -X GET https://api.resourcewatch.org/v1/favourite/:id \
-H "Authorization: Bearer <your-token>"

Delete favorite

This endpoint deletes the favorite with id of the param. If the favorite belongs to other user or not exist, the endpoint returns 400.

To delete the favorite by id, you have to do a DELETE request:

curl -X DELETE https://api.resourcewatch.org/v1/favourite/:id \
-H "Authorization: Bearer <your-token>"

Graph

The following graph endpoints are available

List concepts

Returns a list including all the concepts present in the graph

curl -X GET https://api.resourcewatch.org/v1/graph/query/list-concepts

Query example

{
  "data": [
    {
      "id": "europe",
      "label": "Europe",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ],
      "numberOfDatasetsTagged": 0
    },
    {
      "id": "damage",
      "label": "Damage",
      "synonyms": [
        "destruction"
      ],
      "labels": [
        "CONCEPT",
        "TOPIC"
      ],
      "numberOfDatasetsTagged": 2
    },
    {
      "id": "guernsey",
      "label": "Guernsey",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ],
      "numberOfDatasetsTagged": 0
    }
  ]
}

Get inferred concepts

This endpoint returns the set of concepts that are inferred from the set passed as a parameter

Parameters

Parameter Description Type Values Required
concepts List of concepts Text Any Text, values separated by commas Yes
curl -X GET https://api.resourcewatch.org/v1/graph/query/concepts-inferred?concepts=<concept_list>

Example

Concepts inferred from the set: [‘spain’, 'raster’]

https://api.resourcewatch.org/v1/graph/query/concepts-inferred?concepts=spain,raster
{
  "data": [
    {
      "id": "location",
      "label": "Location",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "TOPIC"
      ]
    },
    {
      "id": "eu",
      "label": "EU",
      "synonyms": [
        "European Union"
      ],
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ]
    },
    {
      "id": "raster",
      "label": "Raster",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "DATA_TYPE"
      ]
    },
    {
      "id": "oecd",
      "label": "OECD",
      "synonyms": [
        "Organisation for Economic Co-operation and Development"
      ],
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ]
    },
    {
      "id": "schengen_area",
      "label": "Schengen Area",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ]
    },
    {
      "id": "country",
      "label": "Country",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ]
    },
    {
      "id": "continent",
      "label": "Continent",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ]
    },
    {
      "id": "global",
      "label": "Global",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ]
    },
    {
      "id": "general",
      "label": "General",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "TOPIC"
      ]
    },
    {
      "id": "spain",
      "label": "Spain",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ]
    },
    {
      "id": "dataset",
      "label": "Dataset",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "DATA_TYPE"
      ]
    },
    {
      "id": "europe",
      "label": "Europe",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "GEOGRAPHY"
      ]
    }
  ]
}

Concepts’ ancestors

This endpoint returns the ancestors from the list of concepts provided

Parameters

Parameter Description Type Values Required
concepts List of concepts Text Any Text, values separated by commas Yes
https://api.resourcewatch.org/v1/graph/query/concepts-ancestors?concepts=<concept_list>

Example

Ancestors of the concepts from the set: ['forest_cover’, 'landslide’]

https://api.resourcewatch.org/v1/graph/query/concepts-ancestors?concepts=forest_cover,landslide
{
  "data": [
    {
      "id": "indicator",
      "label": "Indicator",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "TOPIC"
      ]
    },
    {
      "id": "forest",
      "label": "Forest",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "TOPIC"
      ]
    },
    {
      "id": "natural_disaster",
      "label": "Natural disaster",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "TOPIC"
      ]
    },
    {
      "id": "natural_phenomena",
      "label": "Natural phenomena",
      "synonyms": "",
      "labels": [
        "CONCEPT",
        "TOPIC"
      ]
    }
  ]
}

Similar datasets

Returns a set of datasets that are similar to the dataset provider sorted by their degree of similarity.

curl -X GET https://api.resourcewatch.org/v1/graph/query/similar-dataset/<dataset-id>

Parameters available

Parameter Description Type Values Required
published Include only published datasets Boolean true/false No
app List of applications datasets should belong to (at least one of them) Text Any text, values separated by commas No
env Include only datasets with at least one of the specified environments Text One or more values from ['production’, 'preproduction’] No
limit Maximum number of datasets returned by the endpoint Integer A positive integer (3 by default) No

Example

Datasets that are similar to the dataset with id 63a7a997-695d-4629-b6e9-9b169f5c69b including only those that are published with a limit of 6 results in total, datasets from both production and preproduction environments are included.

https://api.resourcewatch.org/v1/graph/query/similar-dataset/63a7a997-695d-4629-b6e9-9b169f5c69bf?published=true&env=production,preproduction&app=rw&limit=6
{
  "data": [
    {
      "dataset": "0a59f415-ee0b-4d19-96f7-c7304c152e1b",
      "concepts": [
        "global",
        "raster",
        "geospatial"
      ]
    },
    {
      "dataset": "0087944f-871c-44bc-b4d9-cd5acfc27023",
      "concepts": [
        "global",
        "raster",
        "geospatial"
      ]
    },
    {
      "dataset": "0303127a-70b0-4164-9251-d8162615d058",
      "concepts": [
        "raster",
        "geospatial"
      ]
    },
    {
      "dataset": "05b7c688-09ba-4f33-90ea-185a1039df43",
      "concepts": [
        "global",
        "geospatial"
      ]
    },
    {
      "dataset": "050f4146-566c-4a6d-9aaa-b49ab66a3090",
      "concepts": [
        "global",
        "geospatial"
      ]
    },
    {
      "dataset": "00abb46f-34e2-4bf7-be30-1fb0b1de022f",
      "concepts": [
        "global",
        "geospatial"
      ]
    }
  ]
}

Similar datasets including ancestors

Returns a set of datasets that are similar to the dataset provider sorted by their degree of similarity as well as taking into account ancestor concepts.

curl -X GET https://api.resourcewatch.org/v1/graph/query/similar-dataset-including-descendent/<dataset-id>

Parameters available

Parameter Description Type Values Required
published Include only published datasets Boolean true/false No
app List of applications datasets should belong to (at least one of them) Text Any text, values separated by commas No
env Include only datasets with at least one of the specified environments Text One or more values from ['production’, 'preproduction’] No
limit Maximum number of datasets returned by the endpoint Integer A positive integer (3 by default) No

Example

Datasets that are similar to the dataset with id 03bfb30e-829f-4299-bab9-b2be1b66b5d4 including only those that are published with a limit of 6 results in total, datasets from both production and preproduction environments are included.

https://api.resourcewatch.org/v1/graph/query/similar-dataset-including-descendent/03bfb30e-829f-4299-bab9-b2be1b66b5d4?published=true&env=production,preproduction&app=rw&limit=6
{
  "data": [
    {
      "dataset": "05b7c688-09ba-4f33-90ea-185a1039df43",
      "concepts": [
        "country",
        "forest",
        "geospatial",
        "table"
      ],
      "numberOfOcurrences": 1
    },
    {
      "dataset": "0448c79d-0ee0-42ff-9331-aeee70cef301",
      "concepts": [
        "forest_cover",
        "forest_gain",
        "forest_loss",
        "geospatial"
      ],
      "numberOfOcurrences": 1
    },
    {
      "dataset": "098b33df-6871-4e53-a5ff-b56a7d989f9a",
      "concepts": [
        "country",
        "geospatial"
      ],
      "numberOfOcurrences": 1
    },
    {
      "dataset": "0be2ce12-79b3-434b-b557-d6ea92d787fe",
      "concepts": [
        "geospatial",
        "table"
      ],
      "numberOfOcurrences": 1
    },
    {
      "dataset": "050f4146-566c-4a6d-9aaa-b49ab66a3090",
      "concepts": [
        "geospatial",
        "table"
      ],
      "numberOfOcurrences": 1
    },
    {
      "dataset": "00abb46f-34e2-4bf7-be30-1fb0b1de022f",
      "concepts": [
        "geospatial",
        "table"
      ],
      "numberOfOcurrences": 1
    }
  ]
}

Search datasets by concepts

This endpoint performs a dataset search based on the concepts provided and the tags that have been associated to all the different datasets that are part of the application. Ancestors of the tags directly associated to a datasets are taken into account in the search.

curl -X GET https://api.resourcewatch.org/v1/graph/query/search-datasets?concepts[0][0]='water'

Up to three sets of concepts can be provided as shown in the example below. Given the following sets of concepts:

The url should be formed as follows:

https://api.resourcewatch.org/v1/graph/query/search-datasets?concepts[0][0]=spain,concepts[0][1]=europe,concepts[1][0]=water,concepts[2][0]=raster,concepts[2][1]=geospatial

AND logical operators are applied among the sets while OR is used for set elements.

Parameters available

Parameter Description Type Values Required
published Include only published datasets Boolean true/false No
app List of applications datasets should belong to (at least one of them) Text Any text, values separated by commas No
env Include only datasets with at least one of the specified environments Text One or more values from ['production’, 'preproduction’] No
page[size] Maximum number of results returned by the endpoint Number No

Example

Search for datasets with the tag global and water and at least one of the two tags: raster, geospatial. The resulting datasets should also be published and be categorized either as production or preproduction and belong to the application rw. The total number of results returned won’t be limited since a very high number has been provided as limit (999999).

https://api.resourcewatch.org/v1/graph/query/search-datasets?concepts[0][0]=global&concepts[1][0]=water&concepts[2][0]=raster&concepts[2][1]=geospatial&published=true&env=production,preproduction&app=rw&page[size]=999999

{
  "data": [
    "11f43558-d703-4b9d-aff0-f2354a11b359",
    "1b97e47e-ca18-4e50-9aae-a2853acca3f0",
    "20c70a51-4ddf-4f6c-ad2c-1a6729b95fa4",
    "21ac3cd2-9c19-47c7-ad18-4bcad118870f",
    "33bed1fb-9261-41bf-8b50-127a4d0c80c5",
    "3624554e-b240-4edb-9110-1f010642c3f3",
    "36803484-c413-49a9-abe2-2286ee99b624",
    "371e700e-bc9a-4526-af92-335d888de309",
    "60be01b0-99fb-459c-8a08-b934270f8c4b",
    "63a7a997-695d-4629-b6e9-9b169f5c69bf",
    "894f43a8-ce8e-43a5-a4c7-fa80faa43d63",
    "99075509-df36-461e-abb0-659cee555bd0",
    "9e9a5c50-b825-4f12-838f-1650943c2be1",
    "c17fab24-f71a-4c3e-bb87-6b753a944e6b",
    "c9eadefd-4a06-4f3b-a2eb-3e3f45624c24",
    "d7c3d954-ac86-4d1a-bb6a-c8c432a94e26",
    "e63bb157-4b98-4ecb-81d6-c1b15e79895a",
    "e7582657-9c16-4eb1-89e8-0211d94015c6",
    "e94f0e2d-2b5f-41ed-967f-d97e54dd81ea",
    "ede84747-0116-45c2-accb-1dfe141c00ff",
    "f717ac77-6f06-493f-8336-4e660a18f74c",
    "fa6443ff-eb95-4d0f-84d2-f0c91682efdf"
  ]
}

Get most liked datasets

This endpoint returns the list of the most liked datasets in descending order.

curl -X GET https://api.resourcewatch.org/v1/graph/query/most-liked-datasets

Response:

{
    "data": [
        {
            "id": "e2971008-029f-441b-97cd-ee0555728182",
            "count": {
                "low": 2,
                "high": 0
            }
        },
        {
            "id": "f6bb99af-541a-4d41-9e47-cc36cb479d4b",
            "count": {
                "low": 2,
                "high": 0
            }
        },
        {
            "id": "223b936e-06b8-4970-abd9-4f123904d95d",
            "count": {
                "low": 2,
                "high": 0
            }
        },
        {
            "id": "0b9f0100-ce5b-430f-ad8f-3363efa05481",
            "count": {
                "low": 2,
                "high": 0
            }
        }
    ]
}

Get most viewed datasets list

This endpoint returns the list of the most viewed datasets in descending order of total views.

Parameters

Parameter Description Type Values Required
limit Maximum number of results Number Any positive number No
curl -X GET https://api.resourcewatch.org/v1/graph/query/most-viewed

Response:

{
  "data": [
    {
      "dataset": "0087944f-871c-44bc-b4d9-cd5acfc27023",
      "views": 172
    },
    {
      "dataset": "00abb46f-34e2-4bf7-be30-1fb0b1de022f",
      "views": 68
    },
    {
      "dataset": "01b0b8cf-6638-4a9b-9896-d919d0656a64",
      "views": 5
    },
    {
      "dataset": "01ae2fd7-b818-429f-a27e-a36c8def971a",
      "views": 2
    },
    {
      "dataset": "00b5c224-8a78-41c4-89a6-8299dec8609e",
      "views": 0
    }
  ]
}

Update view counter for dataset and user

Updates the total view counter for the corresponding dataset. If the request is authenticated, it will also increment the counter of number of times the user has viewed the dataset.

curl -X POST https://api.resourcewatch.org/v1/graph/dataset/<dataset-id>/visited
-H "Authorization: Bearer <your-token>"

Areas

The following area endpoints are available

Get user areas

Returns the list of areas created by the user provided

Parameters

Parameter Description Type Values Required
application Application Text Any Text, values separated by commas No
curl -X POST https://api.resourcewatch.org/v1/area?application=<application>
-H "Authorization: Bearer <your-token>"

Example

Areas created by an user for the application RW.

curl -X POST https://api.resourcewatch.org/v1/area?application=rw
-H "Authorization: Bearer <your-token>"
{
  "data": [
    {
      "type": "area",
      "id": "59ca3213d08a7d001054522b",
      "attributes": {
        "name": "Test area France",
        "application": "rw",
        "geostore": "8f77fe62cf15d5098ba0ee11c5126aa6",
        "userId": "58e22f662071c01c02f76a0f",
        "createdAt": "2017-09-26T10:55:15.990Z",
        "image": "",
        "datasets": [

        ],
        "use": {

        },
        "iso": {

        }
      }
    },
    {
      "type": "area",
      "id": "59ca32ea3209db0014e9a7b7",
      "attributes": {
        "name": "Test custom area",
        "application": "rw",
        "geostore": "b12640deba9d3c5012c5359dd5572e2d",
        "userId": "58e22f662071c01c02f76a0f",
        "createdAt": "2017-09-26T10:58:50.226Z",
        "image": "",
        "datasets": [

        ],
        "use": {

        },
        "iso": {

        }
      }
    }
  ]
}

Create area

Creates a new area

Parameters

Parameter Description Type Values Required
application Application Text Any Text, values separated by commas Yes
name Name of the new area Text Any Text Yes
geostore Geostore ID Text Any Text Yes
curl -X POST https://api.resourcewatch.org/v1/area \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": <name>,
   "application": <application>,
   "geostore": <geostore id>
 }'

Example

Create an area with name ‘Portugal area’ and Geostore ID '713899292fc118a915741728ef84a2a7’ for the Resource Watch application

curl -X POST https://api.resourcewatch.org/v1/area?application=rw \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
   "name": "Portugal area",
   "application": "rw",
   "geostore": "713899292fc118a915741728ef84a2a7"
 }'
{
  "data": {
    "type": "area",
    "id": "5a0da028e6d876001080c259",
    "attributes": {
      "name": "Portugal area",
      "application": "rw",
      "geostore": "713899292fc118a915741728ef84a2a7",
      "userId": "58e22f662071c01c02f76a0f",
      "createdAt": "2017-11-16T14:26:48.396Z",
      "image": "",
      "datasets": [

      ],
      "use": {

      },
      "iso": {

      }
    }
  }
}

Delete area

Deletes an area

curl -X DELETE https://api.resourcewatch.org/v1/area/<area-id> \
-H "Authorization: Bearer <your-token>" \

Example

curl -X POST https://api.resourcewatch.org/v1/area/59ca3213d08a7d001054522b \
-H "Authorization: Bearer <your-token>" \

Get area

Gets all the information from an area

curl -X GET https://api.resourcewatch.org/v1/area/<area-id> \
-H "Authorization: Bearer <your-token>" \

Example

curl -X GET https://api.resourcewatch.org/v1/area/59ca32ea3209db0014e9a7b7 \
-H "Authorization: Bearer <your-token>" \
{
    "data": {
        "type": "area",
        "id": "59ca32ea3209db0014e9a7b7",
        "attributes": {
            "name": "Test custom area",
            "application": "rw",
            "geostore": "b12640deba9d3c5012c5359dd5572e2d",
            "userId": "58e22f662071c01c02f76a0f",
            "createdAt": "2017-09-26T10:58:50.226Z",
            "image": "",
            "datasets": [],
            "use": {},
            "iso": {}
        }
    }
}

Areas v2

The following endpoints merge together areas of interest and subscriptions. This means they can be used to transition away from subscriptions without the users losing the subscriptions that they have already created.

Please ensure that you are using v2 in the URL when requesting these endpoints.

Getting all user areas

Example request to get all areas for the logged user:

curl -X GET https://api.resourcewatch.org/v2/area
-H "Authorization: Bearer <your-token>"

Example response:

{
    "data": [
        {
            "type": "area",
            "id": "5e4d74c3ef240412c2d56a71",
            "attributes": {
                "application": "gfw",
                "userId": "5e2f0eaf9de40a6c87dd9b7d",
                "createdAt": "2020-02-19T12:17:01.176Z",
                "datasets": [],
                "use": {},
                "iso": {},
                "admin": {},
                "tags": [],
                "status": "saved",
                "public": false,
                "fireAlerts": false,
                "deforestationAlerts": false,
                "webhookUrl": "",
                "monthlySummary": false,
                "subscriptionId": "5e4d273dce77c53768bc24f9",
                "email": "your.email@resourcewatch.org",
                "language": "en"
            }
        }
    ]
}

Example request to get ALL areas (only available for ADMIN users):

curl -X GET https://api.resourcewatch.org/v2/area?all=true
-H "Authorization: Bearer <your-token>"

Example response:

{
    "data": [
        {
            "type": "area",
            "id": "5e4d74c3ef240412c2d56a71",
            "attributes": {
                "application": "gfw",
                "userId": "5e2f0eaf9de40a6c87dd9b7d",
                "createdAt": "2020-02-19T12:17:01.176Z",
                "datasets": [],
                "use": {},
                "iso": {},
                "admin": {},
                "tags": [],
                "status": "saved",
                "public": false,
                "fireAlerts": false,
                "deforestationAlerts": false,
                "webhookUrl": "",
                "monthlySummary": false,
                "subscriptionId": "5e4d273dce77c53768bc24f9",
                "email": "your.email@resourcewatch.org",
                "language": "en"
            }
        }
    ],
    "links": {
        "self": "http://api.resourcewatch.org/v2/area?all=true&page[number]=1&page[size]=10",
        "first": "http://api.resourcewatch.org/v2/area?all=true&page[number]=1&page[size]=10",
        "last": "http://api.resourcewatch.org/v2/area?all=true&page[number]=1&page[size]=10",
        "prev": "http://api.resourcewatch.org/v2/area?all=true&page[number]=1&page[size]=10",
        "next": "http://api.resourcewatch.org/v2/area?all=true&page[number]=1&page[size]=10"
    },
    "meta": {
        "total-pages": 1,
        "total-items": 1,
        "size": 10
    }
}

Returns the list of areas for the user who made the request. This endpoint requires authentication.

This endpoint supports the following query parameters as filters:

Field Description Type Example
application Filter results by the application associated with the areas. String ‘gfw’
status Filter results by the status of the area. String 'saved’
public Filter results by the privacy status of the area. Boolean true
all Return all the areas instead of just the areas associated with user of the request. This filter will only be taken into account for ADMIN users. Boolean true
page[number] The number of the page to fetch. Only taken into account when using the all=true filter. Number 1
page[size] The size of the page to fetch. Only taken into account when using the all=true filter. Maximum value is 100. Number 10

Note: Due to performance and memory management issues, when the all=true filter is applied, the returned result is always paginated.

Implementation details

Finds all areas for the user who requested the list of areas. For each area, if it has an associated subscription (i.e. the subscriptionId field of the area is not empty), it merges the subscription data over the area data, returning it as a single object. After that, the remaining user subscriptions are converted to area objects and returned.

Note: if the all=true query filter is provided, then the /find-all endpoint of the subscriptions is used to find all existing subscriptions.

Getting a single user area

curl -X GET https://api.resourcewatch.org/v2/area/:id
-H "Authorization: Bearer <your-token>"

Example response:

{
    "data": {
        "type": "area",
        "id": "5e4d787bef240412c2d56a74",
        "attributes": {
            "application": "gfw",
            "userId": "5e2f0eaf9de40a6c87dd9b7d",
            "createdAt": "2020-02-19T12:17:01.176Z",
            "datasets": [],
            "use": {},
            "iso": {},
            "admin": {},
            "tags": [],
            "status": "saved",
            "public": false,
            "fireAlerts": false,
            "deforestationAlerts": false,
            "webhookUrl": "",
            "monthlySummary": false,
            "subscriptionId": "5e4d273dce77c53768bc24f9",
            "email": "tiago.garcia@vizzuality.com",
            "language": "en"
        }
    }
}

Returns the information for the area with the id provided. This endpoint requires authentication.

If the area has the public attribute set to false, you will only be able to fetch its information if you are the owner of the area. Otherwise, a 401 Unauthorized response will be returned.

If the area has the public attribute set to true and the user who requests it is not the owner, some information will be hidden for privacy reasons.

Implementation details

Try to find an area with the id provided:

  1. If the area exists:
    1. If the area has an associated subscription, the subscription is fetched, its data is merged over the area and the result is returned.
    2. If the area has no subscription associated, the area data is returned.
  2. If the area does not exist:
    1. Try to find a subscription with the id provided. If it exists, it is returned as an area object, if not, a 404 Not Found error is returned.

Creating an area

curl -X POST https://api.resourcewatch.org/v2/area
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json" -d \
 '{
    "name": "Example area",
    "application": "gfw",
    "image": "",
    "tags": [],
    "public": false,
    "fireAlerts": true,
    "deforestationAlerts": true,
    "webhookUrl": "http://example.com",
    "monthlySummary": true,
    "email": "youremail@resourcewatch.org",
    "language": "en"
}'

Example response:

{
    "data": {
        "type": "area",
        "id": "5e4d7c47ef240412c2d56a78",
        "attributes": {
            "name": "Example area",
            "application": "gfw",
            "wdpaid": null,
            "userId": "5e2f0eaf9de40a6c87dd9b7d",
            "createdAt": "2020-02-19T18:19:51.485Z",
            "image": "",
            "datasets": [],
            "tags": [],
            "status": "pending",
            "public": false,
            "fireAlerts": true,
            "deforestationAlerts": true,
            "webhookUrl": "http://example.com",
            "monthlySummary": true,
            "subscriptionId": "5e4d7c47dd8fa31290d548ae",
            "email": "youremail@resourcewatch.org",
            "language": "en"
        }
    }
}

Use this endpoint to create new areas. This endpoint requires authentication.

This endpoint supports the following request body parameters:

Field Description Type Example
name The name of the area being created. String 'Example’
image Image associated with the dataset - in GET areas, this attribute will have the URL for the image. String https://www.google.com/example.jpg
application The application to which this area is associated with. Defaults to 'gfw’. String 'gfw’
language The language of this area. Defaults to 'en’. String 'es’
geostore An ID of a geostore to which this area relates to. String '123’
public If the area is public or not. Defaults to false. Boolean true
fireAlerts If the area is intended to subscribe to fire alerts. Defaults to false. Boolean true
deforestationAlerts If the area is intended to subscribe to deforestation alerts. Defaults to false. Boolean true
monthlySummary If the area is intended to subscribe to monthly summaries. Defaults to false. Boolean true
email Email to be provided to the subscription. String youremail@resourcewatch.org
webhookUrl Webhook URL to be provided to the subscription (only used in case the email is not set). String https://www.google.com/
status The status of the area - either 'saved’ or 'pending’. Read-only attribute. String 'saved’
subscriptionId The ID of the subscription associated with this area. Read-only attribute. String 5e4d7c47dd8fa31290d548ae

Email notification

According to multiple factors (including the geostore that is associated with the area, if the area subscribes to fireAlerts, deforestationAlerts, etc.), there might be a period of time in which the data for the area is being generated. While that is the case, the area will have status set to 'pending'. Once the area data is ready, the status of the area will be updated to 'saved'.

After creating an area, if the email field of the area has a valid email, an email is sent to the user. The email content varies according to the status of the area:

Email substitution parameters

The following parameters are provided to the email service and can be used in the construction of the email:

(5d517b3fb8cfd4001061d0b2 is an example of an area ID).

Implementation details

POST of a new area always starts by creating the area and, taking into account the area attributes, it might also create a subscription which will then be associated with the area. The area’s subscriptionId attribute will then be updated with the id of the created subscription if that’s the case. The created area is then returned.

The subscription is created only if the area has selected set to true at least one of the following attributes:

Updating an area

curl -X PATCH https://api.resourcewatch.org/v2/area/:id
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json" -d \
 '{
    "name": "Example area",
    "application": "gfw",
    "image": "",
    "tags": [],
    "public": false,
    "fireAlerts": true,
    "deforestationAlerts": true,
    "webhookUrl": "http://example.com",
    "monthlySummary": true,
    "email": "youremail@resourcewatch.org",
    "language": "en"
}'

Example response:

{
    "data": {
        "type": "area",
        "id": "5e4d7c47ef240412c2d56a78",
        "attributes": {
            "name": "Example area",
            "application": "gfw",
            "wdpaid": null,
            "userId": "5e2f0eaf9de40a6c87dd9b7d",
            "createdAt": "2020-02-19T18:19:51.485Z",
            "image": "",
            "datasets": [],
            "tags": [],
            "status": "pending",
            "public": false,
            "fireAlerts": true,
            "deforestationAlerts": true,
            "webhookUrl": "http://example.com",
            "monthlySummary": true,
            "subscriptionId": "5e4d7c47dd8fa31290d548ae",
            "email": "youremail@resourcewatch.org",
            "language": "en"
        }
    }
}

Use this endpoint to update an existing area. This endpoint requires authentication and, in order to PATCH an area, you need to be either the owner of the area or be an ADMIN user.

This endpoint supports the following request body parameters:

Field Description Type Example
name The name of the area being created. String 'Example’
image Image associated with the dataset - in GET areas, this attribute will have the URL for the image. String https://www.google.com/example.jpg
application The application to which this area is associated with. Defaults to 'gfw’. String 'gfw’
language The language of this area. Defaults to 'en’. String 'es’
geostore An ID of a geostore to which this area relates to. String '123’
public If the area is public or not. Defaults to false. Boolean true
fireAlerts If the area is intended to subscribe to fire alerts. Defaults to false. Boolean true
deforestationAlerts If the area is intended to subscribe to deforestation alerts. Defaults to false. Boolean true
monthlySummary If the area is intended to subscribe to monthly summaries. Defaults to false. Boolean true
email Email to be provided to the subscription. String youremail@resourcewatch.org
webhookUrl Webhook URL to be provided to the subscription (only used in case the email is not set). String https://www.google.com/
status The status of the area - either 'saved’ or 'pending’. Read-only attribute. String 'saved’
subscriptionId The ID of the subscription associated with this area. Read-only attribute. String 5e4d7c47dd8fa31290d548ae

Email notification

According to multiple factors (including the geostore that is associated with the area, if the area subscribes to fireAlerts, deforestationAlerts, etc.), there might be a period of time in which the data for the area is being generated. While that is the case, the area will have status set to 'pending'. Once the area data is ready, the status of the area will be updated to 'saved'.

After updating an area, if it has status saved and if the email field of the area has a valid email, an email is sent to the user, to let him know the area of interest is ready to be viewed.

Email substitution parameters

The following parameters are provided to the email service and can be used in the construction of the email:

(5d517b3fb8cfd4001061d0b2 is an example of an area ID).

Implementation details

PATCHing an area is a bit more complex, and it comes down to 3 major cases:

  1. The area already exists and has subscriptions preference (deforestationAlerts, fireAlerts or monthlySummary set to true) in the request data:
    1. If the area doesn’t have a subscription associated, a new one is created and associated.
    2. If the area already had a subscription, then the subscription is PATCHed according to the data provided in the request body.
  2. The area already exists and doesn’t has subscription preferences (deforestationAlerts, fireAlerts or monthlySummary set to true) in the request data:
    1. If the area had a subscription associated, then the subscription associated is deleted.
    2. Otherwise, just save the area.
  3. The area doesn’t exist because on the fetch it returned a mapped subscription (meaning we are PATCHing an area using the ID of a subscription):
    1. First, create a new area, and then:
      1. If the request data has subscriptions preference (deforestationAlerts, fireAlerts or monthlySummary set to true), also PATCH the subscription.
      2. If the request data doesn’t have subscriptions preference (deforestationAlerts, fireAlerts or monthlySummary set to true), delete the associated subscription.

Deleting an area

curl -X DELETE https://api.resourcewatch.org/v2/area/:id
-H "Authorization: Bearer <your-token>" \

Returns 204 No Content in case of success.

Use this endpoint to delete an existing area. This endpoint requires authentication and, in order to DELETE an area, you need to be either the owner of the area or be an ADMIN user.

Implementation details

DELETing an area deletes the area if it exists, and then if an associated subscription exists, it is also deleted.

If the ID of a subscription is provided, then that subscription is deleted.

Update areas by geostore

curl -X POST https://api.resourcewatch.org/v2/area/update
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json" -d \
 '{
    "geostores": ["123", "234"],
    "update_params": {
        "status": "saved",
        "name": "Updated Area"
    }
}'

Example response:

{
    "data": [
        {
            "type": "area",
            "id": "5e4d74c3ef240412c2d56a71",
            "attributes": {
                "application": "gfw",
                "userId": "5e2f0eaf9de40a6c87dd9b7d",
                "createdAt": "2020-02-19T12:17:01.176Z",
                "datasets": [],
                "use": {},
                "iso": {},
                "admin": {},
                "tags": [],
                "status": "saved",
                "public": false,
                "fireAlerts": false,
                "deforestationAlerts": false,
                "webhookUrl": "",
                "monthlySummary": false,
                "subscriptionId": "5e4d273dce77c53768bc24f9",
                "email": "tiago.garcia@vizzuality.com",
                "language": "en"
            }
        }
    ]
}

Use this endpoint to batch update multiple areas that are associated with one of the geostore ids provided in the request body. In order to use this endpoint, you need to be authenticated as an ADMIN user.

You can use the update_params field of the request body to specify multiple fields to update on the areas that belong to the geostore ids provided in the body. Keep in mind that the same validations as when updating an area are applied. If a validation fails, the request will fail with 400 Bad Request and no area will be updated.

In case of success a 200 OK response is returned, and all the areas that match the update criteria (belonging to one of the geostores provided in the request body) will be returned.

After updating the areas, for each area that was updated (if it has a valid email associated), an email will be sent to the user to let them know that the area is ready to be viewed.

The following parameters are provided to the email service and can be used in the construction of the email:

Sync areas

curl -X POST https://api.resourcewatch.org/v2/area/sync
-H "Authorization: Bearer <your-token>" \

Example response:

{
    "data": {
        "syncedAreas": 8,
        "createdAreas": 0
    }
}

Example snippet that synchronizes the areas before fetching the information of ALL areas:

// First call the sync endpoint
await request.post('v2/area/sync');

// Then call the get endpoint while there are more pages to find
var results = [];
var hasNextPage = true;
var pageNumber = 1;
while (hasNextPage) {
   var res = await request.get('v2/area?all=true&page[number]=' + pageNumber);
   results = results.concat(res.data);
   pageNumber++;
   hasNextPage = res.links.self === res.links.last;
}

Use this endpoint to synchronize each area information with the associated subscription. The usage of this endpoint is recommended if you are performing update processes that rely on updated subscription information for the areas.

This endpoint supports the following query parameters to control the execution of the sync:

Field Description Type Example
startDate The date from which the sync will be executed. All subscriptions that have been updated since this date will be synced with the existing areas. String 2020-03-18T09:45:56.476Z
endDate The date until which the sync will be executed. All subscriptions that have been updated until this date will be synced with the existing areas. String 2020-03-25T09:45:56.476Z

Note: By default, the sync is done for the last week changes (i.e. the default value for the startDate parameter is one week ago and the default value for the endDate parameter is now).

Webshot

The webshot set of endpoints allows you to capture a given page as a document file, that can then be used, for example, as a preview thumbnail.

This service has two endpoints:

PDF

This endpoint expects a URL as a query parameter and generates a pdf containing a rendered version of that page:

curl -X GET \
  'http://api.resourcewatch.org/v1/webshot/pdf?url=http://google.com&filename=my-google-screenshoz.pdf' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Content-Type: application/json' \

The endpoint accepts the following optional parameters:

It is important to take into account that this endpoint works by rendering the https://resourcewatch.org/embed/widget/<widget id> URL with those dimensions applied to the viewport. So the resulting screenshot will have the proportional size of the corresponding DOM element within that viewport, and not the exact height and width specified.

Widget

This endpoint generates a thumbnail image for the provided widget and stores it on AWS S3.

curl -X POST \
  http://api.resourcewatch.org/v1/webshot/widget/7b540186-9a9f-4e13-a6e8-f38e64fab2e1/thumbnail \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Content-Type: application/json' \
{
    "data": {
        "widgetThumbnail": "http://s3.amazonaws.com/resourcewatch/thumbnails/<filename>.png"
    }
}

This endpoint accepts two optional query parameters, height and width, that configure the size of the generated screenshot. Keep in mind that this endpoint works by rendering the https://resourcewatch.org/embed/widget/<widget id> URL with those dimensions applied to the viewport, and then captures the content of the .widget-content DOM element into an image file. As such, the resulting screenshot will have the proportional size of the corresponding DOM element within that viewport, and not the exact height and width specified.

Topic

What is a Topic?

A topic contains the information to display a web page belonging to a user.

Getting all topics

This endpoint will allow to get all topics belonging to a user:

curl -X GET https://api.resourcewatch.org/v1/topic -H 'Authorization: Bearer exampleToken'

Response:

{
    "data": [
        {
            "id": "10",
            "type": "topics",
            "attributes": {
                "name": "Cities topic",
                "slug": "cities-topic",
                "summary": "",
                "description": "",
                "content": "<p></p>\n<iframe width=\"500\" height=\"410\" src=\"/embed/widget/5ebeddda-8f3d-4e63-8a52-08e15c3e148c\" frameBorder=\"0\"></iframe>\n<p></p>\n<iframe width=\"500\" height=\"410\" src=\"/embed/widget/73c574b9-f9ab-4f77-87be-651ff8dac5fe\" frameBorder=\"0\"></iframe>\n<p>test1</p>\n",
                "published": true,
                "photo": {
                    "cover": "https://s3.amazonaws.com/image.jpg",
                    "thumb": "https://s3.amazonaws.com/image.jpg",
                    "original": "https://s3.amazonaws.com/image.jpg"
                },
                "user-id": "eb63867922e16e34ef3ce862",
                "private": true,
                "application":  ["rw"]
            }
        },
        ...
      ]
}

Filters

Available filters parameters:

Field Description Type
published Filter topics by publishing status (true, false) Boolean
private Filter topics by private status (true, false) Boolean
user Filter topics by author user id Text
application The application to which the topic belongs Text (single value)
curl -X GET https://api.resourcewatch.org/v1/topic?user=57bc2608f098ce98007985e4&private=false
# Deprecated syntax
curl -X GET https://api.resourcewatch.org/v1/topic?filter[user]=57bc2608f098ce98007985e4&filter[private]=false

Sorting

There’s currently no support for custom sorting of topics. The topics are listed on a pseudo-random order.

When loading topics, you can optionally pass an includes query argument to load additional data.

User

Loads the name and email address of the author of the topic. If you request this issue as an authenticated user with ADMIN role, you will additionally get the author’s role.

If the data is not available (for example, the user has since been deleted), no user property will be added to the layer object.

curl -X GET https://api.resourcewatch.org/v1/topic?includes=user

Example response:

{
    "data": [
      {
        "id": "86",
        "type": "topics",
        "attributes": {
          "name": "Test topic three",
          "slug": "test-topic-three-cd4305e9-e3c8-456b-85a0-32eccb6100e6",
          "summary": "test topic three summary",
          "description": "test topic three description",
          "content": "test topic three description",
          "published": true,
          "user-id": "57ac9f9e29309063404573a2",
          "application":  ["rw"],
          "user": {
            "name": "John Doe",
            "role": "ADMIN",
            "email": "john.doe@vizzuality.com"
          }
        }
      }
   ]
}

Creating a topic

When creating a topic, the application field should be present and cannot contain any values that are not associated with the creating user’s account. If an application value is not provided, ["rw"] is used by default, and the process will fail if the user account does not belong to it. Any role can create a topic.

Supported fields:

Name Description Accepted values
name Short name for the topic any valid text
slug Unique identifier for the topic any valid text
summary Summary of the content of the topic any valid text
description Description of the topic any valid text
content Content of the topic, typically encoded as a JSON string any valid text
published If the topic is in a publishable state boolean
photo Object containing a set of image urls associated with the topic object
user_id Id of the user who created the topic string with valid user id (not validated)
private boolean
application Application(s) to which the topic belongs. Defaults to ["rw"]. array of strings
curl -X POST https://api.resourcewatch.org/v1/topics \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
      "data": {
          "type": "topics",
          "attributes": {
              "name": "Cities",
              "summary": "Traditional models of city development can lock us into congestion, sprawl, and inefficient resource use. However, compact, ...",
              "description": "",
              "content": "[{...}]",
              "published": false,
              "photo": {
                  "cover": "...",
                  "thumb": "...",
                  "original": "..."
              },
              "user-id": "eb63867922e16e34ef3ce862",
              "private": true,
              "application":  ["rw"]
          }
      }
  }'
{
    "data": {
        "id": "243",
        "type": "topics",
        "attributes": {
            "name": "Cities",
            "slug": "cities-94bbc472-8970-4d9e-a3f2-d5422b1011e0",
            "summary": "Traditional models of city development can lock us into congestion, sprawl, and inefficient resource use. However, compact, ...",
            "description": "",
            "content": "[{...}]",
            "published": false,
            "photo": {
                "cover": "...",
                "thumb": "...",
                "original": "..."
            },
            "user-id": "eb63867922e16e34ef3ce862",
            "private": true,
            "user": null,
            "application":  ["rw"]
        }
    }
}

Editing a topic

In order to perform this operation, the following conditions must be met:

When updating the application field of a topic, a user cannot add values not associated with their user account.

curl -X PATCH https://api.resourcewatch.org/v1/topics/<id of the topic> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
      "data": {
          "attributes": {
              "description": "Topic related with cities."
          }
      }
  }'
{
    "data": {
        "id": "243",
        "type": "topics",
        "attributes": {
            "name": "Cities",
            "slug": "cities-94bbc472-8970-4d9e-a3f2-d5422b1011e0",
            "summary": "Traditional models of city development can lock us into congestion, sprawl, and inefficient resource use. However, compact, ...",
            "description": "Topic related with cities.",
            "content": "[{...}]",
            "published": false,
            "photo": {
                "cover": "...",
                "thumb": "...",
                "original": "..."
            },
            "user-id": "eb63867922e16e34ef3ce862",
            "private": true,
            "user": null,
            "application":  ["rw"]
        }
    }
}

Clone a topic

Clones an existing topic using its ID. If the original topic contains functioning widgets, they will be duplicated and the new ids will be used by the new topic.

curl -X POST https://api.resourcewatch.org/v1/topics/10/clone -H 'Authorization: Bearer exampleToken'
{
    "data": {
        "id": "224",
        "type": "topics",
        "attributes": {
            "name": "Cities",
            "slug": "cities-a9cb2c87-f6b6-48cf-9b52-9e0de4fd8d6f",
            "summary": "Traditional models of city development can lock us into congestion, sprawl, and inefficient resource use. However, compact, ...",
            "description": "",
            "content": "[{\"id\":1511952250652,\"type\":\"widget\",\"content\":{\"widgetId\":\"b9186ce9-78ae-418b-a6d3-d521283ce485\",\"categories\":[]}},...}]",
            "published": false,
            "photo": {
                "cover": "/system/topics/photos/data?1523301918",
                "thumb": "/system/topics/photos/data?1523301918",
                "original": "/system/topics/photos/data?1523301918"
            },
            "user-id": "eb63867922e16e34ef3ce862",
            "private": true,
            "application":  ["rw"]
        }
    }
}

Dashboard

What is a dashboard

A dashboard contains the information to display a web page belonging to a user.

Getting all dashboards

This endpoint will allow to get all dashboards belonging to a user:

curl -X GET https://api.resourcewatch.org/v1/dashboard -H 'Authorization: Bearer <your-token>'

Example response:

{
    "data": [
        {
            "id": "10",
            "type": "dashboards",
            "attributes": {
                "name": "Cities Dashboard",
                "slug": "cities-dashboard",
                "summary": "",
                "description": "",
                "content": "<p></p>\n<iframe width=\"500\" height=\"410\" src=\"/embed/widget/5ebeddda-8f3d-4e63-8a52-08e15c3e148c\" frameBorder=\"0\"></iframe>\n<p></p>\n<iframe width=\"500\" height=\"410\" src=\"/embed/widget/73c574b9-f9ab-4f77-87be-651ff8dac5fe\" frameBorder=\"0\"></iframe>\n<p>test1</p>\n",
                "published": true,
                "photo": {
                    "cover": "https://s3.amazonaws.com/image.jpg",
                    "thumb": "https://s3.amazonaws.com/image.jpg",
                    "original": "https://s3.amazonaws.com/image.jpg"
                },
                "user-id": "eb63867922e16e34ef3ce862",
                "private": true,
                "production": true,
                "preproduction": false,
                "staging": false,
                "application":  ["rw"],
                "is-highlighted": false,
                "is-featured": false,
                "author-title": "",
                "author-image": {
                    "cover": "/author_images/cover/missing.png",
                    "thumb": "/author_images/thumb/missing.png",
                    "original": "/author_images/original/missing.png"
                }
            }
        }
    ],
    "links": {
        "self": "http://staging-api.globalforestwatch.org/v1/dashboard?page%5Bnumber%5D=1&page%5Bsize%5D=10",
        "first": "http://staging-api.globalforestwatch.org/v1/dashboard?page%5Bnumber%5D=1&page%5Bsize%5D=10",
        "prev": null,
        "next": "http://staging-api.globalforestwatch.org/v1/dashboard?page%5Bnumber%5D=2&page%5Bsize%5D=10",
        "last": "http://staging-api.globalforestwatch.org/v1/dashboard?page%5Bnumber%5D=14&page%5Bsize%5D=10"
    },
    "meta": {
        "total-pages": 14,
        "total-items": 140,
        "size": 10
    }
}

Filters

Example request using query string filters:

curl -X GET https://api.resourcewatch.org/v1/dashboard?name=text&private=false

Deprecated filter syntax:

curl -X GET https://api.resourcewatch.org/v1/dashboard?filter[name]=text&filter[private]=false

Available filters parameters:

Field Description Type
name Filter dashboards by name (partial matches and case-insensitive supported). Text
published Filter dashboards by publishing status (true, false). Boolean
private Filter dashboards by private status (true, false). Boolean
user Filter dashboards by author user id. Text
user.role The role of the user who created the dashboard. If the requesting user does not have the ADMIN role, this filter is ignored. ADMIN, MANAGER or USER
application The application to which the dashboard belongs. Text (single value)
is-highlighted Filter dashboards by highlighted ones (true,false). Boolean
is-featured Filter dashboards by featured ones (true,false). Boolean
author-title Filter dashboards by the title of the author of the dashboard. Text

Deprecation notice: The format filter[filterName]=value which was previously supported for some filters, is now deprecated, in favor of filterName=value.

Pagination

Example request using query string parameters for paging the result:

curl -X GET https://api.resourcewatch.org/v1/dashboard?page[size]=15&page[number]=2
Field Description Type Default value
page[size] The number elements per page. The maximum allowed value is 100 Number 10
page[number] The page number Number 1

Sorting

Sorting dashboards

curl -X GET https://api.resourcewatch.org/v1/dashboard?sort=name

Sorting dashboards by multiple criteria

curl -X GET https://api.resourcewatch.org/v1/dashboard?sort=name,slug

Explicit order of sorting

curl -X GET https://api.resourcewatch.org/v1/dashboard?sort=-name,+slug

Sorting dashboards by the role of the user who owns the dashboard

curl -X GET https://api.resourcewatch.org/v1/dashboard?sort=user.role

Multiple sorting criteria can be used, separating them by commas.

You can specify the sorting order by prepending the criteria with either - or +. By default, asc order is assumed.

The API currently supports sorting by means of the sort parameter. Sorting can be done using any field from the dashboard, as well as user.name and user.role (sorting by user data is restricted to ADMIN users).

Sorting by nested fields is not supported at the moment.

When loading dashboards, you can optionally pass an includes query argument to load additional data.

User

Example request including the information for the user who owns the dashboard:

curl -X GET https://api.resourcewatch.org/v1/dashboard?includes=user

Example response:

{
    "data": [
      {
        "id": "86",
        "type": "dashboards",
        "attributes": {
          "name": "Test dashboard three",
          "slug": "test-dashboard-three-cd4305e9-e3c8-456b-85a0-32eccb6100e6",
          "summary": "test dashboard three summary",
          "description": "test dashboard three description",
          "content": "test dashboard three description",
          "published": true,
          "photo": {
            "cover": "https://s3.amazonaws.com/image.jpg",
            "thumb": "https://s3.amazonaws.com/image.jpg",
            "original": "https://s3.amazonaws.com/image.jpg"
          },
          "user-id": "57ac9f9e29309063404573a2",
          "private": true,
          "production": true,
          "preproduction": false,
          "staging": false,
          "application":  ["rw"],
          "is-highlighted": false,
          "is-featured": false,
          "author-title": "",
          "author-image": {
            "cover": "/author_images/cover/missing.png",
            "thumb": "/author_images/thumb/missing.png",
            "original": "/author_images/original/missing.png"
          },
          "user": {
            "name": "John Doe",
            "role": "ADMIN",
            "email": "john.doe@vizzuality.com"
          }
        }
      }
   ]
}

Loads the name and email address of the owner of the dashboard. If you request this issue as an authenticated user with ADMIN role, you will additionally get the owner’s role.

If the data is not available (for example, the user has since been deleted), no user property will be added to the layer object.

Getting a dashboard by its ID

How to get a dashboard by its ID:

curl -X GET http://api.resourcewatch.org/dashboard/24

Response:

{
  "data": {
    "id": "24",
    "type": "dashboards",
    "attributes": {
      "name": "Cities",
      "slug": "cities",
      "summary": "Traditional models of city development can lock us into congestion, sprawl, and inefficient resource use. However, compact, connected, and efficient growth can help ensure more competitive cities, and provide a better quality of life for citizens.  The decisions that national leaders, local officials, developers, and planners make today will determine how billions of urban cities will live over the next century. Already, half the global population resides in cities. That figure is set to increase to 70 percent by 2050.",
      "description": "",
      "content": "[]",
      "published": false,
      "photo": {
        "cover": "https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/dashboards/photos/000/000/024/cover/data?1523301918",
        "thumb": "https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/dashboards/photos/000/000/024/thumb/data?1523301918",
        "original": "https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/dashboards/photos/000/000/024/original/data?1523301918"
      },
      "user-id": "58f63c81bd32c60206ed6b12",
      "private": true,
      "production": true,
      "preproduction": false,
      "staging": false,
      "user": null,
      "is-highlighted": false,
      "is-featured": false,
      "author-title": "",
      "author-image": {
        "cover": "/author_images/cover/missing.png",
        "thumb": "/author_images/thumb/missing.png",
        "original": "/author_images/original/missing.png"
      }
    }
  }
}

Creating a dashboard

Example request for creating a dashboard:

curl -X POST https://api.resourcewatch.org/v1/dashboard \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
      "data": {
          "type": "dashboards",
          "attributes": {
              "name": "Cities",
              "summary": "Traditional models of city development can lock us into ...",
              "description": "",
              "content": "[{...}]",
              "published": false,
              "photo": {
                  "cover": "...",
                  "thumb": "...",
                  "original": "..."
              },
              "private": true,
              "production": true,
              "preproduction": false,
              "staging": false,
              "application":  ["rw"],
              "is-highlighted": false,
              "is-featured": false,
              "author-title": "",
              "author-image": @file
          }
      }
  }'

Example response:

{
    "data": {
        "id": "243",
        "type": "dashboards",
        "attributes": {
            "name": "Cities",
            "slug": "cities-94bbc472-8970-4d9e-a3f2-d5422b1011e0",
            "summary": "Traditional models of city development can lock us into ...",
            "description": "",
            "content": "[{...}]",
            "published": false,
            "photo": {
                "cover": "...",
                "thumb": "...",
                "original": "..."
            },
            "user-id": "eb63867922e16e34ef3ce862",
            "private": true,
            "production": true,
            "preproduction": false,
            "staging": false,
            "user": null,
            "application":  ["rw"],
            "is-highlighted": false,
            "is-featured": false,
            "author-title": "",
            "author-image": {
                "cover": "...",
                "thumb": "...",
                "original": "..."
            }
        }
    }
}

When creating a dashboard, the application field should be present and cannot contain any values that are not associated with the creating user’s account. If an application value is not provided, ["rw"] is used by default, and the process will fail if the user account does not belong to it. Any role can create a dashboard.

Supported fields:

Name Description Accepted values
name Short name for the dashboard any valid text
summary Summary of the content of the dashboard any valid text
description Description of the dashboard any valid text
content Content of the dashboard, typically encoded as a JSON string any valid text
published If the dashboard is in a publishable state boolean
photo Object containing a set of image urls associated with the dashboard object
private If the dashboard is private or publicly available. boolean
production If the dashboard is available in the production environment. boolean
preproduction If the dashboard is available in the preproduction environment. boolean
staging If the dashboard is available in the staging environment. boolean
application Application(s) to which the dashboard belongs. Defaults to ["rw"]. array of strings
is-highlighted If this dashboard is highlighted (true/false). Defaults to false. Only accessible to users with ADMIN role. boolean
is-featured If this dashboard is featured (true/false). Defaults to false. Can only be set by user with ADMIN role. boolean
author-title The title of the author of the dashboard. any valid text
author-image File for the image of the author of the dashboard. valid image file (jpg, jpeg, png)

Editing a dashboard

Example request for updating a dashboard:

curl -X PATCH https://api.resourcewatch.org/v1/dashboard/<id of the dashboard> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
      "data": {
          "attributes": {
              "description": "Dashboard that uses cities"
          }
      }
  }'

Example response:

{
    "data": {
        "id": "243",
        "type": "dashboards",
        "attributes": {
            "name": "Cities",
            "slug": "cities-94bbc472-8970-4d9e-a3f2-d5422b1011e0",
            "summary": "Traditional models of city development can lock us ...",
            "description": "Dashboard that uses cities",
            "content": "[{...}]",
            "published": false,
            "photo": {
                "cover": "...",
                "thumb": "...",
                "original": "..."
            },
            "user-id": "eb63867922e16e34ef3ce862",
            "private": true,
            "production": true,
            "preproduction": false,
            "staging": false,
            "user": null,
            "application": ["rw"],
            "is-highlighted": false,
            "is-featured": false,
            "author-title": "",
            "author-image": {
                "cover": "...",
                "thumb": "...",
                "original": "..."
            }
        }
    }
}

In order to perform this operation, the following conditions must be met:

When updating the application field of a dashboard, a user cannot add values not associated with their user account.

Delete dashboard

Example request for deleting a dashboard:

curl -X DELETE https://api.resourcewatch.org/v1/dashboard/<id of the dashboard> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"

In order to perform this operation, the following conditions must be met:

Clone dashboard

Example request for cloning a dashboard:

curl -X POST https://api.resourcewatch.org/v1/dashboard/<id>/clone \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"  -d \
 '{
    "data": {
        "attributes": {
            "name": "Copy of Cities dashboard",
        }
    }
  }'

Example response:

{
    "data": {
        "id": "224",
        "type": "dashboards",
        "attributes": {
            "name": "Copy of Cities dashboard",
            "slug": "cities-a9cb2c87-f6b6-48cf-9b52-9e0de4fd8d6f",
            "summary": "Traditional models of city development can lock us into congestion, sprawl, and inefficient resource use. However, compact, ...",
            "description": "",
            "content": "[{\"id\":1511952250652,\"type\":\"widget\",\"content\":{\"widgetId\":\"b9186ce9-78ae-418b-a6d3-d521283ce485\",\"categories\":[]}},...}]",
            "published": false,
            "photo": {
                "cover": "/system/dashboards/photos/data?1523301918",
                "thumb": "/system/dashboards/photos/data?1523301918",
                "original": "/system/dashboards/photos/data?1523301918"
            },
            "user-id": "1111167922e16e34ef3ce872",
            "private": true,
            "production": true,
            "preproduction": false,
            "staging": false,
            "application":  ["rw"],
            "is-highlighted": false,
            "is-featured": false,
            "author-title": "",
            "author-image": {
                "cover": "/author_images/cover/missing.png",
                "thumb": "/author_images/thumb/missing.png",
                "original": "/author_images/original/missing.png"
            }
        }
    }
}

Clones an existing dashboard using its ID. If the original dashboard contains widgets, they will be duplicated and the new ids will be used by the new dashboard. Data can be provided in the body of the request in order to overwrite the data of the original dashboard. In the example on the side, the name of the dashboard will be overwritten.

The following attributes can be overwritten by providing new values in the request body:

Tasks

What is a task?

In the context of this API, a task is a process in charge of performing certain actions on datasets of the document type. These actions can be creating a dataset or overwriting its content.

A task may contains the following fields:

Field Description Type
id Id of the task Text
type Task type - see full list here Text
message Task message, which parametrizes the task Object
status Status of the task - see full list here Text
reads Number of data reads performed by the task Number
writes Number of data writes performed by the task Number
index Name of the Elasticsearch index used in this task Text
datasetId Id of the dataset to which this task relates Text
logs List of the individual operations carried out by this task Array
error Error message generated should the task fail Text
createdAt Date and time in which the task was created DateTime
updatedAt Date and time in which the task was last updated DateTime

A task is fundamentally an internal element to the API, and it’s visibility and interaction is limited to maintenance and debug actions. At its core, a task represents a single package that contains:

Get all tasks

To obtain all tasks:

curl -X GET https://api.resourcewatch.org/v1/doc-importer/task

Example response:

{
    "data": [
        {
            "id": "55b02cfd-dabf-4ad0-a04d-5501cf248a0c",
            "type": "task",
            "attributes": {
                "type": "TASK_CREATE",
                "message": {
                    "id": "55b02cfd-dabf-4ad0-a04d-5501cf248a0c",
                    "type": "TASK_CREATE",
                    "datasetId": "65593fee-26e0-4c3c-84b3-cc0921bf8bc1",
                    "fileUrl": "http://gfw2-data.s3.amazonaws.com/country-pages/fire_alerts_all.csv",
                    "provider": "csv",
                    "legend": {
                        "date": [],
                        "region": [],
                        "country": [],
                        "nested": []
                    },
                    "verified": false,
                    "dataPath": "rows"
                },
                "status": "SAVED",
                "reads": 973,
                "writes": 973,
                "createdAt": "2019-02-20T07:39:31.295Z",
                "updatedAt": "2019-02-20T10:10:07.147Z",
                "index": "index_65593fee26e04c3c84b3cc0921bf8bc1_1550648371365",
                "datasetId": "65593fee-26e0-4c3c-84b3-cc0921bf8bc1",
                "logs": [
                    {
                        "id": "a67f2557-9237-4435-82fd-3a0ad64b0292",
                        "type": "STATUS_INDEX_CREATED",
                        "taskId": "55b02cfd-dabf-4ad0-a04d-5501cf248a0c",
                        "index": "index_65593fee26e04c3c84b3cc0921bf8bc1_1550648371365"
                    },
                    {
                        "id": "53ac8e83-167b-4c77-9b61-6642b1764b32",
                        "type": "STATUS_READ_DATA",
                        "taskId": "55b02cfd-dabf-4ad0-a04d-5501cf248a0c"
                    }
                ]
            }
        },
        {

            "id": "415ecb4e-ed9a-4b0f-9f8b-7755775b08f5",
            "type": "task",
            "attributes": {
                "type": "TASK_CREATE",
                "message": {
                    "id": "415ecb4e-ed9a-4b0f-9f8b-7755775b08f5",
                    "type": "TASK_CREATE",
                    "datasetId": "638cce8c-3e97-4bdd-b4de-41cd28254370",
                    "fileUrl": "http://gfw2-data.s3.amazonaws.com/country-pages/fire_alerts_all.csv",
                    "provider": "csv",
                    "legend": {
                        "date": [],
                        "region": [],
                        "country": [],
                        "nested": []
                    },
                    "verified": false,
                    "dataPath": "rows"
                },
                "status": "SAVED",
                "reads": 973,
                "writes": 973,
                "createdAt": "2019-02-20T07:39:36.421Z",
                "updatedAt": "2019-02-20T10:10:09.175Z",
                "index": "index_638cce8c3e974bddb4de41cd28254370_1550652900017",
                "datasetId": "638cce8c-3e97-4bdd-b4de-41cd28254370",
                "logs": [
                    {
                        "id": "8f5b6b0c-9132-4b5c-b7c4-b58582b3cb0b",
                        "type": "STATUS_INDEX_CREATED",
                        "taskId": "415ecb4e-ed9a-4b0f-9f8b-7755775b08f5",
                        "index": "index_638cce8c3e974bddb4de41cd28254370_1550652900017"
                    },
                    {
                        "id": "63c69b2b-31cd-4bdb-9794-f6d4ec155e7b",
                        "type": "STATUS_READ_DATA",
                        "taskId": "415ecb4e-ed9a-4b0f-9f8b-7755775b08f5"
                    }
                ]
            }
        }
    ],
    "links": {
        "self": "https://api.resourcewatch.org/v1/doc-importer/task?page[number]=1&page[size]=10",
        "first": "https://api.resourcewatch.org/v1/doc-importer/task?page[number]=1&page[size]=10",
        "last": "https://api.resourcewatch.org/v1/doc-importer/task?page[number]=23&page[size]=10",
        "prev": "https://api.resourcewatch.org/v1/doc-importer/task?page[number]=1&page[size]=10",
        "next": "https://api.resourcewatch.org/v1/doc-importer/task?page[number]=2&page[size]=10"
    },
    "meta": {
        "total-pages": 23,
        "total-items": 227,
        "size": 10
    }
}

Pagination

Field Description Type Default value
page[size] The number elements per page. The maximum allowed value is 100 Number 10
page[number] The page number Number 1

Filter params

Available filters:

Field Description Type
type Task type Text
status Task status Text
datasetID Id of the dataset to which the task refers Text
createdAt Tasks created on the given date Date
updatedAt Tasks last updated on the given date Date
createdBefore Tasks created before the given date Date
createdAfter Tasks created after the given date Date
updatedBefore Tasks last updated before the given date Date
updatedAfter Tasks last updated after the given date Date

Return tasks with type TASK_OVERWRITE

curl -X GET https://api.resourcewatch.org/v1/doc-importer/task?type=TASK_OVERWRITE

Return the tasks with status SAVED

curl -X GET https://api.resourcewatch.org/v1/doc-importer/task?status=SAVED

Return the tasks created on Feb 1st 2019

curl -X GET https://api.resourcewatch.org/v1/doc-importer/task?createdAt=2019-02-01

Return the tasks last updated between Jan 2nd and Feb 2nd 2019

curl -X GET https://api.resourcewatch.org/v1/doc-importer/task?updatedAfter=2019-01-02&updatedBefore=2019-02-02

Return the tasks last updated before and Feb 2nd 2019 and with status ERROR

curl -X GET https://api.resourcewatch.org/v1/doc-importer/task?updatedBefore=2019-02-02&status=ERROR

Get a single task

To obtain the task:

curl -X GET https://api.resourcewatch.org/v1/doc-importer/task/55b02cfd-dabf-4ad0-a04d-5501cf248a0c

Example response:

{
    "data": {
        "id": "55b02cfd-dabf-4ad0-a04d-5501cf248a0c",
        "type": "task",
        "attributes": {
            "type": "TASK_CREATE",
            "message": {
                "id": "55b02cfd-dabf-4ad0-a04d-5501cf248a0c",
                "type": "TASK_CREATE",
                "datasetId": "65593fee-26e0-4c3c-84b3-cc0921bf8bc1",
                "fileUrl": "http://gfw2-data.s3.amazonaws.com/country-pages/fire_alerts_all.csv",
                "provider": "csv",
                "legend": {
                    "date": [],
                    "region": [],
                    "country": [],
                    "nested": []
                },
                "verified": false,
                "dataPath": "rows"
            },
            "status": "SAVED",
            "reads": 973,
            "writes": 973,
            "createdAt": "2019-02-20T07:39:31.295Z",
            "updatedAt": "2019-02-20T10:10:07.147Z",
            "index": "index_65593fee26e04c3c84b3cc0921bf8bc1_1550648371365",
            "datasetId": "65593fee-26e0-4c3c-84b3-cc0921bf8bc1",
            "logs": [
                {
                    "id": "a67f2557-9237-4435-82fd-3a0ad64b0292",
                    "type": "STATUS_INDEX_CREATED",
                    "taskId": "55b02cfd-dabf-4ad0-a04d-5501cf248a0c",
                    "index": "index_65593fee26e04c3c84b3cc0921bf8bc1_1550648371365"
                },
                {
                    "id": "53ac8e83-167b-4c77-9b61-6642b1764b32",
                    "type": "STATUS_READ_DATA",
                    "taskId": "55b02cfd-dabf-4ad0-a04d-5501cf248a0c"
                }
            ]
        }
    }
}

Delete a task

You can delete a task if, for example, it is stuck on a running state, but it’s not actually running. This should be considered a “only do it if you know what you are doing” operation, and requires ADMIN permission.

curl -X DELETE https://api.resourcewatch.org/v1/doc-importer/task/<task_id> \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json"

User Management

The following endpoints expose the API’s functionality regarding user management. For more information or implementation details, see the source code.

A note on UI elements

Unlike the other parts of the API, this section covers endpoints that provide end-user interaction, rendering HTML pages or sending emails to reset passwords and such. Some elements of these interfaces can be configured to match specific projects identities (RW, GFW, etc). To specify which project your requests come from, you can add an optional origin query parameter to your requests, with the name of the application. If matching visual elements exist, they will be used in the resulting interfaces displayed to the user.

Login (email + password)

Login endpoints support both HTML and JSON output formats, depending on the Content-type provided in the request. Keep in mind that HTML-based requests will result in redirects - for example, after successfully logging in, you will be taken to /auth/success - while JSON based requests will simply return the matching HTTP code - 200 in case of a successful login.

GET <BASE API URL>/auth/

Convenience URL that redirects to <BASE API URL>/auth/login

GET <BASE API URL>/auth/login

Basic API auth login page. Only supported for HTML requests.

POST <BASE API URL>/auth/login

Endpoint for email + password based login.

For HTML requests, it will redirect to either <BASE API URL>/auth/success or <BASE API URL>/auth/fail depending on whether the login was successful or not. An optional callbackUrl query parameter can be provided, in which case the user will be redirected to that URL in case of login success.

For JSON requests, it will return 200 or 401 HTTP response code depending on whether the login was successful or not. In case of successful logins, the basic user details will be returned as a JSON object.

# Email + password based login - JSON format
curl -X POST http://api.resourcewatch.org/auth/login \
-H "Content-Type: application/json"  -d \
 '{
    "email":"your-email@provider.com",
    "password":"potato"
}'
// Response:
{
  "data": {
    "email": "your-email@provider.com",
    "createdAt": "2018-11-15T04:46:35.313Z",
    "role": "USER",
    "extraUserData": {
      "apps": [
        "rw"
      ]
    },
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjViZWNmYTJiNjdkYTBkM2VjMDdhMjdmNiIsInJvbGUiOiJVU0VSIiwicHJvdmlkZXIiOiJsb2NhbCIsImVtYWlsIjoidGVzdEBleGFtcGxlLmNvbSIsImV4dHJhVXNlckRhdGEiOnsiYXBwcyI6WyJydyJdfSwiY3JlYXRlZEF0IjoxNTQzMzE1NzMxNzcwLCJpYXQiOjE1NDMzMTU3MzF9.kIdkSOb7mCMOxE2ipqVOBrK7IefAjLDhaPG9DT1qvCw"
  }
}

GET <BASE API URL>/auth/fail

Displays login errors for HTML requests. Not supported on JSON requests.

GET <BASE API URL>/auth/check-logged

Check login status

GET <BASE API URL>/auth/success

Successful login page for HTML requests. Not supported on JSON requests.

GET <BASE API URL>/auth/logout

Login invalidation endpoint

GET <BASE API URL>/auth/generate-token

Generates a JWT token for the current user session.

Login (3rd party oauth)

Registration

Registration endpoints support both HTML and JSON output formats, depending on the Content-type provided in the request.

View the registration page

Account creation page, for accounts using email + password based login for HTML requests. Not supported on JSON requests.

curl -X GET http://api.resourcewatch.org/auth/sign-up

Register a new user account

Account creation endpoint, for accounts using email + password based login for both HTML and JSON requests.

The combination of both user email and provider must be unique - a given email address may be associated with multiple, non-related user accounts by using different authentication providers (email+password, facebook, twitter, etc).

For HTML requests, it will display a message informing about any validation error, or informing the user in case of success.

For JSON requests, it will return 200 or 422 HTTP response code depending on whether the login was successful or not. In case of successful logins, the basic user details will be returned as a JSON object. In case of failure, an array of errors is returned.

In both types of requests, on success, an email will be sent to the user, with a link to confirm the account. The email will have the identity of the origin app provided on the request, with a system-wide fallback (GFW) being used in case none is provided.

While optional, it’s highly recommended that you specify which apps the user will be granted access to, as most API operation validate the user’s apps match datasets, widgets, etc.

Account creation using email + password

curl -X POST http://api.resourcewatch.org/auth/sign-up \
-H "Content-Type: application/json"  -d \
 '{
    "email":"your-email@provider.com",
    "password":"potato",
    "repeatPassword":"potato",
    "apps": ["rw"]
}'

Response

{
  "data": {
    "id": "5bfd237767b3176dd63f2eb7",
    "email": "your-email@provider.com",
    "createdAt": "2018-11-27T10:59:03.531Z",
    "role": "USER",
    "extraUserData": {
      "apps": ["rw"]
    }
  }
}

Account creation using email + password with a user defined origin app

curl -X POST http://api.resourcewatch.org/auth/sign-up?origin=rw \
-H "Content-Type: application/json"  -d \
 '{
    "email":"your-email@provider.com",
    "password":"potato",
    "repeatPassword":"potato",
    "apps": ["rw"]
}'

Permissions

Based on roles, different types of users can create new users with different roles:

Confirm user account

Endpoint used in the user validation email to confirm the address upon registration.

It accepts an optional callbackUrl query parameter with an URL to which the user will be redirect if the confirmation succeeds.

Should no callbackUrl be provided, the user is redirected to an URL based on the first application associated to their user account - see ct-oauth-plugin configuration for more info.

Should that application have no configured redirect URL, or the user have no configured app, they are redirect to a platform-wide default URL - see ct-oauth-plugin configuration for more info.

JSON Request:

curl -X GET http://api.resourcewatch.org/auth/confirm/:token \
-H "Content-Type: application/json"

JSON Response:

{
    "data": {
        "id": "5dbadc495eae7358322dd64b",
        "email": "info@vizzuality.com",
        "createdAt": "2019-10-31T13:06:17.676Z",
        "updatedAt": "2019-10-31T13:06:17.676Z",
        "role": "USER",
        "extraUserData": {
            "apps": []
        }
    }
}

Request with callback:

curl -X GET http://api.resourcewatch.org/auth/confirm/:token?callbackUrl=http://your-app.com

Password recovery

Password recovery endpoints support both HTML and JSON output formats, depending on the Content-type provided in the request.

GET <BASE API URL>/auth/reset-password

Displays the password reset form page.

POST <BASE API URL>/auth/reset-password

Endpoint where the password reset request is sent.

# Password reset
curl -X POST http://api.resourcewatch.org/auth/reset-password \
-H "Content-Type: application/json"  -d \
 '{
    "email":"your-email@provider.com"
}'

GET <BASE API URL>/auth/reset-password/:token

Endpoint used to validate email address upon password reset request.

POST <BASE API URL>/auth/reset-password/:token

Endpoint used to submit the new password.

For HTML requests, it will redirect the user to the configured redirect URL on success, or return to the “Reset your password” form on error.

For JSON requests, it will return the user object on success, or a JSON object containing details in case of error.

# New password submission
curl -X POST http://api.resourcewatch.org/auth/reset-password/<email token> \
-H "Content-Type: application/json"  -d \
 '{
    "password":"potato",
    "repeatPassword":"potato"
}'

User details management

Getting all users

Lists user accounts:

# Lists all currently active users belonging to the same apps as the requester
curl -X GET http://api.resourcewatch.org/auth/user
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \
{
    "data": {
         "id": "5d2fadb3adf1dc74d2ad05dfb",
        "email": "john.doe@vizzuality.com",
        "createdAt": "2019-10-31T13:00:58.191Z",
        "updatedAt": "2019-10-31T13:00:58.191Z",
        "role": "USER",
        "extraUserData": {
            "apps": []
        }
    },
     "links": {
         "self": "https://api.resourcewatch.org/auth/user?page[number]=1&page[size]=10",
         "first": "https://api.resourcewatch.org/auth/user?page[number]=1&page[size]=10",
         "last": "https://api.resourcewatch.org/auth/user?page[number]=1&page[size]=10",
         "prev": "https://api.resourcewatch.org/auth/user?page[number]=1&page[size]=10",
         "next": "https://api.resourcewatch.org/auth/user?page[number]=1&page[size]=10"
     },
     "meta": {
         "total-pages": 1,
         "total-items": 3,
         "size": 10
     }
}

Filter by name

You can filter by name by using the name query parameter and a regex value.

curl -X GET http://api.resourcewatch.org/auth/user?name=John
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \

If your search criteria includes characters that would need to be escaped in a regex context, you need to explicitly escape them when using this filter.

Filter by email

You can filter by name by using the email query parameter and a regex value.

If your search criteria includes characters that would need to be escaped in a regex context, you need to explicitly escape them when using this filter.

# Filter users by email address
curl -X GET http://api.resourcewatch.org/auth/user?email=my.address@email.com
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \

# Filter users by the "email+with+plus+sign@email.com" email address, that requires escaping
curl -X GET http://localhost:9000/auth/user?app=all&email=email%5C%2Bwith%5C%2Bplus%5C%2Bsign@email.com
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \

Filter by provider

You can filter by name by using the provider query parameter and a regex value.

curl -X GET http://api.resourcewatch.org/auth/user?provider=facebook
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \

If your search criteria includes characters that would need to be escaped in a regex context, you need to explicitly escape them when using this filter.

Filter by role

You can filter by name by using the role query parameter and a regex value.

curl -X GET http://api.resourcewatch.org/auth/user?role=ADMIN
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \

If your search criteria includes characters that would need to be escaped in a regex context, you need to explicitly escape them when using this filter.

Filter by app

By default, only users belonging to the same apps as the requesting user will be shown when listing users. You can change this behavior by explicitly identifying the apps you’d like to filter by, even if they are not in the list of apps the requesting user belongs to. You can pass multiple apps this way by separating them with commas.

# List users that belong to the gfw app
curl -X GET http://api.resourcewatch.org/auth/user?app=gfw
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \

# List users that belong to any app
curl -X GET http://api.resourcewatch.org/auth/user?app=all
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \

Additionally, you can pass the special all value to this filter, to load users from all applications.

Get a user by id

# shows info for user with the given id
curl -X GET http://api.resourcewatch.org/auth/user/<user_id>
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \

Update your user account details

# updates current user details
curl -X PATCH http://api.resourcewatch.org/auth/user/me
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \
 '{
    "name":"new-name",
    "photo": "https://photo-url.com",
    "extraUserData" : {
        apps: ["rw", "gfw"]
    },
    "role": "MANAGER"
}'

Response:

{
    "data": {
        "id": "57bc2611f098ce9800798688",
        "email": "test@example.com",
        "name": "new-name",
        "photo": "https://photo-url.com",
        "createdAt": "2017-01-13T10:45:46.368Z",
        "updatedAt": "2017-01-13T10:45:46.368Z",
        "role": "MANAGER",
        "extraUserData": {
           "apps": ["rw", "gfw"]
        }
    }
}

Update another user’s account details

# updates details of user given its id
curl -X PATCH http://api.resourcewatch.org/auth/user/57bc2611f098ce9800798688
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \
 '{
    "name":"new-name",
    "photo": "https://photo-url.com",
    "extraUserData" : {
        apps: ["rw", "gfw"]
    },
    "role": "MANAGER"
}'

Response:

{
    "data": {
        "id": "57bc2611f098ce9800798688",
        "email": "test@example.com",
        "name": "new-name",
        "photo": "https://photo-url.com",
        "createdAt": "2017-01-13T10:45:46.368Z",
        "updatedAt": "2017-01-13T10:45:46.368Z",
        "role": "MANAGER",
        "extraUserData": {
           "apps": ["rw", "gfw"]
        }
    }
}

Deleting a user

# updates details of user given its id
curl -X DELETE http://api.resourcewatch.org/auth/user/<user_id>
-H "Content-Type: application/json"  -d \
-H "Authorization: Bearer <your-token>" \
 '{
    "name":"user name",
    "email":"user@email.com",
    "photo": "https://s3.amazonaws.com/wri-api-backups/resourcewatch/test/profiles/avatars/000/000/022/original/data?1544443314",
    ...
}'

Microservices

A list of information related to the microservices

List all registered microservices

To obtain a list of all the registered microservices:

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

Example response:

[
    {
        "infoStatus": {
            "numRetries": 0,
            "error": null,
            "lastCheck": "2019-02-04T14:05:30.748Z"
        },
        "pathInfo": "/info",
        "pathLive": "/ping",
        "status": "active",
        "cache": [],
        "uncache": [],
        "tags": [
            "dataset"

        ],
        "_id": "id",
        "name": "Dataset",
        "url": "http://dataset.default.svc.cluster.local:3000",
        "version": 1,
        "endpoints": [
            {
                "redirect": {
                    "method": "GET",
                    "path": "/api/v1/dataset"
                },
                "path": "/v1/dataset",
                "method": "GET"
            },
            {
                "redirect": {
                    "method": "POST",
                    "path": "/api/v1/dataset/find-by-ids"
                },
                "path": "/v1/dataset/find-by-ids",
                "method": "POST"
            }
        ],
        "updatedAt": "2019-01-24T13:04:46.728Z",
        "swagger": "{}"
    },
    {
        "infoStatus": {
            "numRetries": 0,
            "error": null,
            "lastCheck": "2019-02-04T14:05:30.778Z"
        },
        "pathInfo": "/info",
        "pathLive": "/ping",
        "status": "active",
        "cache": [
            "layer"
        ],
        "uncache": [
            "layer",
            "dataset"
        ],
        "tags": [
            "layer"
        ],
        "_id": "5aa667d1aee7ae16fb419c23",
        "name": "Layer",
        "url": "http://layer.default.svc.cluster.local:6000",
        "version": 1,
        "endpoints": [
            {
                "redirect": {
                    "method": "GET",
                    "path": "/api/v1/layer"
                },
                "path": "/v1/layer",
                "method": "GET"
            },
            {
                "redirect": {
                    "method": "POST",
                    "path": "/api/v1/dataset/:dataset/layer"
                },
                "path": "/v1/dataset/:dataset/layer",
                "method": "POST"
            },
            {
                "redirect": {
                    "method": "GET",
                    "path": "/api/v1/dataset/:dataset/layer"
                },
                "path": "/v1/dataset/:dataset/layer",
                "method": "GET"
            }
        ],
        "updatedAt": "2018-11-08T12:07:38.014Z",
        "swagger": "{}"
    }
]

Filters

The microservice list provided by the endpoint can be filtered with the following attributes:

Filter Description Accepted values
status Status of the microservice pending, active or error
url Internal URL of the microservice within the cluster String

Filtering by status

curl -X GET https://api.resourcewatch.org/api/v1/microservice?status=active \
-H "Authorization: Bearer <your-token>"

Get a microservice by id

To obtain the details of a single microservice, use:

curl -X GET https://api.resourcewatch.org/api/v1/microservice/5aa667d1aee7ae16fb419c23 \
-H "Authorization: Bearer <your-token>"

Example response:

{
  "data": {
    "id": "5aa667d1aee7ae16fb419c23",
    "infoStatus": {
        "numRetries": 0,
        "error": null,
        "lastCheck": "2019-02-04T14:05:30.778Z"
    },
    "pathInfo": "/info",
    "pathLive": "/ping",
    "status": "active",
    "cache": [
        "layer"
    ],
    "uncache": [
        "layer",
        "dataset"
    ],
    "tags": [
        "layer"
    ],
    "name": "Layer",
    "url": "http://layer.default.svc.cluster.local:6000",
    "version": 1,
    "endpoints": [
        {
            "redirect": {
                "method": "GET",
                "path": "/api/v1/layer"
            },
            "path": "/v1/layer",
            "method": "GET"
        },
        {
            "redirect": {
                "method": "POST",
                "path": "/api/v1/dataset/:dataset/layer"
            },
            "path": "/v1/dataset/:dataset/layer",
            "method": "POST"
        },
        {
            "redirect": {
                "method": "GET",
                "path": "/api/v1/dataset/:dataset/layer"
            },
            "path": "/v1/dataset/:dataset/layer",
            "method": "GET"
        }
    ],
    "updatedAt": "2018-11-08T12:07:38.014Z",
    "swagger": "{}"
   }
}

Delete microservice

To remove a microservice:

curl -X DELETE https://api.resourcewatch.org/api/v1/microservice/:id \
-H "Authorization: Bearer <your-token>"

This will delete the microservice and its associated endpoints from the gateway’s database. It does not remove the actual running microservice application instance, which may re-register and become available once again.

Troubleshooting

This section is meant to help you deal with common pitfalls of everyday usage of the API.

Authentication and authorization

401 Unauthorized

401 Unauthorized errors mean that the API did not receive the necessary data to identify who you are. You may not be logged in, there may be an issue with your usage of the user token, or the token you are using may be in the wrong header.

Start by following the steps detailed here for obtaining your private token. At the end you should have your JWT token, a large string of random-looking characters.

If you are sure you have an up-to-date token but are still experiencing 401 Unauthorized errors, there may be an issue with the way the token is transmitted to the API. Be sure to use in Authorization header and Bearer <your token goes here> value.

403 Forbidden

A 403 Forbidden error means that you are identified as a valid user, but you do not have the required permissions for the action you are trying to perform. Common scenarios where this happens are: - You do not have the required user ROLE to carry out that operation. - You may be trying to operate on a resource that belongs to a different application than the ones you are associated with. - Certain resources have a concept of owner with certain actions being exclusively available to that particular user.

Check the specific documentation for the endpoint you are trying to use for more details on its behavior. Conditions that trigger a 403 Forbidden error will often vary beyond the ones listed above.

Errors

The Resource 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 incorrect
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 is not 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 temporarily offline for maintenance. Please try again later.

API attribution requirements

By using the Resource Watch API, you agree to the Resource Watch terms of service and attribution requirements.