🇧🇬 Bulmag Example solution JavaScript /parse + /products

Bulmag and the Pepesto API: A First Bulgarian Grocery Integration

This is a walkthrough of integrating with Bulgaria's Bulmag grocery platform using the Pepesto API. It parses a traditional Bulgarian recipe via /parse and matches ingredients to Bulmag's catalog via /products, with notes on match quality for each item.

Run this yourself

$ PEPESTO_API_KEY=your_key node bulmag-bg-first-integration.js

Full script: bulmag-bg-first-integration.js. You'll need an API key to run it — get one here.

Getting started

bash
export PEPESTO_API_KEY=pep_sk_your_key_here
node bulmag-bg-first-integration.js

The first call

Parse the recipe first. Pass a Bulgarian recipe URL and the bg-BG locale so the API returns ingredient labels in Cyrillic.

js
const parseRes = await fetch('https://s.pepesto.com/api/parse', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.PEPESTO_API_KEY}`,
  },
  body: JSON.stringify({
    recipe_url: 'https://recepti.gotvach.bg/r-bob-chorba-klasicheska',
    locale: 'bg-BG',
  }),
});

const { recipe } = await parseRes.json();
json — parse response
{
  "recipe": {
    "title": "Боб чорба класическа",
    "ingredients": [
      "500g боб бял или шарен",
      "1 глава лук",
      "2 моркова",
      "1 стрък праз",
      "1 домат",
      "30ml слънчогледово олио",
      "1 ч.л. чубрица",
      "1 ч.л. червен пипер",
      "сол"
    ],
    "kg_token": "EiYKJEJvYiBjaG9yYmEga2xhc2ljaGVza2..."
  }
}

Then pass the kg_token to POST /api/products with supermarket_domain: "bulmag.org". Bulmag carries a mix of Bulgarian-origin produce, imported goods, and standard grocery staples, all labelled in Cyrillic.

js
const productsRes = await fetch('https://s.pepesto.com/api/products', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.PEPESTO_API_KEY}`,
  },
  body: JSON.stringify({
    recipe_kg_tokens: [recipe.kg_token],
    supermarket_domain: 'bulmag.org',
  }),
});

const { items } = await productsRes.json();
// items[i] = { item_name, products: [{ product, session_token, num_units_to_buy }] }
json — products response (excerpt, bulmag.org)
{
  "items": [
    {
      "item_name": "лук",
      "products": [
        {
          "product": {
            "product_name": "Кромид лук",
            "quantity": { "grams": 1000 },
            "price": { "price": 129, "promotion": {} }
          },
          "session_token": "eyJwcm9kdWN0...",
          "num_units_to_buy": 1
        }
      ]
    },
    {
      "item_name": "агнешка",
      "products": [
        {
          "product": {
            "product_name": "Агнешка плешка България",
            "quantity": { "grams": 1000 },
            "price": { "price": 1449, "promotion": { "promo": true } }
          },
          "session_token": "eyJwcm9kdWN0...",
          "num_units_to_buy": 1
        }
      ]
    },
    {
      "item_name": "мляко",
      "products": [
        {
          "product": {
            "product_name": "Ацидофилно мляко Нарине 2% 400г",
            "quantity": { "grams": 400 },
            "price": { "price": 77, "promotion": { "promo": true } }
          },
          "session_token": "eyJwcm9kdWN0...",
          "num_units_to_buy": 1
        }
      ]
    }
  ]
}

What the data showed

Match quality for a first attempt is solid. Core vegetables — onion, tomato, carrot — matched well. Bulmag's Bulgarian-origin lamb (Агнешка плешка България) came through as a promo item at 14.49 EUR/kg, which is competitive. The Narine acidophilus milk (Ацидофилно мляко Нарине) matched for dairy requirements.

Where things got interesting: чубрица (savory) had no exact match. It's a very specifically Bulgarian herb that Bulmag doesn't list as a standalone product. The API correctly flagged this as a substitution rather than silently returning something wrong. That transparency matters — you'd rather know a match is approximate than assume it's exact.

The prices at Bulmag are displayed in EUR, which reflects the context of the store's user base. The promo_percentage field surfaced active discounts automatically — both the lamb shoulder (12% off) and the acidophilus milk (11% off) were on promotion.

Next steps

The obvious next step is to run the same kg_token against eBag — Bulgaria's other main online grocery store — and compare which is cheaper for each ingredient. That's exactly what the eBag story covers.

json — session response
{
  "session_id": "ses_bulmag_ghi789",
  "redirect_url": "https://app.pepesto.com/session/ses_bulmag_ghi789",
  "items_count": 9,
  "total_price_cents": 2847
}

The result

Pepesto's Bulmag integration works. It's not perfect — niche Bulgarian herbs and some very local products don't always get an exact match — but the core staples are there, the Cyrillic product names come through correctly, and the promo detection is a genuine bonus.

For a country where the developer ecosystem around grocery delivery is essentially zero, having a clean JSON API that handles Bulgarian product matching is genuinely useful. Even a 70% match rate means you're filling most of your basket automatically instead of doing it by hand.

What else you could do?

Add a substitution fallback: when an ingredient returns a substitution flag, query /api/suggest to find a recipe variant that avoids that ingredient entirely. Add a unit cost normaliser — Bulmag mixes per-kg and per-piece pricing, so comparing across items requires converting to a common unit first. Run a cross-store comparison against eBag using the same kg_token — that's a one-line domain change to the existing script.

Links

Ready to build?

Start integrating Bulgarian grocery data

Bulmag is live in the Pepesto API — parse any Bulgarian recipe and match it to real Bulmag products.

27supermarkets 13countries 1schema Instant access