# Instacart public retailer boundary scraper (`w3crawler/instacart-retailers-scraper`) Actor

Extract bounded public Instacart retailer-directory records with explicit source-access diagnostics.

- **URL**: https://apify.com/w3crawler/instacart-retailers-scraper.md
- **Developed by:** [w3crawler](https://apify.com/w3crawler) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 retailers

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

### Instacart Retailers Scraper

#### Target and scope

This Actor extracts bounded, source-backed retailer records from official public Instacart storefront or retailer pages. It reads public server-rendered retailer state when available, then falls back to retailer JSON-LD and official `/store/` links from the same page. It does not log in, use private APIs, solve CAPTCHAs, use stealth, or infer retailers from an access-barrier page.

A browser may show a login modal or a security-verification page while an unauthenticated request exposes no retailer data. Those outcomes are preserved as minimal diagnostics and an `OUTPUT` summary. The Actor never fabricates a retailer, address, phone number, rating, or store URL.

#### Use cases

- Inventory public retailer identity and metadata visible on Instacart storefront pages.
- Build a small public retailer directory with names, URLs, categories, hours, ratings, and contact fields when exposed.
- Run a scheduled source-access check that distinguishes usable data from login or security barriers.
- Inspect several official public Instacart pages with one bounded run.

#### Cost

Apify platform compute, storage, and any explicitly enabled proxy traffic are billed according to your Apify plan. This Actor has no separate service fee. Keep the source count, `maxItems`, response size, retries, and proxy use bounded to control run time and spend.

### How to use

1. Enter one official HTTPS Instacart page in `startUrl`, or leave it empty and provide `startUrls`.
2. Set the global retailer limit and bounded request controls.
3. Run the Actor and inspect normal rows, diagnostics, and the `OUTPUT` key-value record.

`startUrl` takes precedence over `startUrls` and the compatibility alias `url`. For multi-source mode, set `startUrl` to an empty string. The Actor performs one bounded request per source page; it does not guess pagination because a verified public directory pagination contract is not assumed. Storefront identity is accepted only from source-backed state on the same official page.

### Input

The input schema is the source of truth. All limits below are enforced by the schema and bounded again by the runtime.

| Field                | Type and default                                                  | Bounds and behavior                                                                                                                                                                                                        |
| -------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `startUrl`           | string, `https://www.instacart.com/store/kents-market/storefront` | Primary official HTTPS Instacart storefront or retailer page; maximum 2,000 characters. Takes precedence over the other source fields.                                                                                     |
| `startUrls`          | array, empty                                                      | Compatibility list of `{ "url": "https://..." }` objects, used when `startUrl` is empty. Duplicate normalized URLs are removed.                                                                                            |
| `url`                | string, empty                                                     | Single official HTTPS URL compatibility alias, used when `startUrl` and `startUrls` are empty.                                                                                                                             |
| `timeoutSecs`        | integer, `30`                                                     | Per-request timeout, from 5 through 120 seconds.                                                                                                                                                                           |
| `maxBytes`           | integer, `5000000`                                                | Maximum retained response size, from 100,000 through 5,000,000 bytes.                                                                                                                                                      |
| `maxItems`           | integer, `50`                                                     | Global normal retailer-row limit, from 1 through 100. Diagnostics do not consume the limit.                                                                                                                                |
| `requestDelayMs`     | integer, `0`                                                      | Delay before retries or redirects, from 0 through 10,000 ms.                                                                                                                                                               |
| `maxRequestRetries`  | integer, `1`                                                      | Retries only timeouts, transport failures, and HTTP 5xx responses; from 0 through 2. Access barriers are not bypassed.                                                                                                     |
| `userAgent`          | string, transparent default                                       | Optional user-agent without control characters; maximum 300 characters.                                                                                                                                                    |
| `proxyConfiguration` | object, direct                                                    | Optional `{ "useApifyProxy": true, "apifyProxyGroups": [], "apifyProxyCountry": "US" }`. At most five non-empty groups; country is an optional two-letter code. Proxy use is explicit and does not bypass access controls. |

#### Runnable single-source input

```json
{
  "startUrl": "https://www.instacart.com/store/kents-market/storefront",
  "maxItems": 10,
  "timeoutSecs": 30,
  "maxRequestRetries": 1,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

#### Runnable multi-source input

```json
{
  "startUrl": "",
  "startUrls": [
    { "url": "https://www.instacart.com/store" },
    { "url": "https://www.instacart.com/store/kents-market/storefront" },
    { "url": "https://www.instacart.com/store/sprouts/storefront" }
  ],
  "maxItems": 10,
  "timeoutSecs": 30,
  "maxBytes": 5000000,
  "requestDelayMs": 500,
  "maxRequestRetries": 1,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output

The default dataset contains only source-backed `instacart-retailer` rows. Access diagnostics and run summaries are stored in the `OUTPUT` key-value-store entry and logs. If a run saves retailers before a later request or output problem, the Actor run succeeds and reports `dataStatus: PARTIAL`. A clean empty result succeeds with `dataStatus: NO_RESULTS`. If a real failure occurs before any retailer is saved, the Actor run reports `status: FAILED` and `dataStatus: FAILED`; diagnostics are never added to the dataset.

#### Normal retailer record

```json
{
  "recordType": "instacart-retailer",
  "recordId": "retailer_0123456789abcdef0123",
  "source": "Instacart",
  "url": "https://www.instacart.com/store/kents-market/storefront",
  "sourceUrl": "https://www.instacart.com/store/kents-market/storefront",
  "retailerUrl": "https://www.instacart.com/store/example/storefront",
  "retailerId": "2686",
  "retailerName": "Example Market",
  "description": "Fresh grocery delivery and pickup.",
  "category": "Grocery - Traditional",
  "address": "10 Main Street, New York, NY, 10001",
  "addressDetails": {
    "addressLocality": "New York",
    "addressRegion": "NY",
    "postalCode": "10001"
  },
  "phoneNumber": "+1 212 555 0199",
  "phoneNumbers": ["+1 212 555 0199"],
  "websiteUrl": "https://example.com/market",
  "openingHours": ["Mo-Su 08:00-20:00"],
  "geo": { "latitude": 40.7128, "longitude": -74.006 },
  "imageUrls": ["https://www.instacart.com/assets/store.jpg"],
  "rating": 4.5,
  "reviewCount": 120,
  "position": 1,
  "scrapedAt": "2026-09-08T00:00:00.000Z"
}
```

#### Public-link fallback record

When richer retailer state and JSON-LD are absent, an official `/store/` link on the bounded page can still produce a normal identity row. Fields not exposed by the link are omitted.

```json
{
  "recordType": "instacart-retailer",
  "recordId": "retailer_89ab",
  "source": "Instacart",
  "url": "https://www.instacart.com/store",
  "sourceUrl": "https://www.instacart.com/store",
  "retailerUrl": "https://www.instacart.com/store/fresh-market",
  "retailerName": "Fresh Market",
  "position": 1,
  "scrapedAt": "2026-09-08T00:00:00.000Z"
}
```

#### `OUTPUT` summary

```json
{
  "status": "SUCCEEDED",
  "runStatus": "SUCCEEDED",
  "dataStatus": "PARTIAL",
  "source": "Instacart",
  "actor": "instacart-retailers-scraper",
  "targetCount": 3,
  "itemCount": 2,
  "retailerCount": 2,
  "diagnosticCount": 1,
  "blockedCount": 1,
  "optionalFailureCount": 0,
  "dataAvailable": true,
  "sourceTransport": "apify_proxy",
  "fixture": false,
  "requestCount": 3,
  "generatedBy": "OpenAI Codex with GPT-6",
  "completedAt": "2026-09-08T00:00:00.000Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Advanced options and troubleshooting

Use one source and a small `maxItems` for a smoke test. Multiple source pages, redirects, retries, larger response limits, and media arrays increase compute and request time. Missing contact details, hours, ratings, images, or descriptions are expected when the public page does not expose them.

- `LOGIN_REDIRECT` or `BLOCKED`: the page did not expose retailer records to this unauthenticated run; no bypass was attempted.
- `NO_PUBLIC_RETAILER_DATA`: the response was usable but contained no stable public retailer state, JSON-LD, or official store link.
- `HTTP_ERROR`, `TIMEOUT`, or `REQUEST_FAILED`: inspect the URL, timeout, retry count, and run logs.
- `INVALID_INPUT` or `INVALID_PROXY`: correct the input shape; unsupported fields are reported rather than silently used.

### API, support, and Issues

Use the Apify API or Console dataset endpoint to read normal rows and the default key-value store `OUTPUT` record. When reporting an issue, include the Actor version, run ID, input mode, error code, and a short description. Do not include private customer information or credentials.

### Privacy, legal, and non-affiliation

This Actor is not affiliated with, sponsored by, or endorsed by Instacart. It is intended for public, source-backed business data only. Follow Instacart's terms, robots guidance, rate limits, privacy rules, and applicable law. Public business pages can still contain personal data; use it lawfully. Do not log in, collect private customer data, evade security controls, or infer fields that the public source did not expose.

# Changelog

This Actor's version history is a separate document: https://apify.com/w3crawler/instacart-retailers-scraper/changelog.md

# Actor input Schema

## `startUrl` (type: `string`):

Primary public HTTPS Instacart storefront or retailer page. It takes precedence over startUrls and url.

## `startUrls` (type: `array`):

Compatibility list of additional public HTTPS Instacart pages when startUrl is empty. Duplicate normalized URLs are removed.

## `url` (type: `string`):

Compatibility alias for one public HTTPS Instacart page when startUrl is empty.

## `timeoutSecs` (type: `integer`):

Maximum time allowed for each public request.

## `maxBytes` (type: `integer`):

Maximum response size retained from a public page.

## `maxItems` (type: `integer`):

Maximum normal retailer records across all valid source URLs; diagnostics do not consume this limit.

## `requestDelayMs` (type: `integer`):

Bounded respectful delay before a retry or redirect; the first request is immediate.

## `maxRequestRetries` (type: `integer`):

Retries timeouts, transport failures, and HTTP 5xx responses only; access blocks are not bypassed.

## `userAgent` (type: `string`):

Optional transparent user-agent string.

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

Optional Apify Proxy configuration. Direct access is the default; proxy use does not bypass access controls.

## Actor input object example

```json
{
  "startUrl": "https://www.instacart.com/store/kents-market/storefront",
  "startUrls": [],
  "url": "",
  "timeoutSecs": 30,
  "maxBytes": 5000000,
  "maxItems": 50,
  "requestDelayMs": 0,
  "maxRequestRetries": 1,
  "userAgent": "Mozilla/5.0 (compatible; ApifyActor/1.0; +https://apify.com/)",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runSummary` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("w3crawler/instacart-retailers-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("w3crawler/instacart-retailers-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 '{}' |
apify call w3crawler/instacart-retailers-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,w3crawler/instacart-retailers-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/ihQGTk2SsefSTuZlo/builds/YjtdXKl6FeHPuMwMh/openapi.json
