# Bilka ToGo Scraper - Danish Online Grocery Prices (`studio-amba/bilkatogo-scraper`) Actor

Scrape everyday grocery prices, brands, stock, EAN codes and images from Bilka ToGo (bilkatogo.dk), Salling Group's Danish online supermarket. Fresh dairy, produce, meat, bread, frozen. No login required.

- **URL**: https://apify.com/studio-amba/bilkatogo-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bilka ToGo Scraper

Scrape products from bilkatogo.dk, Salling Group's Danish online grocery and
home-delivery shop (the successor to Føtex home delivery). This is Salling's
real everyday grocery webshop: fresh dairy, produce, meat and fish, bread,
frozen, drinks and pantry staples, all with real shelf prices.

**Coverage note**: our sibling actors `foetex-scraper` and `bilka-scraper`
read foetex.dk/bilka.dk's own Algolia index, which only covers non-perishable
groceries and general merchandise — fresh groceries are NOT in that catalogue.
Bilka ToGo is different: it's Salling's dedicated online grocery shop, so
milk, bread, butter, eggs, meat and fruit are all present with everyday
online prices, not just dry goods.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | String | No | Danish keyword, e.g. `"mælk"`, `"brød"`, `"smør"`, `"æg"`, `"kød"`, `"frugt"` |
| `searchQueries` | Array of strings | No | Multiple search terms in one run (overrides `searchQuery`) |
| `categoryUrl` | String | No | A bilkatogo.dk category page URL, e.g. `https://www.bilkatogo.dk/kategori/mejeri-og-koel/` |
| `categoryUrls` | Array of strings | No | Multiple category URLs in one run (overrides `categoryUrl`) |
| `maxResults` | Integer | No | Product limit across all search terms/categories (default: 100) |
| `storeId` | String | No | Delivery-warehouse store id to read price/stock from (advanced, default `"1653"`) |
| `inStockOnly` | Boolean | No | Only return products currently in stock at the selected store |
| `proxyConfiguration` | Object | No | Legacy proxy settings (not required — data comes from a public search API) |

Provide either a `searchQuery`/`searchQueries` or a `categoryUrl`/
`categoryUrls` (or both — the run will fetch all of them). Leaving everything
empty runs the default search query so `{}` still returns data.

#### Category URLs

Any bilkatogo.dk `/kategori/{slug}/` URL works, at any depth of the category
tree. The seven top-level grocery categories:

- `https://www.bilkatogo.dk/kategori/frugt-og-groent/` — Frugt & grønt (fruit & veg)
- `https://www.bilkatogo.dk/kategori/koed-og-fisk/` — Kød & fisk (meat & fish)
- `https://www.bilkatogo.dk/kategori/mejeri-og-koel/` — Mejeri & køl (dairy & chilled)
- `https://www.bilkatogo.dk/kategori/broed-og-kager/` — Brød & kager (bread & cakes)
- `https://www.bilkatogo.dk/kategori/kolonial/` — Kolonial (pantry)
- `https://www.bilkatogo.dk/kategori/frost/` — Frost (frozen)
- `https://www.bilkatogo.dk/kategori/drikkevarer/` — Drikkevarer (drinks)

### Output

| Field | Type | Example |
|-------|------|---------|
| `name` | String | `"Minimælk 0,4% fedt"` |
| `brand` | String | `"Salling"` |
| `price` | Number or null | `10.60` |
| `originalPrice` | Number or null | `null` |
| `currency` | String | `"DKK"` |
| `onPromotion` | Boolean | `false` |
| `promotionStartDate` | String or null | `"2026-08-28"` |
| `promotionEndDate` | String or null | `"2026-09-11"` |
| `ean` | String | `"5711953134616"` |
| `sku` | String | `"92369031"` |
| `productId` | String | `"84121"` |
| `inStock` | Boolean or null | `true` |
| `unitPrice` | Number or null | `10.60` |
| `unitPriceUnit` | String | `"L."` |
| `packageSize` | String | `"1 l"` |
| `category` | String | `"Mejeri & køl > Mejeri > Mælk > Minimælk"` |
| `imageUrl` | String | Product image |
| `retailer` | String | `"Bilka ToGo"` |
| `url` | String | Product page URL |
| `scrapedAt` | String | ISO timestamp when this Actor run collected the item |
| `sourceUpdatedAt` | String or null | ISO timestamp Bilka ToGo's own catalogue last synced the record |

