Cleanup menu

http
POST /v1/cleanup

Removes synced items that are not in the lists you send — the inverse of sync. For each array you provide, you pass the externalIds to keep; everything else that was synced from your system is deactivated or deleted:

Array providedWhat happens to items NOT in the list
productExternalIdsProducts are deactivated (menuVisible: false) — recoverable by re-syncing
categoryExternalIdsCategories are deleted; their products are kept and unlinked (no category)
ingredientExternalIdsIngredients are deleted, including from product compositions and modifier options

Two important scoping rules:

  • Only items that have an externalId (i.e. came through the API) are affected. Items created manually in the DuckHub app are never touched.
  • Arrays you omit are left completely alone — send only the entity types you want to clean.

Sending no arrays at all is a no-op (success: true with a warning).

Deletes are permanent; empty lists need force

Category and ingredient deletion cannot be undone. An empty array means "keep nothing" — it would wipe every synced item of that type, so the API rejects it with 400 unless you also send force: true. Deactivated products are the one soft case: re-sync them to restore.

Request body#

FieldTypeRequiredMeaning
productExternalIdsstring[]NoProducts to keep visible
categoryExternalIdsstring[]NoCategories to keep
ingredientExternalIdsstring[]NoIngredients to keep
forcebooleanNoDefault false; must be true when any provided array is empty

Example#

Typical full-sync flow — after pushing the current catalog with sync, clean up anything your POS no longer has, then publish:

bash
curl -X POST https://api.duck-hub.com/v1/cleanup \
  -H "Authorization: Bearer dk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "productExternalIds": ["prod-margherita", "prod-pepperoni"],
    "categoryExternalIds": ["cat-pizza"],
    "ingredientExternalIds": ["ing-mozzarella", "ing-olives"]
  }'

Response#

201 Created:

json
{
  "success": true,
  "deactivatedProducts": 3,
  "deletedCategories": 1,
  "deletedIngredients": 2,
  "warnings": []
}
FieldMeaning
deactivatedProductsSynced products hidden from the menu (menuVisible: false)
deletedCategoriesSynced categories removed (products unlinked first)
deletedIngredientsSynced ingredients removed everywhere
warningsNon-fatal notes

Cleanup changes the draft menu — run POST /v1/publish afterwards to update what guests see.

Errors#

  • 400 Passing an empty array would affect ALL items. Set force: true to confirm this action. — an empty array without force
  • 401 — see Authentication