Back to data catalog
Soil API
Global soil information based on SoilGrids-data
OpenAPI Spec
Specification of all endpoints available in the soil api.
Github
Explore the source code behind the soil api.
More info
Data sources
The API is exclusively fetching data from ISRIC (International Soil Reference and Information Centre) - World Soil Information's WebDAV functionality. The service uses SoilGrids data, which is licensed under the CC BY 4.0 license. The data are available at 250 meter resolution.
The nature of the available soil data can be separated into two categories: soil type and soil properties. Soil type data is categorical and represents the dominant soil type at the queried location. The 30 available soil types are: Acrisols, Albeluvisols, Alisols, Andosols, Arenosols, Calcisols, Cambisols, Chernozems, Cryosols, Durisols, Ferralsols, Fluvisols, Gleysols, Gypsisols, Histosols, Kastanozems, Leptosols, Lixisols, Luvisols, Nitisols, Phaeozems, Planosols, Plinthosols, Podzols, Regosols, Solonchaks, Solonetz, Stagnosols, Umbrisols, and Vertisols. More information about the soil types can be found here.
Soil property data is continuous and represents the value of a specific soil property at the queried location and depth. The available soil properties are: Bulk density (bdod), Cation exchange capacity (cec), Coarse fragments (cfvo), Clay (clay), Nitrogen (nitrogen), Organic carbon density (ocd), Organic carbon stocks (ocs), pH water (phh2o), Sand (sand), Silt (silt), and Soil organic carbon (soc). The available depths are: 0-5cm, 5-15cm, 15-30cm, 30-60cm, 60-100cm, 100-200cm, and 0-30cm (the ocs property is only available for the 0-30cm depth and vice versa.) The available values are: mean, 0.05 quantile, median, 0.95 quantile, and uncertainty.
For more information about the data, please visit the SoilGrids FAQ.
Processing
The data is retrieved from the ISRIC WebDAV service through various raster files and processed to be served through the API. For example, soil types are mapped from integer values to the corresponding soil type names, and the units of the soil properties are added to responses. Additionally, some aggregation is performed to produce a summary of the soil types, which, given a bounding box, provides a mapping of each soil type to its number of occurrences in the bounding box.
Examples
Example 1
Retrieving the most probable soil type at the queried location.
// Get the most probable soil type at the queried location
const response = await fetch(
"https://api.openepi.io/soil/type?" +
new URLSearchParams({
lon: "9.58",
lat: "60.1",
})
)
const json = await response.json()
// Get the most probable soil type
const mostProbableSoilType = json.properties.most_probable_soil_type
console.log(`Most probable soil type: ${mostProbableSoilType}`)
from httpx import Client
with Client() as client:
# Get the soil type at the queried location
# and the probability of the top 3 most probable soil types
response = client.get(
url="https://api.openepi.io/soil/type",
params={"lat": 60.1, "lon": 9.58, "top_k": 3},
)
json = response.json()
# Get the soil type and probability for the second most probable soil type
soil_type = json["properties"]["probabilities"][1]["soil_type"]
probability = json["properties"]["probabilities"][1]["probability"]
print(f"Soil type: {soil_type}, Probability: {probability}")
import io.openepi.soil.api.SoilApi;
import io.openepi.soil.model.SoilTypeJSON;
import io.openepi.common.ApiException;
import io.openepi.soil.model.SoilTypes;
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal lon = new BigDecimal("9.58");
BigDecimal lat = new BigDecimal("60.1");
SoilApi api = new SoilApi();
try {
SoilTypeJSON response = api.getSoilTypeTypeGet(lon, lat, null);
SoilTypes mostProbableSoilType = response.getProperties().getMostProbableSoilType();
System.out.println("Most probable soil type: " + mostProbableSoilType);
} catch (ApiException e) {
System.err.println("Exception when calling SoilApi#getSoilTypeTypeGet");
e.printStackTrace();
}
}
}
Example 2
Retrieving the mean of the soil property at the queried location and depth.
// Get the mean value of the soil property at the queried location and depth
const response = await fetch(
"https://api.openepi.io/soil/property?" +
new URLSearchParams({
lon: "9.58",
lat: "60.1",
depths: "0-5cm",
properties: "bdod",
values: "mean",
})
)
const json = await response.json()
// Get the soil information for the bdod property
const bdod = json.properties.layers[0]
// Get the soil property unit and name
const bdodUnit = bdod.unit_measure.mapped_units
const bdodName = bdod.name
// Get the soil property mean value at depth 0-5cm
const bdodDepth = bdod.depths[0].label
const bdodValue = bdod.depths[0].values.mean
console.log(
`Soil property: ${bdodName}, Depth: ${bdodDepth}, Value: ${bdodValue} ${bdodUnit}`
)
from httpx import Client
with Client() as client:
# Get the mean and the 0.05 quantile of the soil properties at the queried location and depths
response_multi = client.get(
url="https://api.openepi.io/soil/property",
params={
"lat": 60.1,
"lon": 9.58,
"depths": ["0-5cm", "100-200cm"],
"properties": ["bdod", "phh2o"],
"values": ["mean", "Q0.05"],
},
)
json_multi = response_multi.json()
# Get the soil information for the phh2o property
phh2o = json_multi["properties"]["layers"][1]
# Get the soil property unit and name
phh2o_name = phh2o["name"]
phh2o_unit = phh2o["unit_measure"]["mapped_units"]
# Get the soil property 0.05 quantile value at depth 100-200cm
phh2o_depth = phh2o["depths"][1]["label"]
phh2o_value = phh2o["depths"][1]["values"]["Q0.05"]
print(
f"Soil property: {phh2o_name}, Depth: {phh2o_depth}, Value: {phh2o_value} {phh2o_unit}"
)
import io.openepi.soil.api.SoilApi;
import io.openepi.soil.model.*;
import io.openepi.common.ApiException;
import java.math.BigDecimal;
import java.util.List;
public class Main {
public static void main(String[] args) {
BigDecimal lon = new BigDecimal("9.58");
BigDecimal lat = new BigDecimal("60.1");
List<SoilDepthLabels> depths = List.of(SoilDepthLabels._0_5CM);
List<SoilPropertiesCodes> properties = List.of(SoilPropertiesCodes.BDOD);
List<SoilPropertyValueTypes> values = List.of(SoilPropertyValueTypes.MEAN);
SoilApi api = new SoilApi();
try {
// Get the soil information for the bdod property
SoilPropertyJSON response = api.getSoilPropertyPropertyGet(lon, lat, depths, properties, values);
SoilLayer bdod = response.getProperties().getLayers().get(0);
// Get the soil property unit and name
SoilMappedUnits bdodUnit = bdod.getUnitMeasure().getMappedUnits();
String bdodName = bdod.getName();
// Get the soil property mean value at depth 0-5cm
SoilDepthLabels bdodDepth = bdod.getDepths().get(0).getLabel();
BigDecimal bdodValue = bdod.getDepths().get(0).getValues().getMean();
System.out.println("Soil property: " + bdodName + ", Depht: " + bdodDepth + ", Value: " + bdodValue + " " + bdodUnit);
} catch (ApiException e) {
System.err.println("Exception when calling SoilApi#getSoilPropertyPropertyGet");
e.printStackTrace();
}
}
}
Example 3
Get a summary of the soil types in the queried bounding box.
// Get a summary of the soil types in the queried bounding box, represented
// by a mapping of each soil type to the number of occurrences in the bounding box
const response = await fetch(
"https://api.openepi.io/soil/type/summary?" +
new URLSearchParams({
min_lon: "9.5",
max_lon: "9.6",
min_lat: "60.1",
max_lat: "60.12",
})
)
const json = await response.json()
// Get the summary of the soil types in the bounding box
const summaryList = json.properties.summaries
// Get the soil type and the number of occurrences
const soilType1 = summaryList[0].soil_type
const count1 = summaryList[0].count
const soilType2 = summaryList[1].soil_type
const count2 = summaryList[1].count
console.log(`Soil type: ${soilType1}, Count: ${count1}`)
console.log(`Soil type: ${soilType2}, Count: ${count2}`)
from httpx import Client
with Client() as client:
# Get a summary of the soil types in the queried bounding box, represented
# by a mapping of each soil type to the number of occurrences in the bounding box
response = client.get(
url="https://api.openepi.io/soil/type/summary",
params={"min_lon": 9.5, "max_lon": 9.6, "min_lat": 60.1, "max_lat": 60.12},
)
json = response.json()
# Get the summary of the soil types in the bounding box
summary_list = json["properties"]["summaries"]
# Get the soil type and the number of occurrences
soil_type_1 = summary_list[0]["soil_type"]
count_1 = summary_list[0]["count"]
soil_type_2 = summary_list[1]["soil_type"]
count_2 = summary_list[1]["count"]
print(f"Soil type: {soil_type_1}, Count: {count_1}")
print(f"Soil type: {soil_type_2}, Count: {count_2}")
mport io.openepi.soil.api.SoilApi;
import io.openepi.soil.model.*;
import io.openepi.common.ApiException;
import java.math.BigDecimal;
import java.util.List;
public class Main {
public static void main(String[] args) {
BigDecimal minLon = new BigDecimal("9.5");
BigDecimal maxLon = new BigDecimal("9.6");
BigDecimal minLat = new BigDecimal("60.1");
BigDecimal maxLat = new BigDecimal("60.12");
SoilApi api = new SoilApi();
try {
SoilTypeSummaryJSON response = api.getSoilTypeSummaryTypeSummaryGet(minLon, maxLon, minLat, maxLat);
// Get the summary of the soil types in the bounding box
List<SoilTypeSummary> summaryList = response.getProperties().getSummaries();
// get the soil type and the number of occurrences
SoilTypes soilType1 = summaryList.get(0).getSoilType();
int count1 = summaryList.get(0).getCount();
SoilTypes soilType2 = summaryList.get(1).getSoilType();
int count2 = summaryList.get(1).getCount();
System.out.println("Soil type: " + soilType1 + ", count: " + count1);
System.out.println("Soil type: " + soilType2 + ", count: " + count2);
} catch (ApiException e) {
System.err.println("Exception when calling SoilApi#getSoilTypeSummaryTypeSummaryGet");
e.printStackTrace();
}
}
}