```json
{
    "name": "Minimælk 0,4% fedt",
    "brand": "Salling",
    "price": 10.6,
    "originalPrice": null,
    "currency": "DKK",
    "onPromotion": false,
    "promotionStartDate": null,
    "promotionEndDate": null,
    "ean": "5711953134616",
    "sku": "92369031",
    "productId": "84121",
    "inStock": true,
    "unitPrice": 10.6,
    "unitPriceUnit": "L.",
    "packageSize": "1 l",
    "category": "Mejeri & køl > Mejeri > Mælk > Minimælk",
    "categories": ["Mejeri & køl", "Mejeri", "Mælk", "Minimælk"],
    "imageUrl": "https://digitalassets.sallinggroup.com/image/upload/...",
    "imageUrls": ["https://digitalassets.sallinggroup.com/image/upload/..."],
    "retailer": "Bilka ToGo",
    "url": "https://www.bilkatogo.dk/produkt/minimaelk-0-4-fedt/84121/",
    "scrapedAt": "2026-09-09T15:39:03.764Z",
    "sourceUpdatedAt": "2026-09-09T14:35:42.000Z"
}
```

`price` is the current shelf/online price at the selected delivery store, and
`originalPrice` is the pre-discount "before" price — when either
`originalPrice` is set or `onPromotion` is `true`, the product is on an
active campaign and `promotionStartDate` / `promotionEndDate` give the
campaign window as published by Bilka ToGo. `unitPrice` / `unitPriceUnit`
give the per-kg/per-litre/per-piece price used for shelf comparisons.

### Technical details

