Skip to main content
New to the API? Start with the Quickstart — your first successful call in five minutes. Then see Recommended integration flows for the end-to-end sequence we recommend.

Overview

The Polygon One API enables you to manage your EUDR and PPWR compliance data programmatically. It is designed for server-to-server integration with your ERP system (SAP, Oracle, Microsoft Dynamics, etc.). What you can do with the API:
  • Articles — Create, update, and query articles. EUDR relevance is determined automatically based on the HS code.
  • Suppliers — Manage supplier data and link suppliers to articles.
  • Plots (EUDR) — Create production plots with their geometry, read them back, link them to supplier articles, and delete them. The deforestation analysis runs automatically after creation.
  • Plot report and geometry check (EUDR) — Download the plot report as PDF, and check a geometry without creating a plot. See Geo analysis.
  • Evidence (EUDR) — Upload documents, attach them to a supplier article, and list them.
  • Orders — Import purchase and sale orders (individually or in batches). Orders can be assigned to DDS statements automatically.
  • DDS Statements — Create and manage due diligence statements for TRACES submission.
  • Packaging master data (PPWR) — Bulk create and update components, packaging units, their sizes and the links between them; units and components can be read back individually and as a list.
  • Quantity feed (PPWR) — Push the volumes placed on the market per SKU, market and year, or aggregate tonnage per material category.
  • Volume reports (PPWR) — Generate and list reports for LUCID and the other national registers, and download the file.
  • Documents (PPWR) — Upload test reports, declarations and drawings and attach them to packaging units and components.
  • Declarations of Conformity (PPWR) — Read each unit’s DoC state, list the declarations, and download the PDF.

Authentication

All API endpoints require a bearer token. Generate your API key in the Polygon One dashboard:
  1. Navigate to Settings > API Keys
  2. Click Create API Key
  3. Select the required permissions (e.g. articles:read, orders:write)
  4. Copy the generated key
Keys start with eudr_ for historical reasons. The same key works for EUDR and PPWR, provided it has the permissions and the user it acts as has the module enabled. A personal key acts as the user who created it; a company key acts as the company’s highest-ranked active user (normally the owner). Orders, DDS statements and all PPWR endpoints also need a customer account; otherwise they answer 403. Include the key in the Authorization header of every request:
API keys are confidential credentials for server-to-server communication. Store them in environment variables and never expose them in client-side code.

OAuth 2.1

The API also accepts OAuth 2.1 access tokens issued by Polygon One for an authorised application acting on behalf of a user. The token carries that user’s role and permissions (no key scopes). To obtain one, register the application (dynamic client registration is supported) and run the standard authorization-code flow with PKCE against the authorization server named in /.well-known/oauth-protected-resource. For AI assistants, see Connect Claude, ChatGPT and Copilot.

Base URL

All API requests are directed to the following URL:

Versioning

The public REST API is frozen as version 1 under /api/v1/<resource> (articles, suppliers, orders, DDS statements, import jobs, plots, evidence, PPWR). Unversioned paths (/api/…) remain a permanent alias of v1 — existing integrations keep working unchanged.
  • Contract scope: Only the endpoints documented in this reference are part of v1. Other paths under these prefixes may change. API keys are not part of the API — you create them under Settings > API Keys.
  • Additive only: Within v1, existing fields are never removed or renamed. New response fields may be added — your client must ignore unknown fields. Unknown request fields are accepted and ignored.
  • Errors: The body is { "error": string } (optionally with details or warnings), and HTTP status codes stay stable. The one exception is the rate-limit 429, see Errors & limits.
  • Breaking changes ship only as /api/v2/, with at least 6 months of parallel operation.

Permissions

Each API key is assigned specific permissions that govern access: In the Settings > API Keys dialog the permissions are grouped by area; in the EUDR module this includes the Evidence group (evidence:read, evidence:write). Deleting and re-analysing evidence is not available to API keys (403). Write permissions include the corresponding read permission. A key with articles:write may therefore perform both write operations and GET requests for articles.

