# Blinkit Scraper - Prices, Inventory and Dark Stores (`s-r/blinkit-scraper`) Actor

Blinkit price tracker and inventory export: collect product prices, MRP, availability and orderable stock across Indian locations, with the serving dark store attached to every offer.

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

## Pricing

from $5.00 / 1,000 per-run start fees

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Blinkit Scraper: Prices, Inventory and Dark Stores

Blinkit Scraper collects local product prices, MRP, availability and orderable inventory across Indian delivery locations. Compare the shelf served by each dark store in one dataset.

Use it to monitor an FMCG brand across cities, compare selling prices against maximum retail prices, or record whether a product is available at a particular delivery point. A national product list cannot explain local availability. This actor keeps each product attached to the serving store and the location you requested, so your analysis can distinguish a product missing in one neighborhood from a product available in another.

### Blinkit Scraper input

Provide search terms in `queries`, category identifiers in `category_ids`, or both. Search terms run independently at every location. The category format is `l0` or `l0/l1`; the Milk category is `14/922`. Category identifiers follow Blinkit's category URLs. The actor accepts up to 20 terms and 20 categories per run.

Add one or more entries to `locations`. Each entry can be a coordinate object with numeric `lat` and `lon`, a six-digit Indian pincode, or address text. You can mix those forms in the same list. Pincodes and addresses are resolved using the location information returned by Blinkit. Where a location cannot be resolved or served, the actor reports that limitation instead of assigning an approximate store.

This input uses the delivery point from the recorded Gurgaon search example:

```json
{
  "queries": ["amul milk"],
  "locations": [{"lat": 28.4595, "lon": 77.0266}],
  "max_items": 15
}
```

`max_items` limits delivered product offers per location and per search term or category. It defaults to 48 and accepts values from 1 to 500. Product variants count as separate offers. `include_out_of_stock` defaults to true; turn it off to keep only currently available offers. `include_stores` also defaults to true and adds fulfillment location context.

For existing integrations, `searchQueries` and `searchTerms` are supported aliases for `queries`. `productsLimit` and `maxResults` alias `max_items`. For search terms, a supplied main field takes precedence. If several limit fields are supplied, the smallest limit wins. A single delivery location can also be specified with `latitude` and `longitude`.

### Output: offers and fulfillment locations

The dataset contains two row types identified by both `record_type` and `_type`. An `offer` row represents a product at a serving dark store for one requested delivery point and search combination. A `fulfillment_location` row connects that dark store to the requested delivery location. Join them using `location_id` and `location_index`. The latter is the zero-based index of your input location, so two delivery points remain distinct when the same store serves both.

Offer rows include `product_id`, `title`, `brand`, `unit`, `price`, `mrp`, `discount_percent`, `inventory`, `availability`, `product_state`, `image_url`, `url`, `merchant_id` and `location_id`. Prices use Indian rupees and `currency` is `INR`. `country` is `IN`. Search context includes `query`, `category_id` and the one-based `position` within that search combination. Every row carries `source` and a UTC `fetched_at` timestamp.

The recorded first Gurgaon offer is Milky Mist 25 g High Protein Milk, product `1453864`, served by merchant `43483`. Its selling price is ₹79 against an MRP of ₹99, with a rounded discount of 20%, a `250 ml` unit and orderable inventory of 2. These are observations from the recorded response, not a promise that the current shelf will have identical prices.

Fulfillment rows include `platform`, `location_id`, `delivery_latitude`, `delivery_longitude`, the delivery pincode when available, and `offers_count`. City, locality, state, formatted address and delivery type are included when returned by the source. The coordinates describe your delivery point. They do not locate the warehouse building. Store rows appear after that delivery point has finished collecting its offers.

### Use cases for a Blinkit price tracker

- **FMCG brand monitoring:** check the selling price, MRP and discount of your range in several cities and see where a product is out of stock.
- **Price tracking:** schedule the actor daily and compare `price` and `mrp` per `product_id` over time to build a Blinkit price history.
- **Availability analysis:** use `inventory`, `availability` and `merchant_id` to map which dark stores carry a product around a delivery point.
- **Market research:** compare assortment and discounting between neighborhoods and cities for quick-commerce analysis.

### Blinkit Scraper compared with other options

Blinkit offers no public API for shelf data, so searches for a Blinkit API usually end in a scraper. Many Blinkit tools return one flat product list for a single place. This actor takes several locations in one run and returns, next to the offers, a `fulfillment_location` row per delivery point that names the serving store. That makes dark-store coverage a direct output instead of something you reconstruct. Existing input aliases stay supported, so you can move over from similar tools without rewriting your input.

### Inventory, variants and delivery estimates