- Queries the same public Algolia search index bilkatogo.dk's own search box uses
- No proxy or browser required — direct HTTPS API calls only
- Prices in DKK (Danish kroner), read from a single delivery-warehouse store
  (default the site's own anonymous default); price and unit price were
  identical across every store spot-checked during recon, so this reflects
  the national online price for the vast majority of products
- Danish-language content throughout
- Catalogue size: ~36,000 products across the full non-food + grocery range

### Cost

Direct API calls, no browser or proxy overhead. **~$0.10 per 1,000 products**
(roughly $0.0001 per result). Usage cost only settles once a run finishes
with status **SUCCEEDED** — a run that fails or is aborted mid-way is not
billed for the results it already pushed.

### Why use Bilka ToGo Scraper

- **Everyday price tracking** — Track real shelf prices for staples (milk,
  bread, butter, eggs, meat, fruit) at Denmark's largest grocery chain
- **Grocery price comparison** — Build a Danish grocery price-comparison feed
  across categories, not just dry goods
- **Competitive intelligence** — Compare your catalog against Bilka ToGo
  pricing, promotions and assortment
- **Market research** — Analyze category trends, new arrivals and assortment
  breadth by category
- **No login or cookies required** — Authenticated access not needed; works
  out of the box

### How to use Bilka ToGo Scraper

1. Open the **Input** tab and provide a search query or a category URL
2. Adjust optional filters such as `maxResults` or `inStockOnly`
3. Click **Start** and wait for the run to complete
4. Download results from the **Output** tab in JSON, CSV, Excel, XML, or HTML
5. Schedule recurring runs from the **Schedule** tab if you need ongoing
   price-monitoring data

### How to scrape Bilka ToGo data

This Actor automates the process of extracting structured grocery data from
Bilka ToGo. You can run it directly from the Apify console, the Apify API, or
any of the official SDKs (JavaScript, Python). It handles pagination,
category-to-facet resolution, and deduplication so you can focus on the
data, not the plumbing.

Typical workflows:

- **One-off export**: paste a keyword or category URL, set `maxResults`, and run
- **Scheduled monitoring**: set a daily cron in the Schedule tab to track
  everyday grocery prices over time
- **Full-category pulls**: use `categoryUrls` with the seven grocery
  categories above to build a complete staples price feed
- **Programmatic integration**: trigger runs from your backend via the Apify
  API and pull the dataset when finished
- **Webhook automation**: receive a callback the moment a run completes and
  pipe the results into Zapier, Make, n8n, BigQuery, or Google Sheets

### Tips for best results

- **Start small** — run with `maxResults: 10` before launching large jobs
- **Use category URLs for full coverage** — a keyword search only returns
  matching products; a category URL returns the whole aisle
- **Filter to in-stock only** — set `inStockOnly: true` for purchase-ready data
- **Schedule runs** — daily runs are usually enough for price monitoring
- **Inspect the dataset schema** — the Storage tab shows the full output structure

### FAQ and support

**Is it legal to scrape Bilka ToGo?** This Actor extracts publicly available
data. Always review the website's Terms of Service before scraping at scale,
and respect rate limits.

**Does this cover fresh groceries, or just pantry items?** Fresh groceries —
this is Salling's dedicated online grocery shop, not the general-merchandise
catalogue. Dairy, produce, meat, fish and bread are all covered.

**Why am I getting fewer results than expected?** Some niche keywords have
few matches in the catalogue. Try a broader Danish term, or switch to a
`categoryUrl` for full-aisle coverage.

**Does price vary by store?** The underlying data is keyed per
delivery-warehouse, but price and unit price were identical across every
store checked during recon. The `storeId` input lets you point at a specific
warehouse if you ever need to verify a regional difference.

**Does this need a proxy?** No. The catalogue is fetched from a public search
API, so no proxy or browser is required for normal use.

For issues, feature requests, or bug reports, open a ticket in the Issues tab
on the Actor page or contact support@apify.com. We monitor every actor and
ship fixes quickly when sites change.

# Actor input Schema

## `searchQuery` (type: `string`):

Product search term in Danish (e.g., 'mælk', 'brød', 'smør', 'æg', 'kød', 'frugt').

## `searchQueries` (type: `array`):

Multiple Danish search terms to scrape in one run (max 50). Overrides Search Query if set.

## `categoryUrl` (type: `string`):

A bilkatogo.dk category page URL, e.g. https://www.bilkatogo.dk/kategori/mejeri-og-koel/. Works at any category depth.

## `categoryUrls` (type: `array`):

Multiple category URLs to scrape in one run (max 25). Overrides Category URL if set.

## `maxResults` (type: `integer`):

Maximum number of products to scrape across all search terms / categories.

## `storeId` (type: `string`):

Bilka ToGo delivery-warehouse store id to read price/stock from (advanced). Default '1653' (Bilka Waves, Hundige) is the site's own anonymous default and matches pricing observed at every other store during recon.

## `inStockOnly` (type: `boolean`):

Only return products currently marked in stock at the selected store.

## `proxyConfiguration` (type: `object`):

Legacy proxy settings. The product catalogue is fetched from a public search API with no anti-bot, so this can be left at its default.

## Actor input object example

```json
{
  "searchQuery": "mælk",
  "maxResults": 20,
  "storeId": "1653",
  "inStockOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "mælk",
    "maxResults": 20,
    "storeId": "1653",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/bilkatogo-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQuery": "mælk",
    "maxResults": 20,
    "storeId": "1653",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/bilkatogo-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQuery": "mælk",
  "maxResults": 20,
  "storeId": "1653",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call studio-amba/bilkatogo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/bilkatogo-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/lIpc8uTIs85e5PYut/builds/hXJtoXgjHldp5BZAo/openapi.json
