curl --request POST \
--url https://app.polygon-one.com/api/v1/plots/validate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Fazenda Boa Vista – Parzelle 3",
"country": "BR",
"commodityGroup": "coffee",
"size": 2.4,
"producerName": "Fazenda Boa Vista Ltda.",
"productionDateFrom": "2026-01-01",
"productionDateTo": "2026-06-30",
"geojson": {
"type": "Polygon",
"coordinates": [
[
[
-47.0601,
-21.1802
],
[
-47.0589,
-21.1802
],
[
-47.0589,
-21.1815
],
[
-47.0601,
-21.1815
],
[
-47.0601,
-21.1802
]
]
]
}
}
'import requests
url = "https://app.polygon-one.com/api/v1/plots/validate"
payload = {
"name": "Fazenda Boa Vista – Parzelle 3",
"country": "BR",
"commodityGroup": "coffee",
"size": 2.4,
"producerName": "Fazenda Boa Vista Ltda.",
"productionDateFrom": "2026-01-01",
"productionDateTo": "2026-06-30",
"geojson": {
"type": "Polygon",
"coordinates": [[[-47.0601, -21.1802], [-47.0589, -21.1802], [-47.0589, -21.1815], [-47.0601, -21.1815], [-47.0601, -21.1802]]]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Fazenda Boa Vista – Parzelle 3',
country: 'BR',
commodityGroup: 'coffee',
size: 2.4,
producerName: 'Fazenda Boa Vista Ltda.',
productionDateFrom: '2026-01-01',
productionDateTo: '2026-06-30',
geojson: {
type: 'Polygon',
coordinates: [
[
[-47.0601, -21.1802],
[-47.0589, -21.1802],
[-47.0589, -21.1815],
[-47.0601, -21.1815],
[-47.0601, -21.1802]
]
]
}
})
};
fetch('https://app.polygon-one.com/api/v1/plots/validate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.polygon-one.com/api/v1/plots/validate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Fazenda Boa Vista – Parzelle 3',
'country' => 'BR',
'commodityGroup' => 'coffee',
'size' => 2.4,
'producerName' => 'Fazenda Boa Vista Ltda.',
'productionDateFrom' => '2026-01-01',
'productionDateTo' => '2026-06-30',
'geojson' => [
'type' => 'Polygon',
'coordinates' => [
[
[
-47.0601,
-21.1802
],
[
-47.0589,
-21.1802
],
[
-47.0589,
-21.1815
],
[
-47.0601,
-21.1815
],
[
-47.0601,
-21.1802
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.polygon-one.com/api/v1/plots/validate"
payload := strings.NewReader("{\n \"name\": \"Fazenda Boa Vista – Parzelle 3\",\n \"country\": \"BR\",\n \"commodityGroup\": \"coffee\",\n \"size\": 2.4,\n \"producerName\": \"Fazenda Boa Vista Ltda.\",\n \"productionDateFrom\": \"2026-01-01\",\n \"productionDateTo\": \"2026-06-30\",\n \"geojson\": {\n \"type\": \"Polygon\",\n \"coordinates\": [\n [\n [\n -47.0601,\n -21.1802\n ],\n [\n -47.0589,\n -21.1802\n ],\n [\n -47.0589,\n -21.1815\n ],\n [\n -47.0601,\n -21.1815\n ],\n [\n -47.0601,\n -21.1802\n ]\n ]\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.polygon-one.com/api/v1/plots/validate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Fazenda Boa Vista – Parzelle 3\",\n \"country\": \"BR\",\n \"commodityGroup\": \"coffee\",\n \"size\": 2.4,\n \"producerName\": \"Fazenda Boa Vista Ltda.\",\n \"productionDateFrom\": \"2026-01-01\",\n \"productionDateTo\": \"2026-06-30\",\n \"geojson\": {\n \"type\": \"Polygon\",\n \"coordinates\": [\n [\n [\n -47.0601,\n -21.1802\n ],\n [\n -47.0589,\n -21.1802\n ],\n [\n -47.0589,\n -21.1815\n ],\n [\n -47.0601,\n -21.1815\n ],\n [\n -47.0601,\n -21.1802\n ]\n ]\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.polygon-one.com/api/v1/plots/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Fazenda Boa Vista – Parzelle 3\",\n \"country\": \"BR\",\n \"commodityGroup\": \"coffee\",\n \"size\": 2.4,\n \"producerName\": \"Fazenda Boa Vista Ltda.\",\n \"productionDateFrom\": \"2026-01-01\",\n \"productionDateTo\": \"2026-06-30\",\n \"geojson\": {\n \"type\": \"Polygon\",\n \"coordinates\": [\n [\n [\n -47.0601,\n -21.1802\n ],\n [\n -47.0589,\n -21.1802\n ],\n [\n -47.0589,\n -21.1815\n ],\n [\n -47.0601,\n -21.1815\n ],\n [\n -47.0601,\n -21.1802\n ]\n ]\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"valid": true,
"errors": [
{
"code": "<string>",
"message": "<string>"
}
],
"warnings": [
{
"code": "<string>"
}
],
"precision": {
"digits": 123,
"class": "ok"
},
"geometry": {},
"measuredAreaHa": 123
}{
"error": "<string>",
"details": "<unknown>",
"warnings": "<unknown>"
}{
"error": "<string>",
"details": "<unknown>",
"warnings": "<unknown>"
}{
"error": "<string>",
"details": "<unknown>",
"warnings": "<unknown>"
}{
"error": "<string>",
"details": "<unknown>",
"warnings": "<unknown>"
}Parzellengeometrie prüfen
Dry run of POST /api/v1/plots: the same input, the same checks and the same geometry quality pipeline — nothing is created or changed, no analysis runs. Requires plots:read. Use it to check a geometry before you create the plot.
The answer is 200 whether the plot would be accepted or not: valid says which. valid: false carries the code create would answer in errors; geometry and measuredAreaHa are then null. valid: true carries the geometry exactly as create would store it, its geodesic area in hectares (null for a point) and the same warnings. Only a body that is not valid JSON is a 400.
A geometry with more than 20,000 vertices is valid: false with plot_geometry_too_many_vertices, as on create.
commodityGroup, size and species are optional here and checked only when sent. Not checked (create checks them): whether the supplierArticleIds belong to your company, and whether an identical plot already exists.
curl --request POST \
--url https://app.polygon-one.com/api/v1/plots/validate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Fazenda Boa Vista – Parzelle 3",
"country": "BR",
"commodityGroup": "coffee",
"size": 2.4,
"producerName": "Fazenda Boa Vista Ltda.",
"productionDateFrom": "2026-01-01",
"productionDateTo": "2026-06-30",
"geojson": {
"type": "Polygon",
"coordinates": [
[
[
-47.0601,
-21.1802
],
[
-47.0589,
-21.1802
],
[
-47.0589,
-21.1815
],
[
-47.0601,
-21.1815
],
[
-47.0601,
-21.1802
]
]
]
}
}
'import requests
url = "https://app.polygon-one.com/api/v1/plots/validate"
payload = {
"name": "Fazenda Boa Vista – Parzelle 3",
"country": "BR",
"commodityGroup": "coffee",
"size": 2.4,
"producerName": "Fazenda Boa Vista Ltda.",
"productionDateFrom": "2026-01-01",
"productionDateTo": "2026-06-30",
"geojson": {
"type": "Polygon",
"coordinates": [[[-47.0601, -21.1802], [-47.0589, -21.1802], [-47.0589, -21.1815], [-47.0601, -21.1815], [-47.0601, -21.1802]]]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Fazenda Boa Vista – Parzelle 3',
country: 'BR',
commodityGroup: 'coffee',
size: 2.4,
producerName: 'Fazenda Boa Vista Ltda.',
productionDateFrom: '2026-01-01',
productionDateTo: '2026-06-30',
geojson: {
type: 'Polygon',
coordinates: [
[
[-47.0601, -21.1802],
[-47.0589, -21.1802],
[-47.0589, -21.1815],
[-47.0601, -21.1815],
[-47.0601, -21.1802]
]
]
}
})
};
fetch('https://app.polygon-one.com/api/v1/plots/validate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.polygon-one.com/api/v1/plots/validate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Fazenda Boa Vista – Parzelle 3',
'country' => 'BR',
'commodityGroup' => 'coffee',
'size' => 2.4,
'producerName' => 'Fazenda Boa Vista Ltda.',
'productionDateFrom' => '2026-01-01',
'productionDateTo' => '2026-06-30',
'geojson' => [
'type' => 'Polygon',
'coordinates' => [
[
[
-47.0601,
-21.1802
],
[
-47.0589,
-21.1802
],
[
-47.0589,
-21.1815
],
[
-47.0601,
-21.1815
],
[
-47.0601,
-21.1802
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.polygon-one.com/api/v1/plots/validate"
payload := strings.NewReader("{\n \"name\": \"Fazenda Boa Vista – Parzelle 3\",\n \"country\": \"BR\",\n \"commodityGroup\": \"coffee\",\n \"size\": 2.4,\n \"producerName\": \"Fazenda Boa Vista Ltda.\",\n \"productionDateFrom\": \"2026-01-01\",\n \"productionDateTo\": \"2026-06-30\",\n \"geojson\": {\n \"type\": \"Polygon\",\n \"coordinates\": [\n [\n [\n -47.0601,\n -21.1802\n ],\n [\n -47.0589,\n -21.1802\n ],\n [\n -47.0589,\n -21.1815\n ],\n [\n -47.0601,\n -21.1815\n ],\n [\n -47.0601,\n -21.1802\n ]\n ]\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.polygon-one.com/api/v1/plots/validate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Fazenda Boa Vista – Parzelle 3\",\n \"country\": \"BR\",\n \"commodityGroup\": \"coffee\",\n \"size\": 2.4,\n \"producerName\": \"Fazenda Boa Vista Ltda.\",\n \"productionDateFrom\": \"2026-01-01\",\n \"productionDateTo\": \"2026-06-30\",\n \"geojson\": {\n \"type\": \"Polygon\",\n \"coordinates\": [\n [\n [\n -47.0601,\n -21.1802\n ],\n [\n -47.0589,\n -21.1802\n ],\n [\n -47.0589,\n -21.1815\n ],\n [\n -47.0601,\n -21.1815\n ],\n [\n -47.0601,\n -21.1802\n ]\n ]\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.polygon-one.com/api/v1/plots/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Fazenda Boa Vista – Parzelle 3\",\n \"country\": \"BR\",\n \"commodityGroup\": \"coffee\",\n \"size\": 2.4,\n \"producerName\": \"Fazenda Boa Vista Ltda.\",\n \"productionDateFrom\": \"2026-01-01\",\n \"productionDateTo\": \"2026-06-30\",\n \"geojson\": {\n \"type\": \"Polygon\",\n \"coordinates\": [\n [\n [\n -47.0601,\n -21.1802\n ],\n [\n -47.0589,\n -21.1802\n ],\n [\n -47.0589,\n -21.1815\n ],\n [\n -47.0601,\n -21.1815\n ],\n [\n -47.0601,\n -21.1802\n ]\n ]\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"valid": true,
"errors": [
{
"code": "<string>",
"message": "<string>"
}
],
"warnings": [
{
"code": "<string>"
}
],
"precision": {
"digits": 123,
"class": "ok"
},
"geometry": {},
"measuredAreaHa": 123
}{
"error": "<string>",
"details": "<unknown>",
"warnings": "<unknown>"
}{
"error": "<string>",
"details": "<unknown>",
"warnings": "<unknown>"
}{
"error": "<string>",
"details": "<unknown>",
"warnings": "<unknown>"
}{
"error": "<string>",
"details": "<unknown>",
"warnings": "<unknown>"
}Autorisierungen
API key generated in Settings > API Keys. Include as Authorization: Bearer <key>.
Body
Fields read from the request body. Anything else — including server-owned fields such as id, analysisStatus, analysisResult, deforestationRiskResult, forestPercentage, isDegraded, imageWidth, imageHeight, pixelCoords, createdAt and updatedAt — is ignored.
Required. Plot geometry as GeoJSON: a Feature or a bare Geometry of type Polygon, MultiPolygon, Point or MultiPoint, in WGS84 longitude/latitude. A missing geometry is 400 with code: plot_geometry_missing; any other type (FeatureCollection, GeometryCollection, LineString, MultiLineString, …) is 400 with code: plot_geometry_type_unsupported — one request creates one plot, so send each feature of a collection as its own request. Coordinates outside longitude ±180 / latitude ±90 are rejected with 400, as is a geometry above the intake limits. A point is only accepted up to 4 ha (20,000 ha for cattle) when size is given; above that EUDR requires a polygon. Part of the duplicate check.
Plot name. Part of the duplicate check (case and surrounding/multiple whitespace are ignored).
Country of production, ISO 3166-1 alpha-2 (e.g. BR). Part of the duplicate check.
Area in hectares. Must be a finite number ≥ 0, otherwise 400.
x >= 0EUDR-regulated commodity groups. non_relevant = article is not covered by EUDR.
cattle, cocoa, coffee, oil_palm, rubber, soya, wood, non_relevant Tree species. Each entry needs both a common and a scientific name, otherwise 400. Required (at least one scientific name) when commodityGroup is wood.
500Show child attributes
Show child attributes
Legacy single-species shorthand, used only when species is empty. Prefer species.
Name of the producer.
Start of the production period (YYYY-MM-DD).
End of the production period (YYYY-MM-DD).
Supplier articles to link the plot to on creation (optional; duplicates are collapsed). Every id must belong to your company, otherwise 403. Part of the duplicate check: the same plot with a different set of links is a new plot. If commodityGroup is missing or non_relevant, it is derived from the linked articles. Without links, commodityGroup is required (400, code: plot_commodity_group_required); a value outside the enum is 400 with code: plot_commodity_group_invalid.
5000Antwort
The verdict create would give; nothing written
The verdict POST /api/v1/plots would give for the same request. Nothing is written.
true when create would accept the plot; false when it would answer 400.
Why create would refuse: code (the code create answers, e.g. plot_geometry_invalid, plot_geometry_self_intersection_unrepairable, plot_geometry_too_many_vertices, plot_precision_too_low) and message. [] when valid is true.
Show child attributes
Show child attributes
What the geometry quality checks changed or noted, as on create.
Show child attributes
Show child attributes
digits: the fewest decimal places of any longitude/latitude, counted as written; class: ok (6 or more), borderline (5), low (4) or reject (3 or fewer). null when a check refused the request before the precision was measured.
Show child attributes
Show child attributes
The geometry create would store (rounded, cleaned and repaired). null when valid is false.
Show child attributes
Show child attributes
Geodesic area of geometry in hectares, rounded to 2 decimals. null for a point or when valid is false.