Response Format

Successful responses return JSON data directly. List endpoints return arrays, while single-resource endpoints return objects. Every list endpoint returns at most 100 rows unless limit is set (max 1000); page with offset until a short page. One exception: GET /api/v1/evidence?supplierArticleId=… returns { "evidence": [...] } with every document of that supplier article as long as you send neither limit nor offset. With limit/offset it pages like the other lists; fields works as on every other GET. Creating a single resource (POST /api/v1/articles, /api/v1/suppliers, /api/v1/orders with one object and no rows) responds synchronously with HTTP 201. The PPWR bulk endpoints (components, units, formats, links, article-links, tonnage, quantities) always expect an array or rows — a single object there is a 400:
Batch imports (array or {"rows": [...]}) come in two forms — the row cap is the only tell. Endpoints with a 5,000-row cap (/api/v1/articles, /api/v1/suppliers, /api/v1/orders, /api/v1/ppwr/quantities) run asynchronously and return HTTP 202 with a job reference:
statusUrl is host-relative (/api/import-jobs/…, unversioned) — join it with the origin https://app.polygon-one.com only; it stays valid. Progress and the final result (imported, updated, skipped and failed rows) are available via GET /api/v1/import-jobs/{jobId} — see the Batch Import (async) guide. Endpoints with a 1,000-row cap (PPWR master data /api/v1/ppwr/components, /units, /formats, /links, /article-links and /api/v1/ppwr/tonnage) respond synchronously with HTTP 200 and the result in the body; components and units respond 409 overwriteRequired when an overwrite needs confirming. Details on the PPWR page.

Field selection (fields)

Every JSON GET endpoint (lists and single resources, EUDR and PPWR; file downloads such as …/mengenmeldung/{reportId}/xml excluded) accepts the optional query parameter fields: a comma-separated list of the resource’s top-level fields. The response then contains only those fields — per element for a list. Values are never changed, only fields are omitted; an optional field that is absent on a resource stays absent with fields too.
ddsReferences drops withdrawn (withdrawn) and rejected (rejected) DDS statements; every other status stays listed, including drafts that have no referenceNumber yet. A withdrawn or rejected DDS drops out of the array, and the order no longer matches hasDdsReference=true. The status move counts as a change for changedSince, so the delta poll returns the order again with an empty ddsReferences. Do not add hasDdsReference=true to a delta poll: the filter would hide exactly that order, and you would never see the revocation. Never release goods on a reference: release depends only on status or on lines[].article.eudrRelevant and lines[].article.needsManualCheck both being false in the current read (see order status). Rules, each a 400 rather than silently ignored:
  • fields must be passed once (comma-separated, not repeated).
  • The list must not be empty (?fields= alone is rejected).
  • Every name must be a documented top-level field of the resource; unknown names are listed in the error message together with the allowed fields. A field we add later can therefore never silently change an existing request.
  • Whitespace around names is ignored and duplicates count once. There is no nested selection (supplier.id).
Without fields the response is unchanged — the parameter is additive within v1.

Error Handling

The API uses standard HTTP status codes: Rate limit, retries and size limits are on Errors & limits. Error responses include an error field and optionally details:
On a validation error, details is a list of issues, one per failing field: path (the field, as a list of keys), message and code, plus further keys depending on the issue.

Duplicate warnings

When creating an article, the API runs advisory checks that can return 409 instead of creating the article:
  • Hard conflict (cannot be overridden): an article with the same internalArticleNr already exists. The response is 409 with an error message.
  • Soft warnings (overridable): a duplicate article name (duplicateName) or a duplicate ean (duplicateEan). The response is 409 with a machine-readable warnings array:
To proceed anyway from a non-interactive integration, resend the request with acknowledgeWarnings: true. Hard conflicts are never overridden by this flag.