Changelog
Track breaking changes, new features, and improvements to the Pixee PIM API.
v6.42.0 — app API
- No public route was added, removed or changed: the public reference stays at 635 paths and 751 operations, and the public contract v1 (
/ext,/windev) is unchanged. - This release adds, in the app, Settings › Supervision › Service status (
GET /settings/etat-service: service state, last successful backup, instance version and whether it is up to date — opened instance by instance) and the control-plane exchange behind it. Those routes carry theSettingstag or are internal to the Pixee control plane and are not part of the public reference; their response schemas appear incomponents.schemaswithout being referenced by any public operation.
v6.41.0 — app API
- Added (authentication)
GET /auth/session-policy— public, like/auth/password-policy:inactivite_max_minutes, the maximum session inactivity in force (Settings › Security, 120 minutes by default). See Authentication → Session policy. - Removed (exports) the six
/exports/schedules*operations now answer410 EXPORT_SCHEDULES_RETIRED(nothing read or written) and are markeddeprecated; theExportSchedule*schemas are gone. Export schedules were never run — use the schedules of a sync profile. The routes will disappear after 30 days without calls. See Exports → Export schedules (retired). - Added (connections) sync profiles —
contenusacceptsmedias(image gallery) andmarques(brand): an export profile carrying only those updates existing products on PrestaShop, WooCommerce or Magento (never creates one; texts, prices and stocks untouched). Elsewhere and on import the profile is saved but not executable:409 SYNC_PROFIL_NON_EXECUTABLEwithdetails.raison: "contenu_partiel_non_pris_en_charge"and, new,details.contenus_non_pris_en_charge. Two more profile types: “Médias”, “Fiche + médias”. The import “Par défaut” no longer listsmedias/marques. See Connectors → Sync profiles. - Changed (connections)
POST /sync-profils/typescreates only the types executable in that direction on that platform (no SEO or “Médias” type on import; none to Dolibarr, Sage or Odoo; no SEO type to Magento) — they used to be created, then refused at launch. On PrestaShop a texts / SEO-only profile no longer sets product features or GPSR records. - Changed (products)
POST /products/{product_id}/media/uploadreadstitle,alt_text,positionandis_primaryfrom the multipart form (they were read from the query string, so form values were lost);is_primary: truereplaces the product's previous primary image. - Added (errors)
VALIDATION_HOST_UNRESOLVED(400, a host that does not resolve,details.champ) — previously reported asVALIDATION_URL_REJECTED_SSRF— andEXPORT_SCHEDULES_RETIRED(see Errors). - The public reference grows from 634 to 635 paths and from 750 to 751 operations. The instance alert state (
etaton/settings/alertes) and the Pixee fleet supervision routes are not part of the public reference. The public contract v1 is unchanged.
v6.40.0 — app API
- No public route was added, removed or changed: the public reference stays at 634 paths and 750 operations, and the public contract v1 (
/ext,/windev) is unchanged. - Changed (products)
POST /products/corbeille/restaurer— a product whose internal reference (SKU) has since been taken by another product stays in the trash withstatut: "ignore"andmotif: "sku_deja_utilise", instead of a generic failure; the other products of the request are restored. - The instance alert settings and the supervision screens added in this release are not part of the public reference.
v6.39.0 — app API
- Added (imports)
POST /mapping-templates/{template_id}/dupliquer— duplicates a column (mapping) template: optional body{ "name" }, otherwise “X (copie)”, suffixed if needed; the copy is never the default. See Imports → Duplicate a mapping template. - Added (imports)
GET /mapping-templatesandGET /mapping-templates/supplier/{supplier_id}accept?import_type=and returnimport_typefor each template; the supplier's default template comes first. - Changed (imports) template names are unique per supplier and import type (case ignored) on creation, rename and duplication:
409 MAPPING_TEMPLATE_NOM_PRISwithdetails.modele_existant_id; existing duplicates stay readable. Only one default per supplier and import type, and imports started without a template (email, FTP, scheduled) apply that default first.POST /mapping-templates/code2asinsaves the per-field modes (global_mode,field_options:skip,fill,overwrite) and takesremplacer: trueto rewrite the template of the same name. See Imports → Mapping templates. - Added (connections) sync profiles — an import profile may carry
mapping_id, a named import mapping of the same connection (ornullfor “Par défaut”); it is applied at launch and on schedules, and the import guards are judged with it. Refusals:422 SYNC_PROFIL_INVALIDEwithdetails.raisonmapping_envoi_interdit,mapping_inconnuormapping_incompatible.POST /sync-profils/{profil_id}/lanceraccepts{"apercu": true}on an import profile to launch only its import preview (apercu_import_seulementotherwise). See Connectors → Sync profiles. - Added (errors)
MAPPING_TEMPLATE_NOM_PRIS(see Errors). - The public reference grows from 633 to 634 paths and from 749 to 750 operations. Named import mappings of the shops (
/{platform}/import/mappings,/import/modeles-mapping, their/copieractions) are managed in the app and are not part of the public reference. The public contract v1 is unchanged.
v6.38.0 — app API
- Changed (connections) sync profiles now run what they announce: their
surchargesare applied by the synchronization, and an export profile withtextes/seowithoutfichesends only those texts on PrestaShop and WooCommerce (existing products only: no creation, images, variations or combinations).raison_non_executableand409 SYNC_PROFIL_NON_EXECUTABLEdetails.raisontake new values:inactif,surcharge_non_appliquee(withdetails.surcharges_non_appliquees) andcontenu_partiel_non_pris_en_charge; the v6.37 valuessurcharges_au_lot_suivant,contenu_partiel_au_lot_suivantandmapping_au_lot_suivantare gone — update any code that matched them.POST /sync-profils/typescreates the export “SEO” and “SEO + contenus” types with the overridetextes_envoyes(their text groups,toujours) where the platform has that option. See Connectors → Sync profiles. - Added (imports)
GET /imports/returnspeut_relancerfor each job: it can be retried — status allows it and the file is still stored. - No public route was added or removed: 633 paths, 749 operations; the public contract v1 is unchanged.
v6.37.0 — app API
- Added (connections) sync profiles —
/sync-profils, 9 operations under theConnectorstag: list a connection's profiles (with the two computed “Par défaut”), create, read, update, delete, list and create the profile types (Stock, Stock + prix, SEO, SEO + contenus), attach a profile to a sync schedule, and launch a profile. They cover the PrestaShop, WooCommerce, Magento, Dolibarr, Sage and Odoo connections. Launching an export profile creates only previews to validate — nothing is sent before; a profile that is not neutral (overrides, partial product record) or inactive cannot be launched yet:409 SYNC_PROFIL_NON_EXECUTABLE. See Connectors → Sync profiles. - Added (errors)
SYNC_PROFIL_INTROUVABLE,SYNC_PROFIL_INVALIDE,SYNC_PROFIL_NOM_PRIS,SYNC_PROFIL_UTILISE,SYNC_PROFIL_NON_EXECUTABLE,SYNC_PROFIL_INCOMPATIBLE(see Errors). - Schedules without a profile run “Par défaut”, exactly as before. No other public route changed: the public reference grows from 628 to 633 paths and from 740 to 749 operations; the public contract v1 (
/ext,/windev) is unchanged.
v6.35.0 and v6.36.0 — app API
- No public route was added, removed or changed: the public reference stays at 628 paths and 740 operations, and the public contract v1 (
/ext,/windev) is unchanged. - Changed (connections) field correspondences saved for a PrestaShop, WooCommerce or Magento connection are now applied on export, on top of the default mapping (never instead of it), as they already were for Dolibarr and Sage. Saving a correspondence outside the allowed fields is refused with
422— new codeSYNC_FIELD_MAPPING_TARGET_UNKNOWN, alongsideSYNC_FIELD_MAPPING_TARGET_PROTECTED,SYNC_FIELD_MAPPING_SOURCE_INVALID,SYNC_FIELD_MAPPING_STRATEGY_UNSUPPORTEDandVALIDATION_INVALID_PATTERN(see Errors). The per-platform correspondence routes are not part of the public reference. - Changed (connections) outbound calls to shops and ERPs now follow instance-wide caps (calls per second, simultaneous synchronizations) set by an administrator; a synchronization over the cap waits instead of failing. The rate limits of this API are unchanged.
v6.34.0 — app API
- Removed (export destination) Google Drive is no longer offered as an export destination.
platform_type: "gdrive"stays in thePlatformTypeenum so existing Drive platforms can still be read, but creating, testing, previewing, sending to or scheduling one answers422 EXPORT_INTEGRATION_ABSENT(POST /exports/platforms,POST /exports/platforms/test,POST /exports/platforms/{platform_id}/test…). Useftp,sftp,s3orminio. Google Drive remains an import source (import_type: "google_drive"). See Exports → Export platforms. - No public route was added or removed; the public contract v1 (
/ext,/windev) is unchanged.
Public contract v1 — October 2026
Since October 7, 2026, /api/v1/ext/* and /api/v1/windev/* — the families called with an API key — form the public contract, major version 1, with its own frozen specification (openapi-public-v1.json, 20 operations), its own version header and a deprecation policy (see API versioning). Entries below are listed most recent first.
October 30, 2026
- Breaking (announced in v1 by exception)
POST /ext/products,POST /ext/products/batch,PUT /ext/products/{ean},PATCH /ext/products/{ean}—category_idis no longer written (the former category tree has been removed): the key is ignored and cited inchamps_ignores(champs_ignores_par_fichein a batch). Read back,category_idstays in the contract and is alwaysnull. File products with the Category Manager. - Deprecated
GET /windev/categories— it served the former category tree and now returns an empty list (same shape), with theDeprecation/Sunsetheaders; removal on April 28, 2027 at the earliest. Thecategorysent byPOST /windev/products/syncis filed in the Category Manager.
October 26, 2026
- Breaking (announced in v1 by exception) WinDev ambiguous reference —
GET/PATCH /windev/products/{ref},POST /windev/products/{ref}/activate|deactivate,POST /windev/products/sync,POST /windev/stock/update,POST /windev/prices/update: when the EAN or manufacturer reference designates several live products, none is chosen and nothing is written —409 WINDEV_REFERENCE_AMBIGUOUSon single routes (details:reference,champ,produits),status: "error"+error_codeon the line of a batch. Previously500. - Breaking (announced in v1 by exception) WinDev trash — a product in the trash is no longer returned by
GET /windev/products,/products/since/{timestamp}(nor counted intotal);GET /windev/products/{ref}of a product that exists only in the trash answers409 WINDEV_PRODUCT_IN_TRASH. Writes to such a product are refused with the same code (previously it was modified and reactivated): restore it, then resend. - Breaking (announced in v1 by exception) WinDev price direction —
POST /windev/products/sync,PATCH /windev/products/{ref},POST /windev/prices/update:price_htis now stored as the selling price excl. VAT (previously as purchase cost, andprice_ttcas selling price).price_ttcis never stored: alone, the line is refused (WINDEV_PRICE_TTC_ONLY,422onPATCH); withprice_ht, it is cited inchamps_ignores. In reads,price_ttcis computed:price_ht × (1 + tax_rate / 100),nullwithouttax_rate. See WinDev → Prices. - Breaking (announced in v1 by exception)
POST /windev/products/sync— an update no longer reactivates a deactivated product; only a created product is activated. - Fixed
POST /windev/products/sync—categoryis attached to the existing category with that name (or id); no category is created; unknown or ambiguous →category_unresolvedon the line, the product's category untouched. - Added
champs_ignores(andchamps_ignores_par_ficheon batches) on every/extand/windevwrite: unknown keys stay tolerated for the whole life of v1, but are now listed in the response instead of being dropped silently. Refusing them (422 REQUEST_UNKNOWN_FIELD) is reserved for a future v2. - Added
GET /ext/products,/ext/products/{ean},/ext/products/delta(and writes that return the product) — read-only fieldssku,condition,net_content,net_content_unit,gross_weight, and product safety (EU GPSR):fabricant(resolved manufacturer, withprovenanceandpersonne_responsable) andavertissements_securite. See External API → Read-only fields. - Clarified
min_order_quantityandlead_time_dayssent by WinDev are the product's (minimum sale quantity, product lead time), not a supplier's. No behaviour changes.
October 23, 2026
- Fixed
/extwrites —brand_nameis matched against your brand directory (exact name ignoring case and accents, alias, or name without legal suffix); unknown, ambiguous or disabled → name kept without an attached brand; no brand is created. Changing the name detaches the previous brand;PUTwithbrand_nameabsent ornull, orPATCHwith"", detaches it. See External API → Brands. - Added
POST /ext/products/batch—data.brands_unresolved. - Fixed
PATCH /windev/products/{ref}andPOST /windev/products/sync— same brand matching forbrand;brand: ""detaches the brand. Addedbrand_unresolved(inconnue,ambigue,inactive) on the sync line.
October 21, 2026
- Clarified
POST /ext/products/batch— aurl_slugthat looks like a full address (a:before the first/, such asjavascript:, including encoded forms::,:, full-width colon) in one product refuses the entire request on entry (422 VALIDATION_URL_SLUG_SCHEME); no product of the batch is saved. Send only the end of the address (my-product-42), then resend the batch. A slug that is only too long still refuses just its product. No behaviour changes. - Fixed
POST /ext/products/batchandPOST /windev/products/sync— an unexpected error on one product no longer returns the technical error text (database query, values) inerror_detailsorerror: the reason says the product was not saved, that the others are processed each on its own, and gives a reference to pass on to support. The reason for a deliberate refusal (namerequired to create, slug, product cap) is unchanged. - Fixed
POST /windev/products/sync— the wait for the product-cap check is bounded to 5 seconds for the whole call (previously up to 5 seconds per creation). Beyond that, a creation whose cap cannot be checked right away is refused with a namederror— resend it; updates are always made.
October 20, 2026
- Breaking (announced in v1 by exception)
POST /ext/products,PUT /ext/products/{ean},PATCH /ext/products/{ean},PATCH /windev/products/{ref}—url_slugis limited to 255 characters (maxLength: 255); beyond,422 VALIDATION_URL_SLUG_TOO_LONG. Such a slug could never be saved (the database refused it with a500): only the refusal code changes, no valid data is affected. - Fixed
POST /ext/products/batch— a product whoseurl_slugexceeds 255 characters is refused alone (error_details, named reason); the other products of the batch are saved. - Fixed
POST /ext/products,POST /ext/products/batch,POST /windev/products/sync— creating a product respects the product cap of your plan, like the app screens and imports. At the cap:403 BILLING_LICENSE_QUOTA_EXCEEDEDon the single route, or409 BILLING_LICENSE_QUOTA_BUSYif another creation was checking the cap at the same moment (retry); in a batch, only that product is refused (named reason inerror_detailsorerror). An update is never refused by the cap. See External API → Product cap.
October 15, 2026
- Breaking (announced in v1 by exception)
POST /ext/products,PUT /ext/products/{ean},PATCH /ext/products/{ean}—weightmust be lower than 10 000 000 (kg),width,heightanddepthlower than 100 000 000 (cm);NaNand infinity are refused. Out of range:422, field named. These values could never be saved (the database refused them with a500): only the refusal code changes. - Fixed
POST /ext/products/batch— an out-of-range product is refused alone (error_details, named reason); the others are saved, and a product in error no longer interrupts the following ones.
October 10, 2026
- Fixed
GET /windev/statusno longer carries the session token (BearerAuth) in the contract. The route never required authentication; the contract now says so. No behaviour changes. - Fixed the 12
/windev/*operations describe thedatapayload of their response (status, product, page of products, sync, stock and price results, categories, suppliers) instead of a free value. Objects stay open (additionalProperties): a field added later is not a breaking change. No response changes. - Added
GET /ext/statusandGET /windev/statusreturnapi_version(major version of the contract, same value as theAPI-Versionheader). Theversionfield ("1.0"/"1.1") is unchanged and frozen: readapi_version. - Added error responses of
/ext/*and/windev/*(missing or refused key, not found, validation, quota, server error) also carryAPI-Version: 1, and the deprecation headers when the operation is deprecated. No response body changes.
October 7, 2026
- Added frozen public specification of v1:
openapi-public-v1.json(20 operations,/api/v1/extand/api/v1/windev), declaring theAPIKeyHeader(X-API-Key) security scheme. Any breaking change against this file is refused before release unless announced here. - Added outgoing webhooks carry the
X-PM-Webhook-Version: 1header and awebhook_version: "1"field in the (signed) payload. Nothing else changes in the payload. See Webhooks → Payload version. - Added every response of
/ext/*and/windev/*carriesAPI-Version: 1(major version of the contract, distinct from the application version). No route changed. - Added deprecation mechanism: a deprecated operation will carry
Deprecation,SunsetandLink: <…>; rel="deprecation", with at least 180 days' notice. No operation is deprecated today.
Public reference (app API) since September 18, 2026
The public reference (/reference) follows the application (v6.40.0): 634 paths and 750 operations, against 449 paths and 548 operations on September 18. These routes are documented but carry no stability promise beyond this changelog — only /ext and /windev form the versioned contract.
- Removed (27 operations):
- Products:
GET /products/categories,POST /products/{product_id}/entities/rewrite-allandPOST /products/{product_id}/entities/{entity_id}/rewrite-description(replaced byPOST /enrichment/products/{product_id}?types=descriptions&entity_id=…);category_idis now refused byPOST /products/andPUT /products/{product_id}(422). - AI Enrichment:
POST /enrichment/web/batch/estimate,POST /enrichment/web/images/batch. - Exports:
POST /exports/schedule(singular, without platform — the schedule it announced was never executed; persisted/exports/schedulesare unchanged);POST /exports/productsandPOST /exports/suppliers(placeholders that answered “completed” without exporting anything). - Brands: the pending-brands queue (
GET /brands/pending,GET /brands/pending/{pending_id},POST /brands/pending/{pending_id}/validate,POST /brands/pending/bulk-validate) andPOST /brands/suggest-matches. - Categories: the former generic category tree (
GET /categories/web,GET /categories/{category_id}/tree|children|parents|translations,PUT /categories/{category_id}/translations), the legacy migrations (POST /categories-manager/categories/migrate-product-categories,POST /categories-manager/mappings/import-from-legacy), and the direct structure writes (POST|PUT|DELETE /categories-manager/taxonomies…,POST /categories-manager/taxonomies/{taxonomy_id}/categories,PUT|DELETE /categories-manager/categories/{category_id}) — replaced byPOST /categories-manager/structure/apercuthen/structure/appliquer, journaled and undoable. See Catalog → Categories.
- Products:
- Added (219 operations) — Products 60, Categories 50, Brands 42, AI Enrichment 35, Authentication 13, Connectors 10, Pricing 3, Exports 2, Search 2, Code2ASIN 1, Suppliers 1. Among them: brand correspondences per shop, brand proposals and GPSR manufacturer records (
/brands/correspondances…,/brands/propositions…,/brands/fabricants…), category families, structure changes and AI proposals (/categories-manager/familles…,/structure…,/propositions-ia…). They are listed in/reference; the resource pages here summarise the main ones. - Changed: write bodies of the app API refuse unknown keys with
422 REQUEST_UNKNOWN_FIELD(the detail names the keys, nothing is written) — the public families/extand/windevare not affected in v1.POST /suppliers/test-connectionwith a Google Drive source answers422 SUPPLIER_INTEGRATION_ABSENT;gdriveis refused as an import-config type (usegoogle_drive).
v6.19.x — September 18, 2026 (contract fixes)
A contract test suite now exercises every public operation against its own spec. It found the following, all fixed on September 18, 2026.
Breaking changes
503is no longer used for a missing configuration. Nine operations answered503 Service Unavailablewhen a per-instance dependency was simply not set up (Odoo connection, connector webhook secret, AI provider, price-monitoring shared key, vector search engine). They now answer409 Conflictwith anerror_codefrom the*_NOT_CONFIGUREDfamily and adetails.how_to_fix.503is reserved for a configured dependency that is momentarily unreachable, and always carriesRetry-After. Affected:POST /brands/import-from-odoo,POST /connectors/{shopify,woocommerce,bigcommerce}/webhook,POST /enrichment/products/{product_id},GET /prices/export-watchlist,POST /prices/observations,GET /search/products/{product_id}/similar. See Errors → Dependency not configured.GET /prestashop/configbehaves like the other connector config endpoints:200 {"configured": false}when nothing is configured (was404), and theconfiguredboolean is always present. (Internal module; listed here because integrations built on the old404will see a change.)template_idis an integer onDELETE /mapping-templates/code2asin/{template_id}andPOST /mapping-templates/code2asin/{template_id}/set-default. A non-numeric value now yields422(was500).
Fixed
- File downloads declare their real content type in the public spec —
text/csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/xml,image/png— instead of the FastAPI defaultapplication/json:GET /categories-manager/mappings/export-csv,GET /compliance/export,GET /compliance/gdsn/catalog,GET /compliance/dpp/{id}/qr,GET /imports/export,GET /prices/map/export,GET /products/export/csv,GET /products/export/excel. Regenerate any client you generated from the earlier spec. - Three
categories-managerread endpoints (/attributes/{attribute_id},/categories/{category_id}/attributes,/mappings/suggestions) declared an object and returned a list, which surfaced as500once the list was empty. The spec now declares the list; the payload did not change. PATCH /prices/monitored/{product_id}returns404 PRODUCT_NOT_FOUNDfor an unknown product (was500).POST /enrichment/web/price-bot/runandGET /enrichment/web/price-bot/statuswere broken in every environment by an internal import error and answered503/{"status": "unknown"}. Fixed.
v6.19.x — September 2026
This release covers what changed on the public API surface between June 19 and September 17, 2026.
Breaking changes
- Public spec now reports the real version.
GET /api/v1/openapi-public.jsonhad been frozen at"6.2.1"since March; it now reports the actual running version (6.19.x). If you compared this field to detect API changes, re-check your assumptions. - Public reference is now an allowlist (fail-closed), effective since August 19, 2026. Only these families appear on
/api/v1/openapi-public.jsonand this site: Authentication, Products (+ Brands, Categories, Suppliers, Product Tags, Search, Product Search), Imports, Exports, AI Enrichment, Connectors, Pricing, Compliance, EAN Lookup, Code2ASIN, External API, Webhooks. The WooCommerce and Magento 2 sync modules, Dolibarr, Sage X3, PrestaShop, and Odoo integrations are no longer part of the public reference — they are documented on docs.pixeepim.com. (Their inbound webhook/push endpoints under/api/v1/connectors/*remain public — see Connectors.) - Price entry update/delete moved off the per-product path.
PATCH /products/{product_id}/prices/{price_id}no longer exists. UsePATCH /prices/{price_id}and the newDELETE /prices/{price_id}instead — see Price Monitor. GET /connectors/now returns a plain array, not the{ items, meta }paginated envelope. It is not paginated./auth/registerrequires an invitation token. It completes a subscription created through an emailed, signedtoken— it is not an open self-signup endpoint. If you were probing this route for generic account creation, that never worked as a public signup flow and won't going forward.
New: Price Lists API
A full price-list system was added under /api/v1/price-lists/*: create channel-scoped price lists (with priority and validity window), add priced entries per product (with tiered min_quantity pricing), bulk-create up to 500 entries, and resolve the effective price for a product across all matching lists. See Price Monitor → Price lists.
New: Repricing
/api/v1/prices/repricing/* (10 endpoints): define rules that automatically adjust prices from conditions (competitor price, margin floor, category, supplier, product), simulate a rule (and its revenue impact) before it ever touches a live price, run repricing manually or let it run on schedule, and revert any individual automated change from its history. See Price Monitor → Repricing.
New: WinDev in the public reference
/api/v1/windev/* (12 endpoints) is now included in the public OpenAPI spec, grouped under the External API tag. It was previously a real, working surface documented only internally — it now shows up in /reference and on this site's WinDev Integration page like any other public family.
New and expanded endpoints
- Connectors — platform catalog (
GET /connectors/platforms,/platforms/{id},/platforms/{id}/field-map,/platforms/{id}/guide), an aggregatedGET /connectors/sync-statusdashboard feed, full connector CRUD (POST/PATCH/DELETE /connectors/{id}, previously read-only in this reference), sync job history (GET /connectors/{id}/jobs) and per-job status (GET /connectors/{id}/sync/jobs/{job_id}), and four inbound webhook endpoints (Shopify, WooCommerce, BigCommerce, Magento 2 push) — each HMAC/token-verified with a 24-hour Redis replay-protection window. - Price Monitor —
GET /analytics/price-sources,GET /products/{id}/stock/history,GET/POST /prices/export-watchlistand/prices/observations(B2C scraper hub ingestion), a validation queue for low-confidence competitor matches (GET /prices/validation,POST /prices/validation/{item_id}), competitor blacklisting (POST/DELETE /prices/competitors/blacklist*), per-alert history (GET /prices/alerts/{id}/history), a MAP violations export, and bulk MAP price setting. - Webhooks —
GET /webhooks/events(discover subscribable event types instead of hardcoding them),POST /webhooks/{id}/toggle,DELETE /webhooks/{id}, andpage/per_pagepagination on list and delivery-log endpoints (previouslyskip/limiton logs). - External API — API key management (
GET/POST /api-keys,GET/PATCH/DELETE /api-keys/{id},POST /api-keys/{id}/rotate) is now documented alongside/ext/*and/windev/*under the same public tag. See External API → API key management. - Authentication —
GET /auth/me,POST /auth/logout,GET /auth/csrf-token,GET /auth/test,POST /auth/login/json,GET /auth/lockout/status/{email},POST /auth/lockout/unlock/{email}are now documented. Refresh-token rotation includes reuse detection: presenting an already-rotated refresh token revokes the entire token family. Cookie-based session clients must now send a CSRF double-submit header (X-CSRF-Token, fetched from/auth/csrf-token) on mutating requests — API-key and bearer-token clients are exempt. - Errors — the error envelope itself (
error.code,error_code,type,message,details,path,request_id,timestamp) is unchanged, butmessageis now genuinely localized viaAccept-Language(French and English), andContent-Languagein the response always announces the language actually served rather than the one requested.MODULE_DISABLED(403) andLICENSE_SUSPENDED(403, read-only mode) are documented as distinct, non-enveloped error shapes — see Errors.
Rate limiting rebalanced
All 26 tiers were reviewed; most read/write/bulk limits increased 5–10× to support large catalogs (100k+ products) — e.g. READ_STANDARD and READ_ADMIN to 1000/min, WRITE_STANDARD/WRITE_CONFIG/WRITE_UPLOAD/WRITE_USER_MGMT to 100/min, all BULK_* tiers to 500/min. AI_BATCH moved the other way, tightening from 5/min to 1/hour (cost control). Three tiers not previously documented here are now covered: AUTH_REGISTER, AUTH_LOGOUT, EXPORT_SCHEDULE. See Rate Limiting for the full table.
v6.19.x — Breaking changes for integrators (June 2026)
Authentication changes (SEC-01, SEC-02, SEC-03)
-
Refresh token mechanism changed — Refresh tokens are now server-side, DB-backed (rotation + family revocation on reuse detection). The
POST /auth/refreshendpoint no longer accepts a Bearer token in the header — it reads therefresh_tokenHttpOnly cookie set at login. Clients that passed a JWT inAuthorizationto refresh must migrate to cookie-based refresh. -
Access token TTL reduced: 120 min → 15 min — Review your token handling to ensure clients refresh before expiry.
-
API key header changed:
Authorization: Bearer→X-API-Key— The API key authentication header is nowX-API-Key: pm_live_.... The previousAuthorization: Bearer pm_live_...format is no longer valid for API key authentication. -
Code2ASIN exports: JWT query param → presigned URL — Export downloads now require a presigned URL obtained via
POST /code2asin/exports/{job_id}/download-url(valid 5 min). The old?token=<jwt>query parameter is removed.
API changes
-
External API (
/api/v1/ext/*) — New M2M integration surface with 8 endpoints. Auth:X-API-Key. Scopes:ext:products:read,ext:products:write. See External API. -
WinDev Integration (
/api/v1/windev/*) — New WinDev-optimized sync surface with 12 endpoints and WinDev-friendly envelope. Auth:X-API-Key. See WinDev Integration. -
Pagination standardized — All paginated endpoints now use
page/per_pageparameters (default: 20, max: 100). Theskip/limitparameters are deprecated legacy aliases. -
Workflow Engine (
/api/v1/workflow/*) — Product publication workflow: draft → review → approved → published → archived. Completeness gate ≥ 70%. 10 endpoints.
Removals
- GraphQL/Hasura proxy removed — The
/api/v1/graphqlproxy has been removed. Headless integrations should use the External API REST surface (/api/v1/ext/*) instead.
v4.5 — May 2026
Major platform update.
- Rebranding: Products Manager → Pixee PIM. Base URL updated to
https://api.pixeepim.com/api/v1/ - Authentication: Added JWT Bearer Token support (120-minute TTL, refreshable). API keys now prefixed
pm_live_/pm_test_with granular scopes - Products: New bulk endpoints (
POST /products/bulk,PATCH /products/bulk). Products now identified by UUID; EAN remains unique index. Addedcost_price,weight,is_activefields - Imports: Jobs moved to
/imports/jobs. Added pause/resume/cancel controls. Added/previewendpoint for pre-flight validation. New automated recurring imports via/imports/automations - Exports: Format-specific endpoints (
/exports/csv/products,/exports/json/products,/exports/excel/products,/exports/zip/products). New export platforms (Google Drive, S3, MinIO, SFTP). Scheduled exports via/exports/schedules - AI Enrichment: New multi-provider job system at
/ai-enrichment/jobs. Support for OpenAI, Anthropic Claude, and configurable models. Cost tracking per job. Provider recommendation engine at/ai-services/recommendations/{use_case} - Price Monitor: New endpoint structure at
/prices/products/{id}. Added competitor price management, price history, stats, and best-price endpoints. Margin tracking - EAN Lookup: Changed from
GET /ean-lookup/{ean}toPOST /ean-lookup/lookupwith provider selection. Batch limit raised to 500 EANs. Added cache stats and pending queue management - Webhooks: New events:
import.started,supplier.created,supplier.updated,ean.resolved. Added delivery logs with per-entry retry (POST /webhooks/{id}/logs/{log_id}/retry) - Code2ASIN: Full job lifecycle: create → start → pause/resume/cancel. Added results with confidence scoring, manual accept/reject, global statistics, and CSV/JSON export
- Rate Limiting: Replaced plan-based limits with per-tier system (AUTH, READ_STANDARD, WRITE_STANDARD, EXPORT_STANDARD, etc.) backed by Redis
- Pagination: Standardised to
skip/limitparameters. Response wrapper changed fromdatatoitems.metaobject enriched withhas_nextandhas_previous - Errors: Response format updated —
detailfield replaceserror/message. Added202 Acceptedfor async operations,423 Lockedfor account lockout
v1.0 — March 2024
Initial public release.
- Products CRUD API (
GET,POST,PATCH,DELETE) - Bulk import via CSV and JSON (
/imports) - Export catalog to CSV/Excel (
/exports) - AI enrichment for descriptions and attributes (
/enrichment) - Connector sync for Shopify, WooCommerce, PrestaShop (
/connectors) - EAN lookup and validation (
/ean-lookup) - Price monitoring and alerts (
/price-monitor) - Code2ASIN mapping (
/code2asin) - Compliance & Digital Product Passport endpoints (
/compliance) - Webhook support for real-time event notifications
- API key authentication
API versioning
The version is part of the base URL (https://api.pixeepim.com/api/v1/). The public contract is the set of families called with an API key — /api/v1/ext/* and /api/v1/windev/*; its frozen specification is openapi-public-v1.json. The other /api/v1 routes are the API of the app screens: documented in /reference, without a stability promise beyond this changelog.
API-Version: 1is set on every response of the public families, successes and errors. It is the major version of the contract, independent of the application version (info.versionof the public reference).- One major version = one prefix. A breaking change opens
/api/v2/extnext to/api/v1/ext; both live together for the whole deprecation notice of v1. - Not breaking (no version change): adding a route, a response field, an optional parameter, an enum value in a response, or a more precise error code under the same status. Your client must ignore fields it does not know.
- Breaking: removing or renaming a route, a field or a parameter; making an optional parameter required; changing a field's type or meaning; changing a success HTTP status; tightening validation on an input that was accepted so far; changing a unit or a format (dates, decimals).
Deprecation
- A deprecated operation carries
Deprecation(RFC 9745),Sunset(RFC 8594) andLink: <https://apidoc.pixeepim.com/changelog>; rel="deprecation"on its responses. - Minimum notice: 180 days, for every client, between the announcement and the removal. When an Enterprise contract provides for it, the notice is 12 months; the
Sunsetdate is then set to honour the longest contractual notice among the clients using the operation. - Every deprecation is announced on this page the day it is decided. No operation is deprecated today.
Outgoing webhooks follow the same rules, with their own version (X-PM-Webhook-Version) — see Webhooks → Payload version.