Skip to content

Outbound Endpoints (Middleware -> Webshop)

The webshop polls these to retrieve changed records.

GET /api/v1/updated-products

Returns products with pending changes.

Parameter Type Default Description
since ISO8601 (none) Only return records updated after this timestamp
limit int 50 Max records (up to 500)
offset int 0 Pagination offset

Response:

{
  "payload": [
    {
      "id": 1,
      "externalId": "PROD-001",
      "odooId": 12345,
      "isNew": false,
      "changedFields": ["name", "description"],
      "context": "daily_sync",
      "data": { "name": "Widget A", "description": "Updated" },
      "updatedAt": "2026-02-24T10:30:00Z"
    }
  ],
  "meta": { "total": 5, "limit": 50, "offset": 0 }
}

GET /api/v1/updated-partners

Same structure as products, with additional parentExternalId, parentId, and type fields.

GET /api/v1/updated-partners/{id}/hierarchy

Returns the full hierarchy tree for a partner.

GET /api/v1/updated-sale-orders

Same structure, with additional direction filter parameter.

GET /api/v1/pricelists/updated

Returns only price items where the price actually changed. This is the key endpoint that solves the 128k update explosion.

Response:

{
  "payload": [
    {
      "id": 1,
      "pricelistExternalId": "PL-001",
      "pricelistName": "Standard",
      "productExternalId": "PROD-001",
      "price": 29.99,
      "previousPrice": 24.99,
      "isNew": false,
      "startDate": "2026-01-01",
      "endDate": "2026-12-31",
      "updatedAt": "2026-02-24T10:30:00Z"
    }
  ],
  "meta": { "total": 3, "limit": 50, "offset": 0 }
}

GET /api/v1/pricelists

Returns distinct pricelist IDs and names.

GET /api/v1/pricelists/{pricelistId}/items

All items for a specific pricelist (full sync, not just changes).

GET /api/v1/stocks/changed

Only stock entries where quantity changed (delta query).

GET /api/v1/stocks/by-supplier/{supplierId}

All stock for a specific supplier.

GET /api/v1/stocks/by-product/{productId}

All suppliers' stock for a specific product.

GET /api/v1/stocks/lookup?supplier_id=...&product_id=...

Look up a specific stock entry.

GET /api/v1/purchase-orders/updated

Updated purchase orders with changedFields.

GET /api/v1/purchase-orders/{id}

Purchase order details including lines.

Acknowledgement Endpoints

After the webshop processes a record, it acknowledges it:

DELETE /api/v1/updated-products/{id}
DELETE /api/v1/updated-partners/{id}
DELETE /api/v1/updated-sale-orders/{id}

Batch acknowledgement:

POST /api/v1/updated-products/batch-delete
POST /api/v1/updated-partners/batch-delete
POST /api/v1/updated-sale-orders/batch-delete
POST /api/v1/pricelists/updated/batch-delete
POST /api/v1/stocks/changed/batch-delete
POST /api/v1/purchase-orders/updated/batch-delete

Request body for batch: { "ids": [1, 2, 3] }

Alternative ACK with details:

POST /api/v1/updates/{entityType}/{id}/ack

This also auto-resolves any related open sync failures.