/api/v2/.
Entries marked Changed describe a change in behaviour, including one that refuses a request
that was accepted before; read them before you update an integration.
2026-10-20
- New:
ccEmails(max. 10) is now supported when creating one supplier withPOST /api/v1/suppliers. These contacts are copied on every email to the supplier; an address equal toemailis ignored, and an invalid address rejects the request. - Changed: production countries on article-supplier links are resolved from ISO alpha-2/alpha-3 codes and localized country names on write, and read back as canonical English country names. Older or free-text values that cannot be resolved remain unchanged.
2026-10-19
- New: PPWR packaging-unit responses include the optional
recyclabilityReferencefield: the free-text source on which the recyclability grade rests. - Changed:
POST /api/v1/dds-statementsautomatically partitions deliveries above the TRACES limits into a DDS group. The201response includesmemberIds; every member must be submitted and validated before the group head can be submitted. - New: a DDS delivery that cannot be partitioned returns
422withdds_partition_producer_too_largeorgroup_volume_too_small. The optional manual compliance check can also refuse the request with422 compliance_blockedand the blocking articles; nothing is written on these responses.
2026-10-13
- Changed:
GET /api/v1/dds-statementsandGET /api/v1/dds-statements/{id}:articles[].volume,articles[].remainingVolume,totalVolumeandtotalRemainingVolumecan benull. This happens only on external (upstream) statements whose reference was declared without a quantity. Anulltotal means at least one line has no volume. Your own statements always carry a volume. Treatnullas “not stated”, never as 0. - Changed (app, EUDR): suppliers declare an upstream DDS with the reference and verification number only; one reference covers all selected articles. The quantity per article is optional, in the supplier portal and in “Link external DDS”.
- New: the components in
GET /api/v1/ppwr/units/{id}carryheavyMetalsValueKind, as inGET /api/v1/ppwr/components. - Changed:
heavyMetalsValueKindhas the valuebelow_detection: all four heavy metals were not detected.heavyMetalsMgPerKgis thennull(never0), and the value counts as conforming. Readnulltogether withheavyMetalsValueKind, not as “unknown” on its own. - Changed (app, PPWR): heavy metals: “all four not detected” is shown as “not detected — compliant”, never as 0.
- Changed (app, PPWR): masses, dimensions, test methods and a printed “n.d.” for the heavy-metal sum are applied from a document automatically when the document prints them plainly (labelled, with unit and axis); anything else waits for your review. A total weight that may include the contents waits; a packaging type read from a document always takes one click.
- Changed (app, PPWR): a plain PFAS declaration (“PFAS-free”, “contains no PFAS”, “PFAS are not intentionally added”, a company’s ”… confirms that …”) is applied automatically. An exception, a footnote, a named substance, a hedge (“largely”, “to the best of our knowledge”) or a lab result still waits for your review.
- Changed (app, PPWR): a printed test method (e.g. “IEC 62321-5:2013”) is applied on its own — also beside a heavy-metals value the supplier entered themselves; the value itself is never overwritten.
- Fixed (app, PPWR): long lab reports are read in full instead of failing on the answer length. A limit of another regulation (e.g. RoHS, lead 1000 mg/kg) is no longer proposed as the PPWR heavy-metals limit.
- Changed (app, EUDR): legal and evidence documents: dates, parties, reference numbers and areas are filled only when the document prints them under a recognised label or in a certifying sentence; a self-certification (“X certifies that …”) names X as the issuer, never as the holder. A value the document prints but whose shape our rules cannot confirm is checked by the AI against the passage: it fills itself only when the passage states it explicitly, else it waits for your review.
- Changed (app, EUDR): a legal or evidence document is read once per file and judged for each article copy by fixed rules. The analysis is faster, and copies of the same file in the same context get the same result. The printed holder is matched against the supplier and the declared producers, also across translations and transliterations; when it matches no party, the document blocks. When the document leaves open whether the named company is the holder, you get a review hint instead of a block. The certification body is never the holder of a certificate. A certification scheme that differs from the declared one is a review hint, not a block.
- Changed (app, EUDR): a legal document is expired when its printed expiry date lies before the end of the article’s production period; with no production period, when it lies before today.
- Fixed (app, EUDR): a document submitted as evidence for a geo risk on several plots is checked against each plot’s own country and commodity. Before, the result for one plot could be reused for another. A printed validity period counts up to its latest date.
- Changed (app, EUDR): legal compliance: categories that need no evidence, or whose requirement is already met, no longer show a declined document as an open item. The document stays visible as “Optional evidence – not used” or “Not used – requirement already met”. Suppliers no longer get “Fix” hints for such documents.
- Changed (app): every document is read with Mistral OCR; PDFs up to 120 pages get full text recognition (was 40).
2026-10-09
- New:
GET /api/v1/readiness?resourceType&resourceId&actionevaluates one resource for exactly one action (eudr.dds_draft.create,eudr.dds.submit,ppwr.supplier_reply.submit,ppwr.declaration.issue): state, findings (at most 100) and the next permitted actions (at most 20). An explanatory snapshot, never an authorisation for a later write. Foreign and missing resources answer404, an unsupported combination400 not_supported. - New:
GET /api/v1/ppwr/article-units?articleId|orderIdlists the packaging units linked to exactly one article or order, paged bycursor(packaging:read). - New: the MCP server offers write tools: create articles, suppliers and orders, update orders,
create DDS drafts, update external DDS metadata, and create or update PPWR components and packaging
units and link them — plus the read tools
getReadinessandlistPpwrArticleUnits. No deletes, no invitations, no TRACES submission. See AI assistants (MCP).
2026-10-07
- New: the public API accepts OAuth 2.1 access tokens issued by Polygon One for an authorised
application acting on behalf of a user (authorization code + PKCE, dynamic client registration via
/.well-known/oauth-protected-resource). The token carries that user’s role and permissions, not API-key scopes. A consent screen shows the application and the requested access. - New: MCP server at
https://app.polygon-one.com/api/mcpfor Claude, ChatGPT and Copilot Studio: 20 read-only tools, one per GET endpoint of the REST API (listArticles,getOrder,listPpwrDeclarations…). Sign in with OAuth or an API key. No writes, no DDS submission, no compliance decisions; 120 calls per minute per user and client; results above 1 MB are refused with a hint to narrow the query; file downloads are not available to assistants yet. - Changed: endpoints that are not available for API keys (re-analysis triggers, support chat, AI import, partner logo, admin) refuse OAuth tokens too — “machine client” means both.
- Changed: a
Bearertoken that is not aneudr_key is now verified as an OAuth token and answers401when invalid; it no longer falls back to the browser session cookie. - Changed: requests carrying any
Authorization: Bearerheader no longer receive a session-cookie refresh (Set-Cookie). - New: writes made with an OAuth token are logged with the application’s client id on the audit
row (
metadata.oauthClientId); a PPWR intake through an OAuth token gets field provenanceapi, like an API-key intake. - New:
POST /api/v1/orders/{id}/origin-confirmationaccepts the order’s selectedsupplierArticleIdsafter all current plots have been uploaded and queues the supplier’s confirmation of that current origin data (202). Previous-order data is not copied and buyer authorship is preserved. See Have the supplier confirm the origin. - Fixed: two batch imports (or an import and an edit in the app) that rewrite the lines of the
same order at the same time no longer leave the order with the lines of both. The last rewrite
wins; the order’s lines are always exactly one request’s set. Never send the same
orderNumberin two in-flight requests. - Changed:
PATCH /api/v1/plots/{id}re-derives the commodity group from the new links: a plot whose group is unset ornon_relevanttakes the group of its new links, as on create (woodwhen any of them is wood); an explicit group never changes. A plot that iswoodafter the change needs a species with a scientific name — stored, or sent in the new optionalspeciesfield — otherwise400 plot_species_required. A plot whose group changed after its analysis ran is re-analysed. - New (app): an expired supplier invite link is shown as “Expired” on the supplier card, the progress sheet and the waiting cards, with a Resend that picks the right invite. The day-7 reminder revives an expired EUDR invite instead of skipping it.
- New (app): critical questionnaire answers are visible to the supplier before submit and to the buyer behind the red; a missing questionnaire country is named (chip, gaps sheet, viewer, Articles table).
- Changed (app): an update request you send about a questionnaire names the question and opens the supplier’s form on it; system-sent requests stay unchanged.
- Changed (app): the buyer-review thread entry names the section and the countries; the gaps card never shows your own request as the supplier’s reply.
- Changed (risk engine; stored verdicts move on re-analysis only): wood plots take the wood path on every branch; recurring disturbance alerts alone support HIGH only when the 2020 forest is at least 0.5 ha and the alert area at least 0.18 ha.
- New (app): suppliers whose EUDR articles were imported before the auto-invite automation was switched on, and who were never invited, are invited by a daily catch-up and at switch-on.
- Changed — breaking for integrations that send an estimated size:
POST /api/v1/evidence/upload-urlandPOST /api/v1/ppwr/documents/upload-urlsignfileSizeintouploadUrl. ThePUTmust send exactlyfileSizebytes, otherwise storage refuses it with403(before,fileSizewas only checked when the URL was issued).fileSizemust be an integer greater than0;0or a fraction answers400 "Invalid file size.". Send the file’s exact byte count. - New (documented):
POST /api/v1/evidencetakesreuseS3Key: thes3Keyfrom an earlier successful response attaches the same stored file to another supplier article without uploading it again. Exactly one source (file, theuploaded*fields orreuseS3Key), otherwise400; areuseS3Keyyour company does not own answers403. - Changed:
POST /api/v1/articles/bulk-delete,POST /api/v1/suppliers/bulk-delete,POST /api/v1/orders/bulk-delete,PUT /api/v1/articles/{id}/inputsandPOST /api/v1/articles/{id}/primary-produceranswer a body that is not a JSON object with400 { "error": "Invalid JSON body" }instead of500.
2026-10-06
- New: the API reference documents every field, examples and error bodies (including
429). - Changed: a malformed id in the path answers
400(or the endpoint’s404) instead of500. - Changed: a request body that is not a JSON object answers
400instead of500. - Changed: validation errors return
detailsas a list of issues (path,message,code) on every endpoint. - Changed: a rejected evidence file answers with
error(themessagekey stays). - Changed: deleting a member of a grouped DDS answers
409 GROUP_MEMBER_DELETE_REFUSEDinstead of500. - Changed: a single
POST /api/v1/ordersstoreslines[].positionId; mixed or repeated position ids answer400withcode(positionIdMixed,duplicatePositionId).PATCHanswers the same way. - Changed: a single
POST /api/v1/orderswith an order number that already exists answers409instead of500. - Changed:
GET /api/v1/suppliersno longer returns the internal fieldsdeletedAtandretentionUntilon embedded compliance results. - New (documented):
GET /api/v1/ppwr/units/{id}components carry eight further attributes (recycled-content source and method, contact sensitivity, heavy-metal and PFAS fields). - Changed: an order with an article that still awaits the manual EUDR-relevance check reads
open, notnotRelevantordone.lines[].article.needsManualCheckshows which line. - Changed: changing an order’s number to one that already exists answers
409(was500). - Changed: plots (API keys only): a
supplierArticleIdsvalue that is not a list answers400 plot_supplier_article_ids_invalid(was: plot created without links). - Changed: plots (API keys only): without
commodityGroup, a plot whose linked articles give no single commodity group answers400 plot_commodity_group_required(was: created, analysis failed). - Changed: plots (API keys only): the wood-species rule and the point-area cap use the effective
commodity group (sent, or derived from the links). A retry of a plot that is wood through its links
needs
species. - Changed: PPWR units refused by the plan’s unit quota are reported in
failedwithpackagingUnitQuotaReached(were inskipped); a refused unit creates nothing, not even its supplier. - Changed: on PPWR
links, a blankmassGramswith aformatReferencekeeps the stored per-size mass (was: deleted it). - Changed: attaching a PPWR document answers
201withextractionQueued: falsewhen the analysis could not be queued (was500after the document was stored). - Changed: the declaration PDF’s
langis matched case-insensitively; an unsupported value answers400listing the supported codes (was: German). - Changed: the technical-documentation PDF validates
langlike the declaration PDF: an unsupported value answers400(was: German). - Changed: in a PPWR import, a size row with an empty Supplier cell under a unit that names a
supplier is accepted (was
conflictingSizeRow); a size row keeps its own error when its unit fails. - New:
POST /api/v1/ppwr/mengenmeldung/reportsuses the LUCID operator id stored for the workspace when the request omits it, and returns thesystemOperatorIdit used. - Changed: the five PPWR yes/no flags (
contactSensitive,foodContact,placedUnderOwnBrand,modifiesConformity,reusable) can be switched off through the import: a statednois stored; a blank keeps the stored value. A size row that contradicts its unit row fails withconflictingSizeRow. - Changed:
POST /api/v1/ppwr/formatsasks before it overwrites existing sizes:409witherror: "overwriteRequired"andconfirmUpdateCount; resend withoverwrite: true(like units and components). - Changed:
GET /api/v1/ppwr/declarations?changedSince=also returns a declaration that was superseded, or whoseactiveSpecIdsshrank because a newer declaration took over a unit. - New: declarations carry
supersededAt. - Changed: a declaration’s
pdfUrlisnullwhen the file cannot be served. - Changed: volume report: a packaging unit counts its figure without size OR its per-size
figures, never both. A unit holding both blocks the report with
placement_both_levelsuntil one level is cleared (this includes reusable units). Typed figures outrank the quantity feed, the feed outranks figures taken from orders. - Changed: quantity feed: feed figures are computed whenever they are read — link and SKU
changes apply without a re-push; they are placed per size when every linked SKU of a multi-size
unit names a size, otherwise on the unit.
derived/cleared/conflictsin the job result count packaging units of the touched period/market scopes. Every push is recorded in the audit log (one entry per push, with the job id and the API key). Pushes into one workspace are processed one at a time, so two pushes into the same period and market can no longer leave a mix of both. - Changed: generating a volume report supersedes only the previous report of the same type for that year and market (an HJM1 no longer marks a filed HMM1 as superseded). Version numbers count per report type.
- New:
DELETE /api/v1/ppwr/tonnage?periodYear&market&zsvrCategoryremoves a tonnage figure the API pushed;404when none,409 manualOverridePresentfor a figure entered in the app. - Changed:
GET /api/v1/evidencehonourslimit,offsetandfields(they were ignored); an unknown field orlimitabove 1000 answers400. Without them the full list is returned as before. Documents are returned oldest upload first. - Changed: a re-analysis of a single plot keeps the previous result until the new one is
written, also after a failed run (
analysisStatusandassessedAttell which run it belongs to). - Changed: an idempotent plot repeat with an invalid
sizeanswersdeduplicated; the dry run (POST /api/v1/plots/validate) answersvalid: falsewithPLOT_LIMIT_REACHEDat the plot limit.
2026-10-02
- Changed: when an order batch (
POST /api/v1/orderswith an array) creates an article for a purchase order, that article is now a per-order template in every workspace. The order line points at its own copy of the article, numbered<internalArticleNr>#<orderNumber>, solines[].articleinGET /api/v1/ordersnames that copy. Sale orders and existing articles are unchanged. - New: PPWR unit rows accept
materialandmassGrams. A new unit with amaterialand nocomponentCodesgets one main-part component. The response addsmainPartsCreatedandunitsWithoutComponents.
2026-10-01
- New: read PPWR Declarations of Conformity —
GET /api/v1/ppwr/declarations,GET /api/v1/ppwr/declarations/{id}and the PDF viaGET /api/v1/ppwr/declarations/{id}/pdf.GET /api/v1/ppwr/units?include=docaddsdocStateandactiveDeclarationper unit. See Reading Declarations of Conformity. - New: EUDR evidence under v1 —
POST /api/v1/evidence/upload-url,POST /api/v1/evidenceandGET /api/v1/evidence, with the permissionsevidence:readandevidence:write. - New: articles carry
supplierLinks([{ supplierId, supplierArticleId }]). - New: attach documents to PPWR units and components —
POST /api/v1/ppwr/documents/upload-urlandPOST /api/v1/ppwr/documents. See Uploading documents. - New: the ERP integration key preset includes
plots:writeandevidence:write. Keys created earlier keep their permissions. - Changed: re-analysing a plot is no longer available to API keys —
POST /api/v1/plots/{id}/reanalyzeanswers403("Not available for API keys"). - Changed: a workspace can have a plot limit and a monthly plot quota. When one is reached,
POST /api/v1/plotsanswers409withcode: "PLOT_LIMIT_REACHED"and creates nothing. - Changed: exports can be switched off for a workspace. Downloads such as the plot report, the
Declaration of Conformity PDF and the volume report file then answer
403withcode: "EXPORTS_BLOCKED". - Changed: an optional compliance check for DDS statements. When it is switched on for your
workspace,
POST /api/v1/dds-statementsandPOST /api/v1/dds-statements/{id}/submitanswer422witherror: "compliance_blocked"anddetails.blockingArticleswhile articles are not compliant.
2026-09-30
- Changed:
POST /api/v1/orderswith one object now storesdeliveryDate. Before, the value was accepted and dropped.
2026-09-29
- New: geo analysis guide.
POST /api/v1/plots/validatechecks a geometry without creating a plot;GET /api/v1/plots/{id}/reportreturns the plot report as PDF. See Geo analysis over the API. - New:
GET /api/v1/plots/{id}carries ananalysisobject with the result of the deforestation analysis. - Changed:
POST /api/v1/plotswith an API key refuses lines, collections, coordinates with fewer than 4 decimal places and geometry that cannot be repaired —400with acode, nothing is written. It stores the normalised geometry and returnsdeduplicatedandwarnings. - Changed:
plotsembedded in articles, suppliers and DDS statements lists distinct plots without geometry, at most 1000 entries;plotsTruncated: truemeans more exist. Articles embedded in a supplier carry no plots. Fetch a plot’s geometry withGET /api/v1/plots/{id}. - Changed:
POST /api/v1/orderswith one object refuses asupplierIdof another company and an article id your company does not own (400). - New: PPWR unit and size rows accept
supplierReference(the supplier’s article number). - Changed: PPWR unit and component rows with an unknown
supplierNamenow create a name-only supplier and link it (listed insuppliersCreated). Before, the row was stored without a supplier.
2026-09-26
- Changed: every list endpoint returns at most 100 rows when
limitis not set (limitat most 1000). Page withoffsetuntil a page is shorter thanlimit. Exception:GET /api/v1/evidencereturns every row and ignoreslimitandoffset. - New: guide for delta sync of orders with
changedSince. See Delta sync. - New: optional
positionIdon order rows (your ERP position number). See Positions. - New: derived order
status(open,done,notRelevant) and the?status=filter onGET /api/v1/orders. - New: with per-order article copies enabled,
hsCodeon order rows can create a new version of the order’s article copy. - Changed:
ddsReferencesand thehasDdsReferencefilter drop withdrawn and rejected DDS statements. - Documented:
hsCodeandarticleDescriptionon order rows only apply when the row creates the article.
2026-09-24
- New: versioned paths
/api/v1/…. Paths without a version (/api/…) stay a permanent alias. See Versioning. - New:
fieldsquery parameter on every JSONGETendpoint (exceptGET /api/v1/evidence, which ignores it). See Field selection. - New: the OpenAPI spec is generated from the application’s own request and response contracts.
2026-09-23
- New: plots API — create, read, link and delete plots.
- New:
changedSincefilter onGET /api/v1/orders. - Changed:
PATCH /api/v1/dds-statements/{id}changes external DDS statements only; any other statement answers404.
2026-09-15
- New: read PPWR master data back —
GET /api/v1/ppwr/units,/units/{id},/components,/components/{id}. - Changed:
PATCH /api/v1/orders/{id}andPATCH /api/v1/articles/{id}ignore fields that cannot be changed.
2026-09-05
- New: PPWR packaging sizes —
POST /api/v1/ppwr/formats. See PPWR.
2026-08-17
- New: PPWR quantity feed (
POST /api/v1/ppwr/quantities), tonnage (POST /api/v1/ppwr/tonnage) and volume reports (/api/v1/ppwr/mengenmeldung/…). See PPWR.
2026-07-31
- New: link SKUs to PPWR units —
POST /api/v1/ppwr/article-links.
2026-07-28
- New: filter and page
GET /api/orders—hasDdsReference,orderNumbers,limitandoffset.
2026-07-27
- Fixed: the base URL in the reference is
https://app.polygon-one.com.
2026-07-12
- New: PPWR API — master-data intake for components, units and links
(
POST /api/ppwr/components,/units,/links). See PPWR. - Changed: batch imports of articles, suppliers and orders run asynchronously —
202with ajobId, results viaGET /api/import-jobs/{jobId}. A single object still answers201.
2026-06-16
- New: duplicate and plausibility warnings on article create (
409withwarnings, override withacknowledgeWarnings).