WinDev Integration

Synchronise your WinDev applications with Pixee PIM — push products in batch, update stock and prices, and pull the full catalog with a response format designed for WinDev's HTTP calls.

The WinDev API (/api/v1/windev/*) uses a simplified JSON envelope that maps cleanly to WinDev variables. Products are identified by reference (internal WinDev key) or EAN, and all batch endpoints accept up to 5 000 items per call.


Overview

Base URLhttps://api.pixeepim.com/api/v1/windev
AuthX-API-Key header
Read scopewindev:read
Write scopewindev:write
Sync scopewindev:sync
Stock / price batch5 000 items max
Product sync batch1 000 items max
Contract versionAPI-Version: 1 on every response

Create WinDev API keys in Settings → API Keys and select the appropriate scopes. A single key can carry multiple scopes.


Authentication

All endpoints except GET /status require an API key in the X-API-Key header. GET /status declares no security requirement in the contract (since October 10, 2026 it is no longer marked with the session token BearerAuth); it never required authentication.

Authenticated request

curl https://api.pixeepim.com/api/v1/windev/products \
  -H "X-API-Key: pm_live_abc123..."

Scopes

ScopeGrants access to
windev:readGET /products, GET /products/since/{ts}, GET /products/{ref}, GET /categories, GET /suppliers
windev:writePATCH /products/{ref}, POST /products/{ref}/activate, POST /products/{ref}/deactivate, POST /stock/update, POST /prices/update
windev:syncPOST /products/sync

Response format

Every response uses the same WinDev-friendly envelope:

Success

{
  "success": true,
  "code": 200,
  "message": "125 produits trouvés",
  "data": [...],
  "count": 125,
  "page": 1,
  "pages": 10,
  "total": 125
}

success and code map directly to WinDev boolean and integer variables. count reflects the number of items in data for that page; total is the full dataset size across all pages.

Since October 10, 2026 the contract describes the data payload of each of the 12 operations (status, product, page of products, sync, stock and price results, categories, suppliers) instead of a free value. The objects stay open (additionalProperties): a field added later is not a breaking change. No response changed — same keys, same values; a field that was absent (error, warning…) stays absent.

Errors (401, 403, 404, 409, 422, 500) use the platform's standard error envelope, not the WinDev envelope:

Error

{
  "error": {
    "code": 404,
    "error_code": "PRODUCT_NOT_FOUND",
    "type": "not_found",
    "message": "…",
    "details": { "reference": "REF-001" },
    "path": "/api/v1/windev/products/REF-001",
    "request_id": "abc-123",
    "timestamp": "2026-10-21T10:00:00Z"
  }
}

In batch endpoints (/products/sync, /stock/update, /prices/update) a failure on one line does not fail the call: it is reported on that line of data (status: "error" or "not_found", with error, and error_code for a named refusal — see Named refusals).


Unknown fields

Writes tolerate keys they do not know (nothing is refused, nothing is written for them) and list them, sorted, in the envelope's champs_ignores (empty list when there are none). On a batch (/products/sync, /stock/update, /prices/update), champs_ignores is the union for all lines and champs_ignores_par_fiche gives the detail: [{ "index": 0, "ean": "…", "reference": "…", "champs": ["…"] }] (index from 0; reference on /products/sync only). Reads carry both keys as null. Unknown keys stay tolerated for the whole life of contract v1.


Named refusals

These refuse the request on single-product routes (409 / 422, standard error envelope) and refuse only the line in a batch (status: "error" + error_code, the other lines go on). Nothing is written for a refused line.

error_codeStatus (single routes)When
WINDEV_PRODUCT_IN_TRASH409The product is in the trash (and no live product carries this reference). Restore it, then resend. A product in the trash is no longer returned by the lists, the delta or total; GET /products/{ref} of a product that exists only in the trash answers this 409
WINDEV_REFERENCE_AMBIGUOUS409The EAN or manufacturer reference designates several live products: none is chosen. details: reference, champ (ean or manufacturer_reference), produits (up to 10 conflicting ids). Fix the duplicate in Pixee PIM, then resend
WINDEV_PRICE_TTC_ONLY422 (PATCH)price_ttc sent without price_ht — see Prices

Prices (HT and TTC)

Since October 26, 2026, price_ht is the selling price excl. VAT of the product (before: it was stored as the purchase cost, and price_ttc as the selling price). price_ttc is never stored: sent alone, the line is refused (WINDEV_PRICE_TTC_ONLY); sent with price_ht, it is cited in champs_ignores. WinDev no longer writes the purchase cost. In reads, price_ht is the selling price excl. VAT and price_ttc is computed: price_ht × (1 + tax_rate / 100), rounded to the cent, null without tax_rate.


Versioning and product cap

  • API-Version: 1 is set on every /windev response, errors included. GET /status returns the same value in data.api_version; data.version ("1.1") is a frozen historical value — read api_version. Deprecation headers and notice: see External API → Versioning. The frozen specification of both families is openapi-public-v1.json.
  • Product cap. Since October 20, 2026, a product created by POST /products/sync respects the product cap of your plan (see External API → Product cap). At the cap, only that product is refused, with a named reason in its error; the other products of the call are processed, and updates are always made.
  • The wait for the cap check is bounded to 5 seconds for the whole call (since October 21, 2026; previously up to 5 seconds per creation). Beyond that, a creation whose cap cannot be checked right away is refused with a named error (another creation was checking the cap at the same time) — resend it.

GET/windev/status

Status

Public health check — no authentication required. Returns api_version (major version of the public contract, same value as the API-Version header), the frozen historical version, and the list of available endpoints. Use this to verify connectivity from WinDev before running a sync.

Request

GET
/windev/status
curl https://api.pixeepim.com/api/v1/windev/status

Response

{
  "success": true,
  "code": 200,
  "message": "WinDev API opérationnelle",
  "data": {
    "api": "ProductsManager WinDev API",
    "version": "1.1",
    "api_version": "1",
    "timestamp": "2026-06-19T10:00:00Z",
    "endpoints": [
      "GET  /api/v1/windev/status",
      "GET  /api/v1/windev/products",
      "POST /api/v1/windev/products/sync",
      "GET  /api/v1/windev/products/since/{timestamp}",
      "PATCH /api/v1/windev/products/{ref}",
      "GET  /api/v1/windev/products/{ref}",
      "POST /api/v1/windev/stock/update",
      "POST /api/v1/windev/prices/update",
      "GET  /api/v1/windev/categories",
      "GET  /api/v1/windev/suppliers"
    ]
  },
  "count": 1
}

GET/windev/products

List products

Returns a paginated product list. Use for the initial full sync when no reference timestamp exists yet.

Requires windev:read.

Query parameters

  • Name
    page
    Type
    integer
    Description

    Page number, starting at 1 (default: 1).

  • Name
    limit
    Type
    integer
    Description

    Items per page, max 500 (default: 100).

  • Name
    search
    Type
    string
    Description

    Free-text search across product name and reference.

  • Name
    ean
    Type
    string
    Description

    Exact EAN filter.

  • Name
    active_only
    Type
    boolean
    Description

    Return only active products (default: true).

Request

GET
/windev/products
curl "https://api.pixeepim.com/api/v1/windev/products?page=1&limit=100&active_only=true" \
  -H "X-API-Key: pm_live_abc123..."

Response

{
  "success": true,
  "code": 200,
  "message": "1250 produits trouvés",
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "ean": "3760000000001",
      "manufacturer_reference": "012-1146",
      "name": "Support TV mural fixe",
      "brand": "KIMEX",
      "price_ht": null,
      "price_ttc": null,
      "stock": 0,
      "is_active": true,
      "updated_at": "2026-06-19T09:30:00Z"
    }
  ],
  "count": 100,
  "page": 1,
  "pages": 13,
  "total": 1250
}

POST/windev/products/sync

Sync products

Push up to 1 000 products from WinDev to Pixee PIM in a single call. Each product is matched first by EAN (if provided), then by reference. On match: update; no match: create — a creation counts against your plan's product cap. Only a created product is activated automatically: an update no longer reactivates a deactivated product.

Each line of data reports ref, ean, id (null on error) and status (created, updated or error), plus error (and error_code for a named refusal) when status is error, warning when the supplier code is unknown, brand_unresolved (inconnue, ambigue or inactive) when brand matched no brand of your directory, and category_unresolved (inconnue or ambigue) when category matched no existing category. An unexpected error on one product refuses only that product: its error says it was not saved, that the others are processed each on its own, and gives a reference to pass on to support — never the technical error text.

Requires windev:sync.

Body parameters

Pass a JSON array directly (not wrapped in an object key):

  • Name
    reference
    Type
    string
    Description

    WinDev internal reference — used as fallback key when no EAN is provided.

  • Name
    ean
    Type
    string
    Description

    EAN/GTIN. Preferred matching key.

  • Name
    name
    Type
    string
    Description

    Product name.

  • Name
    brand
    Type
    string
    Description

    Brand name, matched against your brand directory (exact name ignoring case and accents, alias, or name without legal suffix). Unmatched: the name is kept without an attached brand — no brand is created. "" detaches the brand.

  • Name
    price_ht
    Type
    number
    Description

    Selling price excl. VAT (EUR).

  • Name
    price_ttc
    Type
    number
    Description

    Never stored — alone, the line is refused (WINDEV_PRICE_TTC_ONLY); with price_ht, cited in champs_ignores.

  • Name
    stock
    Type
    integer
    Description

    Stock quantity.

  • Name
    weight
    Type
    number
    Description

    Weight in kg.

  • Name
    supplier_code
    Type
    string
    Description

    Supplier code for stock tracking.

See the full schema in Sync product fields below.

Request

POST
/windev/products/sync
curl -X POST https://api.pixeepim.com/api/v1/windev/products/sync \
  -H "X-API-Key: pm_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '[
    {
      "reference": "ART-001",
      "ean": "3760000000001",
      "name": "Support TV mural fixe",
      "brand": "KIMEX",
      "price_ht": 18.50,
      "tax_rate": 20,
      "stock": 42,
      "weight": 1.5
    },
    {
      "reference": "ART-002",
      "name": "Câble HDMI 2m",
      "price_ht": 5.00,
      "stock": 150
    }
  ]'

Response

{
  "success": true,
  "code": 200,
  "message": "Sync terminé : 1 créés, 1 mis à jour, 0 erreurs",
  "data": [
    { "ref": "ART-001", "ean": "3760000000001", "status": "updated", "id": "550e8400-..." },
    { "ref": "ART-002", "ean": null, "status": "created", "id": "661f9511-..." }
  ],
  "count": 2,
  "champs_ignores": [],
  "champs_ignores_par_fiche": []
}

Sync product fields

FieldTypeNotes
referencestringRequired — WinDev internal key
eanstringEAN/GTIN (preferred match key)
namestringRequired — product name
brandstringBrand name, matched against the brand directory, never created (brand_unresolved otherwise)
short_descriptionstring
descriptionstring
price_htnumberSelling price excl. VAT in EUR
price_ttcnumberNever stored — see Prices
stockinteger≥ 0
supplier_codestring
weightnumberkg
width / height / depthnumbercm
unit_of_measurestring
package_weightintegergrams
package_quantityinteger≥ 1
upc / gtin / external_idstring
min_order_quantityinteger≥ 1 — the product's minimum sale quantity (not a supplier's minimum purchase)
lead_time_daysinteger≥ 0 — the product's lead time (not a supplier's)
hs_codestringCustoms tariff code
country_of_originstringISO 3166-1 alpha-2 (e.g. FR)
dangerous_goodsboolean
color / size / materialstring
tax_ratenumber0–100
warranty_durationintegermonths
categorystringCategory name (or id): attached to the existing category with that name (case, accents and punctuation ignored), filed in the Category Manager. No category is created; unknown or ambiguous → the product's category is untouched and the line carries category_unresolved

GET/windev/products/since/{timestamp}

Products since timestamp

Returns products created or updated since the given Unix timestamp. Designed for incremental sync — store the timestamp after each sync and pass it as since on the next call.

Requires windev:read.

Path parameters

  • Name
    timestamp
    Type
    integer
    Description

    Unix timestamp in seconds (e.g. 1750291200 for 2026-06-19 00:00:00 UTC).

Query parameters

  • Name
    page
    Type
    integer
    Description

    Page number (default: 1).

  • Name
    limit
    Type
    integer
    Description

    Items per page, max 500 (default: 100).

Request

GET
/windev/products/since/{timestamp}
curl "https://api.pixeepim.com/api/v1/windev/products/since/1750291200?limit=200" \
  -H "X-API-Key: pm_live_abc123..."

WinDev pseudo-code

// Store last sync timestamp in a global variable or DB
nLastSync est un entier = GlbLastSyncTimestamp

sURL est une chaîne = ...
    "https://api.pixeepim.com/api/v1/windev/products/since/" + nLastSync

HTTPRequête(sURL, httpGET, sRéponse, "", "X-API-Key: " + sAPIKey)

// Parse JSON response
// GlbLastSyncTimestamp = DateSystèmeVersTimestamp(DateSystème())

GET/windev/products/{ref}

Get a product

Retrieves a single product by its WinDev reference or EAN. The ref path parameter is tried first as a manufacturer_reference, then as an EAN.

Requires windev:read.

Path parameters

  • Name
    ref
    Type
    string
    Description

    WinDev reference or EAN of the product to retrieve.

Request

GET
/windev/products/{ref}
curl https://api.pixeepim.com/api/v1/windev/products/ART-001 \
  -H "X-API-Key: pm_live_abc123..."

Response

{
  "success": true,
  "code": 200,
  "message": "Produit trouvé",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "ean": "3760000000001",
    "manufacturer_reference": "ART-001",
    "name": "Support TV mural fixe",
    "brand": "KIMEX",
    "is_active": true,
    "updated_at": "2026-06-19T09:30:00Z"
  },
  "count": 1
}

PATCH/windev/products/{ref}

Update a product

Partially updates a product identified by WinDev reference or EAN. Only fields included in the payload are modified — omitted fields are left unchanged.

Requires windev:write.

Fires a product.updated webhook event on success.

url_slug is limited to 255 characters (since October 20, 2026): beyond, the request is refused with 422 VALIDATION_URL_SLUG_TOO_LONG. An update is never refused by the product cap. price_ht is the selling price excl. VAT; price_ttc alone → 422 WINDEV_PRICE_TTC_ONLY (see Prices). A product in the trash → 409 WINDEV_PRODUCT_IN_TRASH; an ambiguous reference → 409 WINDEV_REFERENCE_AMBIGUOUS.

Path parameters

  • Name
    ref
    Type
    string
    Description

    WinDev reference or EAN of the product to update.

The body accepts any writable product field. Fields include everything from POST /products/sync plus extended attributes:

  • Identifiers: name, ean, asin, upc, gtin, external_id, reference, url_slug
  • Content: brand, description, short_description, promotional_text
  • Status: is_active, lifecycle_status, discontinued, end_of_life_date
  • Dimensions: weight, width, height, depth, unit_of_measure
  • Packaging: package_length, package_width, package_height, package_weight, package_quantity
  • B2B: min_order_quantity, max_order_quantity, order_increment, lead_time_days, backorder_allowed, preorder_available, requires_quote, is_b2b_only
  • Compliance: hs_code, country_of_origin, dangerous_goods, dangerous_goods_class, reach_compliant, rohs_compliant, ce_marked, weee_category
  • Energy: energy_class, recyclable, eco_friendly, carbon_footprint_kg
  • Warranty: warranty_duration, warranty_type, return_policy_days, return_allowed
  • Physical: color, color_secondary, size, material, finish, style, pattern
  • JSON: technical_specs, compatibility
  • Inline: price_ht (selling price excl. VAT), stock, supplier_code, tax_rate

Request

PATCH
/windev/products/{ref}
curl -X PATCH https://api.pixeepim.com/api/v1/windev/products/ART-001 \
  -H "X-API-Key: pm_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "price_ht": 19.99,
    "stock": 38,
    "is_active": true,
    "warranty_duration": 24,
    "ce_marked": true
  }'

Response

{
  "success": true,
  "code": 200,
  "message": "Produit mis à jour",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "ean": "3760000000001",
    "name": "Support TV mural fixe",
    "is_active": true,
    "updated_at": "2026-06-19T10:05:00Z"
  },
  "count": 1
}

POST/windev/products/{ref}/activate

Activate / Deactivate

Convenience endpoints to toggle product visibility without a full PATCH body.

  • POST /products/{ref}/activate → sets is_active = true, status = active
  • POST /products/{ref}/deactivate → sets is_active = false, status = inactive

Both require windev:write and fire a product.updated webhook event.

Path parameters

  • Name
    ref
    Type
    string
    Description

    WinDev reference or EAN of the product.

Activate

POST
/windev/products/{ref}/activate
curl -X POST https://api.pixeepim.com/api/v1/windev/products/ART-001/activate \
  -H "X-API-Key: pm_live_abc123..."

Response

{
  "success": true,
  "code": 200,
  "message": "Produit activé",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "is_active": true,
    "status": "active"
  },
  "count": 1
}

POST/windev/stock/update

Update stock

Updates stock quantities in batch — up to 5 000 items per call. Products are matched by EAN.

If supplier_code is provided, the stock is updated on the supplier_products record for that supplier. Otherwise, the generic product_stocks entry is updated.

Fires a stock.updated webhook event (first 50 EANs included in payload).

Each line of data reports ean, updated (boolean) and status — updated, not_found or error — with error when the status is not_found or error, and error_code for a named refusal.

Requires windev:write.

Body parameters

Pass a JSON array directly:

  • Name
    ean
    Type
    string
    Description

    EAN of the product.

  • Name
    stock
    Type
    integer
    Description

    New stock quantity (≥ 0).

  • Name
    supplier_code
    Type
    string
    Description

    Supplier code — routes the update to the supplier-level stock record.

Request

POST
/windev/stock/update
curl -X POST https://api.pixeepim.com/api/v1/windev/stock/update \
  -H "X-API-Key: pm_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '[
    { "ean": "3760000000001", "stock": 42, "supplier_code": "KIMEX" },
    { "ean": "3760000000002", "stock": 0 },
    { "ean": "3760000000003", "stock": 15, "supplier_code": "KIMEX" }
  ]'

Response

{
  "success": true,
  "code": 200,
  "message": "Stocks : 2 mis à jour, 1 introuvables, 0 erreurs",
  "data": [
    { "ean": "3760000000001", "updated": true, "status": "updated" },
    { "ean": "3760000000002", "updated": false, "status": "not_found", "error": "…" },
    { "ean": "3760000000003", "updated": true, "status": "updated" }
  ],
  "count": 3
}

POST/windev/prices/update

Update prices

Updates product prices in batch — up to 5 000 items per call. Products are matched by EAN.

price_ht is stored as the selling price excl. VAT (since October 26, 2026; before, it was stored as cost). price_ttc is never stored: a line with price_ttc only is refused (status: "error", error_code: "WINDEV_PRICE_TTC_ONLY"); with price_ht, it is cited in champs_ignores.

Fires a price.updated webhook event (first 50 EANs included in payload).

Each line of data reports ean, updated and status (updated, not_found or error), the recorded price_ht when updated, and error (plus error_code for a named refusal) otherwise.

Requires windev:write.

Body parameters

  • Name
    ean
    Type
    string
    Description

    EAN of the product.

  • Name
    price_ht
    Type
    number
    Description

    Selling price excl. VAT in EUR (≥ 0) — the only price stored.

  • Name
    price_ttc
    Type
    number
    Description

    Never stored — alone, the line is refused (WINDEV_PRICE_TTC_ONLY).

Request

POST
/windev/prices/update
curl -X POST https://api.pixeepim.com/api/v1/windev/prices/update \
  -H "X-API-Key: pm_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '[
    { "ean": "3760000000001", "price_ht": 18.50 },
    { "ean": "3760000000002", "price_ttc": 9.99 }
  ]'

Response

{
  "success": true,
  "code": 200,
  "message": "Prix : 1 mis à jour, 0 introuvables, 1 erreurs",
  "data": [
    { "ean": "3760000000001", "updated": true, "status": "updated", "price_ht": 18.5 },
    { "ean": "3760000000002", "updated": false, "status": "error", "error_code": "WINDEV_PRICE_TTC_ONLY", "error": "…" }
  ],
  "count": 2,
  "champs_ignores": [],
  "champs_ignores_par_fiche": []
}

GET/windev/categories

Categories

Item shape kept in contract v1: id, name, slug, parent_id, level, path, is_active, product_count.

Requires windev:read.

Request

GET
/windev/categories
curl https://api.pixeepim.com/api/v1/windev/categories \
  -H "X-API-Key: pm_live_abc123..."

Response

{
  "success": true,
  "code": 200,
  "message": "0 catégories",
  "data": [],
  "count": 0
}

GET/windev/suppliers

Suppliers

Returns the list of active suppliers sorted by name. Use supplier_code values when pushing products via POST /products/sync or POST /stock/update.

Requires windev:read.

Request

GET
/windev/suppliers
curl https://api.pixeepim.com/api/v1/windev/suppliers \
  -H "X-API-Key: pm_live_abc123..."

Response

{
  "success": true,
  "code": 200,
  "message": "8 fournisseurs",
  "data": [
    {
      "id": "c3d4e5f6-...",
      "name": "KIMEX International",
      "code": "KIMEX",
      "is_active": true,
      "contact_email": null,
      "contact_phone": null,
      "country": "FR"
    }
  ],
  "count": 8
}

Was this page helpful?