Inventory is the quantity currently orderable through the product card, capped at 50. A value of 50 does not establish the exact stock level inside the warehouse. Availability follows Blinkit's product state: `InStock` or `OutOfStock`. Unavailable variants can still appear when out-of-stock inclusion is enabled.

Variants have their own product identifiers. Repeated copies of the same card within one search combination are removed. A product matching two different terms can appear once for each term, with the corresponding context preserved. Store offer counts include those delivered search-context rows.

`eta_minutes` is included when Blinkit displays a recognizable delivery estimate and is null when unknown. Store-level estimates use the most common estimate among that store's delivered offers. They describe the observed delivery promise and should not be treated as a service guarantee.

### Pagination and incomplete results

Large requests continue automatically on Apify. Direct API users receive a `cursor` and repeat the same input with that token until it becomes null. Keep the search terms, locations and options unchanged while continuing. Positions, duplicate detection and store offer counts carry across those requests.

`partial` and `warnings` explain unfinished work, empty search combinations or unavailable locations. Other usable locations can still produce results. If every requested combination returns no products, the run has no offer rows. The actor does not substitute products from unrelated locations or invent missing identifiers.

### Pricing and trial limits

Product billing counts delivered `offer` rows only. Fulfillment location context does not generate an offer event. A separate actor start event may apply according to the current pricing shown on this actor's Pricing tab, including runs without matches. Consult that tab for the active amounts before running a large collection.

Non-paying accounts have a delivery cap of 10 dataset rows per run. Offers are ordered before fulfillment context, so the cap can omit some or all store rows. Only the offers actually delivered are counted for product billing. Your requested limit applies independently to each location and term; adding locations or terms increases the potential paid result count.

### Frequently asked questions

#### Can I compare several cities in one run?

Yes. Supply the delivery coordinates, pincodes or addresses together in `locations`. Each offer keeps its input location index and serving merchant identifier. Compare matching product identifiers across those locations while retaining the timestamps.

#### Does inventory show exact warehouse stock?

It shows the orderable amount visible on the product card, up to 50. It does not reveal an exact physical count above that limit. Combine inventory with availability when interpreting a missing or unavailable variant.

#### Are these coordinates the dark store's address?

They are delivery coordinates. The serving dark store is identified by `merchant_id` and `location_id`. The actor does not provide a warehouse coordinate or address when Blinkit does not expose one.

#### Can I start with a pincode?

Yes. A six-digit Indian pincode can be provided as a location string. The returned city and delivery coordinates reflect the source's location resolution. For precise neighborhood comparisons, provide the exact delivery coordinates instead of relying on a broader postal area.

# Actor input Schema

## `queries` (type: `array`):

Search terms, up to 20; each is searched at every location.

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

Alias for queries, used when queries is absent.

## `searchTerms` (type: `array`):

Alias for queries, used when queries and searchQueries are absent.

## `category_ids` (type: `array`):

Numeric category identifiers: l0 or l0/l1, such as 14/922.

## `locations` (type: `array`):

One to 20 Indian delivery points: lat/lon objects, six-digit pincodes or address strings.

## `latitude` (type: `number`):

Single-location latitude alias; supply longitude too.

## `longitude` (type: `number`):

Single-location longitude alias; supply latitude too.

## `max_items` (type: `integer`):

Maximum offers per location and query/category, including variants. Defaults to 48. If several limit fields are supplied, the smallest wins.

## `productsLimit` (type: `integer`):

Alias for max_items. If several limit fields are supplied, the smallest wins.

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

Alias for max_items. If several limit fields are supplied, the smallest wins.

## `include_out_of_stock` (type: `boolean`):

Include out-of-stock products, with inventory 0.

## `include_stores` (type: `boolean`):

Include fulfillment_location rows for completed delivery points.

## `cursor` (type: `string`):

Signed continuation token; repeat the same input with this token.

## Actor input object example

```json
{
  "queries": [
    "amul milk"
  ],
  "locations": [
    {
      "lat": 28.4595,
      "lon": 77.0266
    }
  ],
  "include_out_of_stock": true,
  "include_stores": true
}
```

# Actor output Schema

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

Offer rows and fulfillment_location context rows.

## `output` (type: `string`):

Counts, warnings and completion status.

# 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 = {
    "queries": [
        "amul milk"
    ],
    "locations": [
        {
            "lat": 28.4595,
            "lon": 77.0266
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/blinkit-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 = {
    "queries": ["amul milk"],
    "locations": [{
            "lat": 28.4595,
            "lon": 77.0266,
        }],
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/blinkit-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 '{
  "queries": [
    "amul milk"
  ],
  "locations": [
    {
      "lat": 28.4595,
      "lon": 77.0266
    }
  ]
}' |
apify call s-r/blinkit-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/blinkit-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/Tk13qxGtRQSjBe6ZD/builds/buSGwNHNYmls56Vq6/openapi.json
