Import the menu
Send the menu built in your POS: sections, add-ons and items with option groups. Every line is matched by your external_id: new ones are created, changed ones updated, the rest counted as unchanged. One invalid line is reported in errors and does not stop the others. Deals are never changed. Up to 1000 lines per list per call; bigger menus go in parts with mode=partial.
curl --request PUT \
--url https://staging2.xfaster.net/api/partner/v1/menu \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"mode": "full",
"categories": [
{
"external_id": "CAT-PIZZA",
"name": {
"he": "פיצות",
"ar": "بيتزا",
"en": "Pizzas"
},
"position": 1
},
{
"external_id": "CAT-DRINKS",
"name": "שתייה",
"position": 2
}
],
"addons": [
{
"external_id": "ADD-OLIVES",
"name": {
"he": "זיתים",
"en": "Olives"
},
"price": 400,
"available": true
}
],
"items": [
{
"external_id": "PIZZA-MARG",
"category_external_id": "CAT-PIZZA",
"name": {
"he": "מרגריטה",
"ar": "مارغريتا",
"en": "Margherita"
},
"description": {
"he": "רוטב עגבניות ומוצרלה"
},
"price": 5200,
"available": true,
"option_groups": [
{
"name": "גודל",
"type": "single",
"required": true,
"min": 1,
"max": 1,
"options": [
{
"name": "אישית",
"price": 0
},
{
"name": "משפחתית",
"price": 1500
}
]
}
],
"addon_external_ids": [
"ADD-OLIVES"
]
},
{
"external_id": "COLA-330",
"category_external_id": "CAT-DRINKS",
"name": "קוקה קולה 330 מ\"ל",
"price": 900,
"available": true
}
]
}
'const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
mode: 'full',
categories: [
{
external_id: 'CAT-PIZZA',
name: {he: 'פיצות', ar: 'بيتزا', en: 'Pizzas'},
position: 1
},
{external_id: 'CAT-DRINKS', name: 'שתייה', position: 2}
],
addons: [
{
external_id: 'ADD-OLIVES',
name: {he: 'זיתים', en: 'Olives'},
price: 400,
available: true
}
],
items: [
{
external_id: 'PIZZA-MARG',
category_external_id: 'CAT-PIZZA',
name: {he: 'מרגריטה', ar: 'مارغريتا', en: 'Margherita'},
description: {he: 'רוטב עגבניות ומוצרלה'},
price: 5200,
available: true,
option_groups: [
{
name: 'גודל',
type: 'single',
required: true,
min: 1,
max: 1,
options: [{name: 'אישית', price: 0}, {name: 'משפחתית', price: 1500}]
}
],
addon_external_ids: ['ADD-OLIVES']
},
{
external_id: 'COLA-330',
category_external_id: 'CAT-DRINKS',
name: 'קוקה קולה 330 מ"ל',
price: 900,
available: true
}
]
})
};
fetch('https://staging2.xfaster.net/api/partner/v1/menu', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://staging2.xfaster.net/api/partner/v1/menu"
payload = {
"mode": "full",
"categories": [
{
"external_id": "CAT-PIZZA",
"name": {
"he": "פיצות",
"ar": "بيتزا",
"en": "Pizzas"
},
"position": 1
},
{
"external_id": "CAT-DRINKS",
"name": "שתייה",
"position": 2
}
],
"addons": [
{
"external_id": "ADD-OLIVES",
"name": {
"he": "זיתים",
"en": "Olives"
},
"price": 400,
"available": True
}
],
"items": [
{
"external_id": "PIZZA-MARG",
"category_external_id": "CAT-PIZZA",
"name": {
"he": "מרגריטה",
"ar": "مارغريتا",
"en": "Margherita"
},
"description": { "he": "רוטב עגבניות ומוצרלה" },
"price": 5200,
"available": True,
"option_groups": [
{
"name": "גודל",
"type": "single",
"required": True,
"min": 1,
"max": 1,
"options": [
{
"name": "אישית",
"price": 0
},
{
"name": "משפחתית",
"price": 1500
}
]
}
],
"addon_external_ids": ["ADD-OLIVES"]
},
{
"external_id": "COLA-330",
"category_external_id": "CAT-DRINKS",
"name": "קוקה קולה 330 מ\"ל",
"price": 900,
"available": True
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://staging2.xfaster.net/api/partner/v1/menu",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'mode' => 'full',
'categories' => [
[
'external_id' => 'CAT-PIZZA',
'name' => [
'he' => 'פיצות',
'ar' => 'بيتزا',
'en' => 'Pizzas'
],
'position' => 1
],
[
'external_id' => 'CAT-DRINKS',
'name' => 'שתייה',
'position' => 2
]
],
'addons' => [
[
'external_id' => 'ADD-OLIVES',
'name' => [
'he' => 'זיתים',
'en' => 'Olives'
],
'price' => 400,
'available' => true
]
],
'items' => [
[
'external_id' => 'PIZZA-MARG',
'category_external_id' => 'CAT-PIZZA',
'name' => [
'he' => 'מרגריטה',
'ar' => 'مارغريتا',
'en' => 'Margherita'
],
'description' => [
'he' => 'רוטב עגבניות ומוצרלה'
],
'price' => 5200,
'available' => true,
'option_groups' => [
[
'name' => 'גודל',
'type' => 'single',
'required' => true,
'min' => 1,
'max' => 1,
'options' => [
[
'name' => 'אישית',
'price' => 0
],
[
'name' => 'משפחתית',
'price' => 1500
]
]
]
],
'addon_external_ids' => [
'ADD-OLIVES'
]
],
[
'external_id' => 'COLA-330',
'category_external_id' => 'CAT-DRINKS',
'name' => 'קוקה קולה 330 מ"ל',
'price' => 900,
'available' => true
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"dry_run": false,
"created": {
"categories": 2,
"items": 1,
"addons": 1
},
"updated": {
"categories": 0,
"items": 1,
"addons": 0
},
"switched_off": {
"categories": 0,
"items": 3,
"addons": 0
},
"unchanged": 0,
"errors": [
{
"kind": "item",
"external_id": "WINGS-6",
"code": "category_not_found",
"message": "No section with this category_external_id (send it in categories)."
}
]
}external_id.
How lines are matched
| Line | Matched by | If not found |
|---|---|---|
Section (categories) | external_id, else a section of the store with exactly the same name | Created |
Add-on (addons) | external_id | Created (needs price) |
Item (items) | external_id, else (markets) the item with the same barcode | Created (needs name and price) |
- A line that is already up to date counts as
unchangedand changes nothing. - A new item follows
available(on when you leave it out). - A plain text
nameis the Hebrew name. Send{"he", "ar", "en"}for more languages. Empty texts never erase a translation. option_groupsandaddon_external_idsreplace the item’s groups and add-ons. Option groups are for restaurants only.- Deals are never changed from the POS. They follow the items inside them.
Full or partial
mode: "partial"(default) changes only the lines you send.mode: "full"also switches off your mapped items, add-ons and sections that are missing from the call. Nothing is deleted, and XFaster items you never mapped are left alone. A full menu with no items is refused.- Up to 1000 lines per list in one call. A bigger menu goes in parts with
mode: "partial".
"dry_run": true first. You get the same counts and errors, and nothing changes.Errors
The answer always lists the lines that were skipped inerrors, with a code and a message. The other lines were saved. Fix the line and send it again: re-sending the same menu is safe.
Authorizations
The store's API key (xfp_test_… on the sandbox, xfp_live_… on live). XFaster creates it and shows it once. An integrator key (one key for a POS company) also sends X-XFaster-Store.
Headers
Any unique string. Repeating a request with the same key within 24 hours returns the first answer instead of acting twice.
"5f0c3d1e-8b6a-4e1f-9c2d-7a1b0e4f6d21"
Body
partial: only the lines you send. full: also switches OFF your mapped items, add-ons and sections that are missing (never deletes; XFaster items you never mapped are left alone).
partial, full Check everything and return the counts, change nothing.
1000Show child attributes
Show child attributes
1000Show child attributes
Show child attributes
1000Show child attributes
Show child attributes
Response
What was done (or, with dry_run, what would be done)
curl --request PUT \
--url https://staging2.xfaster.net/api/partner/v1/menu \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"mode": "full",
"categories": [
{
"external_id": "CAT-PIZZA",
"name": {
"he": "פיצות",
"ar": "بيتزا",
"en": "Pizzas"
},
"position": 1
},
{
"external_id": "CAT-DRINKS",
"name": "שתייה",
"position": 2
}
],
"addons": [
{
"external_id": "ADD-OLIVES",
"name": {
"he": "זיתים",
"en": "Olives"
},
"price": 400,
"available": true
}
],
"items": [
{
"external_id": "PIZZA-MARG",
"category_external_id": "CAT-PIZZA",
"name": {
"he": "מרגריטה",
"ar": "مارغريتا",
"en": "Margherita"
},
"description": {
"he": "רוטב עגבניות ומוצרלה"
},
"price": 5200,
"available": true,
"option_groups": [
{
"name": "גודל",
"type": "single",
"required": true,
"min": 1,
"max": 1,
"options": [
{
"name": "אישית",
"price": 0
},
{
"name": "משפחתית",
"price": 1500
}
]
}
],
"addon_external_ids": [
"ADD-OLIVES"
]
},
{
"external_id": "COLA-330",
"category_external_id": "CAT-DRINKS",
"name": "קוקה קולה 330 מ\"ל",
"price": 900,
"available": true
}
]
}
'const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
mode: 'full',
categories: [
{
external_id: 'CAT-PIZZA',
name: {he: 'פיצות', ar: 'بيتزا', en: 'Pizzas'},
position: 1
},
{external_id: 'CAT-DRINKS', name: 'שתייה', position: 2}
],
addons: [
{
external_id: 'ADD-OLIVES',
name: {he: 'זיתים', en: 'Olives'},
price: 400,
available: true
}
],
items: [
{
external_id: 'PIZZA-MARG',
category_external_id: 'CAT-PIZZA',
name: {he: 'מרגריטה', ar: 'مارغريتا', en: 'Margherita'},
description: {he: 'רוטב עגבניות ומוצרלה'},
price: 5200,
available: true,
option_groups: [
{
name: 'גודל',
type: 'single',
required: true,
min: 1,
max: 1,
options: [{name: 'אישית', price: 0}, {name: 'משפחתית', price: 1500}]
}
],
addon_external_ids: ['ADD-OLIVES']
},
{
external_id: 'COLA-330',
category_external_id: 'CAT-DRINKS',
name: 'קוקה קולה 330 מ"ל',
price: 900,
available: true
}
]
})
};
fetch('https://staging2.xfaster.net/api/partner/v1/menu', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://staging2.xfaster.net/api/partner/v1/menu"
payload = {
"mode": "full",
"categories": [
{
"external_id": "CAT-PIZZA",
"name": {
"he": "פיצות",
"ar": "بيتزا",
"en": "Pizzas"
},
"position": 1
},
{
"external_id": "CAT-DRINKS",
"name": "שתייה",
"position": 2
}
],
"addons": [
{
"external_id": "ADD-OLIVES",
"name": {
"he": "זיתים",
"en": "Olives"
},
"price": 400,
"available": True
}
],
"items": [
{
"external_id": "PIZZA-MARG",
"category_external_id": "CAT-PIZZA",
"name": {
"he": "מרגריטה",
"ar": "مارغريتا",
"en": "Margherita"
},
"description": { "he": "רוטב עגבניות ומוצרלה" },
"price": 5200,
"available": True,
"option_groups": [
{
"name": "גודל",
"type": "single",
"required": True,
"min": 1,
"max": 1,
"options": [
{
"name": "אישית",
"price": 0
},
{
"name": "משפחתית",
"price": 1500
}
]
}
],
"addon_external_ids": ["ADD-OLIVES"]
},
{
"external_id": "COLA-330",
"category_external_id": "CAT-DRINKS",
"name": "קוקה קולה 330 מ\"ל",
"price": 900,
"available": True
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://staging2.xfaster.net/api/partner/v1/menu",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'mode' => 'full',
'categories' => [
[
'external_id' => 'CAT-PIZZA',
'name' => [
'he' => 'פיצות',
'ar' => 'بيتزا',
'en' => 'Pizzas'
],
'position' => 1
],
[
'external_id' => 'CAT-DRINKS',
'name' => 'שתייה',
'position' => 2
]
],
'addons' => [
[
'external_id' => 'ADD-OLIVES',
'name' => [
'he' => 'זיתים',
'en' => 'Olives'
],
'price' => 400,
'available' => true
]
],
'items' => [
[
'external_id' => 'PIZZA-MARG',
'category_external_id' => 'CAT-PIZZA',
'name' => [
'he' => 'מרגריטה',
'ar' => 'مارغريتا',
'en' => 'Margherita'
],
'description' => [
'he' => 'רוטב עגבניות ומוצרלה'
],
'price' => 5200,
'available' => true,
'option_groups' => [
[
'name' => 'גודל',
'type' => 'single',
'required' => true,
'min' => 1,
'max' => 1,
'options' => [
[
'name' => 'אישית',
'price' => 0
],
[
'name' => 'משפחתית',
'price' => 1500
]
]
]
],
'addon_external_ids' => [
'ADD-OLIVES'
]
],
[
'external_id' => 'COLA-330',
'category_external_id' => 'CAT-DRINKS',
'name' => 'קוקה קולה 330 מ"ל',
'price' => 900,
'available' => true
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"dry_run": false,
"created": {
"categories": 2,
"items": 1,
"addons": 1
},
"updated": {
"categories": 0,
"items": 1,
"addons": 0
},
"switched_off": {
"categories": 0,
"items": 3,
"addons": 0
},
"unchanged": 0,
"errors": [
{
"kind": "item",
"external_id": "WINGS-6",
"code": "category_not_found",
"message": "No section with this category_external_id (send it in categories)."
}
]
}