# BİM API scraper — Turkey's largest discount grocery chain (bim.com.tr): the weekly Aktüel Ürünler and İndirim leaflets with every product, its campaign price, struck price and BİM's own discount percent, package size, brand, features, instalments and images; upcoming leaflets days before they start; the leaflet sheets as images; and BİM's public store finder. Prices in TRY. No account, no browser.

> Every leaflet BİM is publishing right now — the recent ones, the one on shelf today, and the UPCOMING ones (BİM puts the next week's sheets up days early). Each entry carries the leaflet key you pass to `leaflet/products`, its family (`aktuel` special-buy sheet or `indirim` price-cut sheet), BİM's own date label, the start and end dates, and whether it is current, upcoming or past. This is the only legitimate source of a leaflet key: BİM keeps no archive.
> ReefAPI engine `bim` · 6 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/bim/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http). Send the key as `Authorization: Bearer <key>`, or put it in the URL (`?key=<key>`) when the client has no header field, as ChatGPT does.

## Endpoints

### POST https://api.reefapi.com/bim/v1/leaflets — 1 credit
Every leaflet BİM is publishing right now — the recent ones, the one on shelf today, and the UPCOMING ones (BİM puts the next week's sheets up days early). Each entry carries the leaflet key you pass to `leaflet/products`, its family (`aktuel` special-buy sheet or `indirim` price-cut sheet), BİM's own date label, the start and end dates, and whether it is current, upcoming or past. This is the only legitimate source of a leaflet key: BİM keeps no archive.

**Parameters:**
- `type` (enum, optional, default "all") — Which leaflet family to list. BİM runs both at once. [one of: all, aktuel, indirim]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a request on a fresh exit (1-8, default 3).

**Returns:** leaflets[{leaflet_key, type, date_label (BİM's own text), starts_on, ends_on (ISO; the YEAR is inferred — BİM prints day and month only), year_inferred, weekday, is_current, days_from_today, status (current|upcoming|today|past — `current` is the sheet BİM's own site is showing), url}], count, current_leaflet_key, today (Istanbul date), types_present[]

**Example request body:**
```json
{
  "type": "all"
}
```

### POST https://api.reefapi.com/bim/v1/leaflet/products — 1 credit
Every product on one BİM leaflet: title, brand, campaign price in TRY, the struck price and BİM's discount percent where BİM prints them, package size, feature bullets, interest-free instalments, image and product URL. Pick the leaflet by `leaflet_key`, by `date` (future dates included), or leave both out for the sheet on shelf today. An unknown key is rejected, never answered with the wrong week.

**Parameters:**
- `leaflet_key` (integer, optional) — The leaflet's own id, exactly as `leaflets` returns it. 🔴 BİM keeps no archive: only the keys `leaflets` currently lists answer — any other key silently renders the current leaflet, and this engine rejects that with NOT_FOUND rather than returning the wrong week's products.
- `date` (string, optional) — Instead of `leaflet_key`: an ISO date. Returns the leaflet BİM publishes for that day — for `indirim`, the sheet whose date range covers it (BİM runs a long sheet and a weekly one at the same time, and the one starting nearest your date wins; use `leaflets` + `leaflet_key` to pick the other). Future dates work: BİM publishes upcoming leaflets days ahead.
- `type` (enum, optional, default "aktuel") — Which leaflet family. Used when you give a `date`, or on its own to get that family's current leaflet. Ignored when `leaflet_key` is given. [one of: aktuel, indirim]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a request on a fresh exit (1-8, default 3).

**Returns:** leaflet{leaflet_key, type, date_label, starts_on, ends_on, year_inferred, weekday, is_current, days_from_today, status, url}, products[]{position, product_id, title, brand (null when BİM left its brand field empty — the brand is then often inside the title and is NOT split out), package_size, features[], price (number, TRY), price_before_discount (the struck price — null on every `aktuel` leaflet because BİM does not print one there; filled on `indirim`), discount_percent (BİM's own printed figure, which truncates), discount_percent_calculated (the exact arithmetic, null when there is no struck price), currency=TRY, campaign_type, max_interest_free_installments, image, slug, url}, count, products_with_struck_price, products_without_price[] (BİM prints no price for these — it hides a 0,00 price button), banner_tiles (advert tiles inside BİM's grid, never counted as products), price_range{min, max}, currency=TRY, source_publishes_struck_price (false on every `aktuel` leaflet — BİM does not print one there)

**Example request body:**
```json
{
  "type": "aktuel"
}
```

### POST https://api.reefapi.com/bim/v1/product/detail — 1 credit
One BİM leaflet product by its URL or slug: title, price, struck price and discount where BİM prints them, package size, the feature list (the product page often carries more bullets than the leaflet tile), every image, instalments — plus which leaflet it belongs to and its brand, read from that leaflet. A product whose leaflet has expired returns NOT_FOUND rather than BİM's silent homepage.

**Parameters:**
- `url` (string, optional) — A BİM product URL, as `leaflet/products` returns it in `url`. ⚠️ BİM product pages live only while their leaflet does — take a fresh URL from `leaflet/products` rather than storing one.
- `slug` (string, optional) — Alternative to `url`: just the slug part, as `leaflet/products` returns it in `slug`.
- `include_brand` (boolean, optional, default true) — BİM's product page does not publish the brand — only the leaflet listing does. Left true, the engine also reads the product's leaflet so `brand` and the leaflet's date are filled (one extra request). Set false for the page alone; `brand` is then null because it was not read, and `brand_source` says so.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a request on a fresh exit (1-8, default 3).

**Returns:** product{product_id, title, brand, brand_source (leaflet|not_requested — BİM's product page never publishes a brand), package_size, features[], price, price_before_discount, discount_percent, discount_percent_calculated, currency=TRY, max_interest_free_installments, image, images[], slug, url}, leaflet{leaflet_key, type, date_label, starts_on, ends_on, is_current, status, url} (null when include_brand=false)

**Example request body:**
```json
{
  "url": "https://www.bim.com.tr/aktuel-urunler/darel-calisma-masasi-14-9/aktuel.aspx"
}
```

### POST https://api.reefapi.com/bim/v1/posters — 1 credit
BİM's leaflet sheets as images — the scanned Aktüel, İndirim and Kırtasiye posters, each with BİM's date label, a cover image, every page image in order and BİM's own download link. This is the printed sheet; `leaflet/products` is the same campaign as structured rows.

**Parameters:**
- `type` (enum, optional, default "all") — Which poster tab to return. [one of: all, aktuel, indirim, kirtasiye]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a request on a fresh exit (1-8, default 3).

**Returns:** posters[{type (aktuel|indirim|kirtasiye), label, starts_on, ends_on, cover_image, page_images[], page_count, download_url}], count, counts_by_type{}, total_pages

**Example request body:**
```json
{
  "type": "all"
}
```

### POST https://api.reefapi.com/bim/v1/stores — 1 credit
BİM's public store finder. With no parameters it returns the 81 provinces; with a `city` it returns that province's districts; with both it returns the stores — branch name and street address. Works by name or by BİM's own numeric ids.

**Parameters:**
- `city` (string, optional) — Province name or BİM's numeric province id. Leave it out to get the list of all 81 provinces BİM serves.
- `county` (string, optional) — District name or BİM's numeric district id. Leave it out to get the districts of `city`. 🔴 BİM's store finder needs a district — a province on its own returns no stores, not all of them.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a request on a fresh exit (1-8, default 3).

**Returns:** level (cities|counties|stores), cities[{id, name}] or counties[{id, name}] or stores[{name, address, city, county}], count, reported_count (BİM's own 'Listelenen Mağaza Sayısı'), city{id, name}, county{id, name}. BİM does not publish coordinates, telephone numbers or opening hours for its stores.

**Example request body:**
```json
{
  "city": "İstanbul",
  "county": "Kadıköy"
}
```

### POST https://api.reefapi.com/bim/v1/brands — 1 credit
BİM's own-label brands. With no parameters it returns BİM's eleven product categories; with a `category` it returns that category's own-label brand names and logos. BİM publishes brand names and logos here only — there are no products or prices on this surface.

**Parameters:**
- `category` (string, optional) — A category slug or numeric id from this action's own `categories` list. Leave it out to get the category list itself.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a request on a fresh exit (1-8, default 3).

**Returns:** level (categories|brands), categories[{category_id, slug, name, url}] or brands[{name, logo}], count, category{category_id, slug, name}, description (BİM's own category text)

**Example request body:**
```json
{
  "category": "sut-ve-sut-urunleri"
}
```

## At scale
- **Volume:** 5M+ requests a day, measured at 60 requests a second across the fleet with no
  central bottleneck. Per-key limits are raised for high-volume accounts; volume pricing on request.
- **Missing a source:** tell us a site we do not cover and it becomes an engine. A customer asked
  for bestprice.gr on 21 Sep 2026 and it was in the catalog on 22 Sep.
- **Support:** 2 minute median time from a question in the live chat to the first answer. Setup
  help included, no support tier to buy.
- **One key, one credit pool** across every API. No per-site plans, no separate subscriptions.

## More
- Try it live, no code: https://reefapi.com/playground?engine=bim
- Human docs page: https://reefapi.com/docs/bim
- Overview page: https://reefapi.com/bim-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
