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:
This also auto-resolves any related open sync failures.