As of Monday, January 18, 2021, the new version 2.0 of the Decentraland LAND API (or Marketplace API) is available. The full documentation can be found in the API’s repo on GitHub, but you can find an overview of the changes in this blogpost and a migration guide has been added to the Decentraland Docs.

Version 2.0 introduces several new endpoints that return more easily digestible information for anyone building tools that need access to descriptive data about LAND parcels and estates. Keep reading for an overview of v2, how it stacks up against v1, and a look at what’s getting deprecated (and what’s sticking around) in v1.

Who is the LAND API for?

If you’re not a developer familiar with the LAND NFT, you might be wondering what either version of this API is even for. In a nutshell, every LAND parcel or estate possesses a set of descriptive metadata. Tools like the Marketplace need access to this data in order to display all of the relevant details for any particular piece (or pieces) of LAND.

For example, LAND can have different types: it can be either unowned or owned. It can be dedicated to a plaza or community district, or it could be part of a public road.

LAND can also be given a descriptive name by its owner, or it’s owner could include their own name within their LAND’s details. Obviously, every parcel must also have x and y coordinates marking its position on the map of Genesis City. Now, these are just a few examples of the most important LAND metadata accessible via the LAND API, but the Marketplace and other platforms like OpenSea need access to all of this info.

Whether you’re building a marketplace or you want to render your own map of Decentraland, anyone building tools that need access to easily parsable and digestible data about LAND and Estates can make use of the LAND API.

Why do we need a new LAND API?

First and foremost, it’s important that each endpoint in any API return data in a consistent manner. Writing code against an API with multiple endpoints that return the same or related data, but in different formats, can be incredibly frustrating.

Let’s say you’re expecting to receive the LAND type as a string, but instead get an integer that maps arbitrarily to a type. How are you supposed to handle this in your code?

Version 1 of the LAND API included several inconsistencies like this, but version 2.0 has since standardized all of these data types, as you can see in the documentation.

Furthermore, the objects returned by the old v1 endpoints were often huge in size, making API calls slow to execute and the resulting data very difficult to parse. Version 2 has simplified these objects, making the API more performant and easier to integrate with your code.

Finally, not all of the parcels within Genesis City could be rendered via v1 of the LAND API. Specifically, the Aetheria community district contains an additional 2,000 parcels that were not exposed in the older API. Now these parcels are all supported by v2 of the API, making for a complete and comprehensive Atlas.

What’s new in version 2.0, and how to use it

One of the biggest differences between v1 and v2 is GET /tiles. The v1 endpoint would return an object with the format:

{
  type: number
  x: number
  y: number
  owner?: string
  estate_id?: string
  name?: string
  top?: number
  left?: number
  topLeft?: number
  price?: number
}

The new GET /v2/tiles endpoint returns the following object:

{
  id: string
  x: number
  y: number
  type: 'owned' | 'unowned' | 'plaza' | 'road' | 'district'
  top: boolean
  left: boolean
  topLeft: boolean
  updatedAt: number
  name?: string
  owner?: string
  estateId?: string
  tokenId?: string
  price?: number
}

Not only does this endpoint now return more data, like the parcel’s ID, recent update timestamp, and tokenID, but it also returns data in more readable strings as compared to integers.

You can filter your results using the following parameters:

Parameter Description Example
x1,y1,x2,y2 Request parcels within a section of the map bounded by the given coordinates. /v2/tiles?x1=10&y1=10&x2=20&y2=20
include Request parcel field data with only the specified info. /v2/tiles?include=type,top,left,topLeft
exclude Exclude specific fields in your results. /v2/tiles?exclude=updatedAt,tokenId

Due to the more complex and customizable data returned by this endpoint (and similar endpoints in v2), the new API uses fewer total endpoints and is more performant.

The Graph

You’ll notice that some old v1 endpoints don’t have a counterpart in v2. That’s because this data is now more easily accessible through The Graph: an indexing protocol that provides open APIs (called “subgraphs”) you can use to access data stored in web3 networks like Ethereum or IPFS.

The Graph is a big improvement over the previous v1 API because it provides LAND data without the need for a centralized, proprietary indexing server. By using a shared and open network, The Graph gives dApps a more stable and decentralized way of querying data on web3 protocols.

Learn how to make queries about Decentraland in The Graph by visiting The Graph’s Decentraland playground. There, you’ll find info on how requests are formatted along with a console where you can make some experimental calls!

Here’s a quick example to help you get familiar with how queries to the Graph are formatted:

Find the five cheapest parcels currently on sale:

This query returns the 5 cheapest LAND NFTs listed for sale, ordered by price. The category has been set to ‘parcel’, the order status is ‘open’ and the expiration date for the order is set to be greater than ‘now’ to ensure that none of the listed sales are expired.

Note: ‘now’ is expressed as a Unix timestamp, which can be found here.

Query:

{
  nfts(first: 5, orderBy: searchOrderPrice, where:{ category: parcel, searchOrderStatus: open, searchOrderExpiresAt_gt: 1611082372 }) {
    parcel {
      x,
      y
    }
    activeOrder {
      price
    }
  }
}

Result:

{
  "data": {
    "nfts": [
      {
        "activeOrder": {
          "price": "7950000000000000000000"
        },
        "parcel": {
          "x": "82",
          "y": "-21"
        }
      },
      {
        "activeOrder": {
          "price": "7950000000000000000000"
        },
        "parcel": {
          "x": "83",
          "y": "-21"
        }
      },
      {
        "activeOrder": {
          "price": "7950000000000000000000"
        },
        "parcel": {
          "x": "84",
          "y": "-21"
        }
      },
      {
        "activeOrder": {
          "price": "8000000000000000000000"
        },
        "parcel": {
          "x": "-74",
          "y": "-47"
        }
      },
      {
        "activeOrder": {
          "price": "8000000000000000000000"
        },
        "parcel": {
          "x": "-74",
          "y": "-46"
        }
      }
    ]
  }
}

You’ll notice that the prices are expressed in wei. Simply move the decimal point over 18 places to get the actual listed price. All numbers stored on the Ethereum blockchain are stored in wei to help maintain precision of smaller numbers.

What’s new, what’s deprecated, and what’s still supported?

Before you dive into the juicy details, it should be noted that the original v1/map.png endpoint is still supported and will not be deprecated. This is the most widely used endpoint within the community, so it’s important to avoid unnecessary breaking changes.

For a full rundown of how the old API stacks up against version 2.0, visit the documentation. Here, you’ll find a migration guide that explains which v1 endpoints have v2 replacements, which endpoints have been replaced by Graph queries, and which endpoints will be entirely unsupported.

Don’t miss future updates!

Follow Decentraland on Twitter to stay up to date with all of the latest open source, community releases in the World Explorer, Builder, Marketplace, SDK, and DAO!