# Zepto API for agents

> API for Agents · https://apiforagents.dev/platforms/zepto · HTML twin: https://apiforagents.dev/platforms/zepto

A product's price and stock at one dark store, right now, from Zepto.

Endpoint: `POST https://apiforagents.dev/v1/zepto`. One op per call. Quote first with `"estimateOnly": true`.

## Prices (USD per record, pay as you go)

| Record | Per record |
|---|---|
| category | $0.0009 |
| products | $0.0009 |
| search | $0.0009 |

## Operations

### products

Full product detail at one store. Price, MRP, discount, stock count, rating, seller, manufacturer, specifications. By product URL.

| Field | Required | Type | Meaning |
|---|---|---|---|
| subjects | yes | list of string (1-10 items) | Product URLs at that store. |
| store | yes | object |  |
| store.storeId | no | string | The dark store's own id, when a previous answer or a store URL gave you one. The most exact way to name a store; wins over the others. |
| store.city | no | string | The city the pincode is in ("Agra"). Helps the pincode resolve to the right store; ignored when storeId or lat/lon are given. |
| store.pincode | no | string | A 6-digit Indian postal code ("282003"); the nearest serving store is used. Give city too when the pincode is ambiguous. |
| store.lat | no | number | Latitude in decimal degrees, with lon: the store serving that point. |
| store.lon | no | number | Longitude in decimal degrees; only read together with lat. |

Response fields (each row of data; every field present, null when the source had nothing):

| Field | Type |
|---|---|
| productId | string |
| variantId | string |
| storeScope | string |
| storeId | string |
| vendorProductId | string |
| productName | string |
| brand | string |
| price | number |
| mrp | number |
| discountPct | number |
| packSize | string |
| inStock | boolean |
| stockCount | integer |
| rating | number |
| ratingCount | integer |
| category | string |
| rank | integer |
| sponsored | boolean |
| images | list of string |
| productUrl | string |
| description | string |
| countryOfOrigin | string |
| manufacturer | string |
| seller | string |
| specifications | any |
| latitude | number |
| longitude | number |
| details | object |

`details` is always the last field: everything else the source sent for that row, under our own field names. Its keys depend on the source that answered, so read them defensively; it is `{}` when there is nothing more.

Example request:

```bash
curl -X POST https://apiforagents.dev/v1/zepto \
  -H "Authorization: Bearer $AFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"op":"products","subjects":["https://www.zepto.com/pn/<product-name>/pvid/<id>"],"store":{"city":"Bengaluru","pincode":"560001"}}'
```

Example response rows (made-up names, real field names; a live row carries every field above):

```json
[
  {
    "productName": "Tomato, Hybrid",
    "brand": "Fresh",
    "price": 32,
    "mrp": 40,
    "discountPct": 20,
    "packSize": "500 g",
    "inStock": true,
    "category": "Vegetables",
    "rank": 1,
    "rating": 4.3,
    "ratingCount": 1200,
    "productId": "1563872094",
    "variantId": "1783170642",
    "storeId": "1613790522",
    "vendorProductId": "2511739480",
    "images": [
      "https://img.zeptonow.com/tomato-hybrid.jpg"
    ],
    "productUrl": "https://www.zeptonow.com/tomato-hybrid-1000",
    "details": {}
  },
  {
    "productName": "Onion",
    "brand": "Fresh",
    "price": 38,
    "mrp": 45,
    "discountPct": 16,
    "packSize": "1 kg",
    "inStock": true,
    "category": "Vegetables",
    "rank": 2,
    "rating": 4.3,
    "ratingCount": 1200,
    "productId": "1331370611",
    "variantId": "1288289772",
    "storeId": "2237783320",
    "vendorProductId": "2449101274",
    "images": [
      "https://img.zeptonow.com/onion.jpg"
    ],
    "productUrl": "https://www.zeptonow.com/onion-1001",
    "details": {}
  }
]
```

Try it in the playground: https://apiforagents.dev/dashboard/run?platform=zepto&op=products (sign in first).

### search

Search the app as a shopper at that store would. Listings with price, MRP, stock and rank.

| Field | Required | Type | Meaning |
|---|---|---|---|
| query | yes | string (≤300 chars) |  |
| store | yes | object |  |
| store.storeId | no | string | The dark store's own id, when a previous answer or a store URL gave you one. The most exact way to name a store; wins over the others. |
| store.city | no | string | The city the pincode is in ("Agra"). Helps the pincode resolve to the right store; ignored when storeId or lat/lon are given. |
| store.pincode | no | string | A 6-digit Indian postal code ("282003"); the nearest serving store is used. Give city too when the pincode is ambiguous. |
| store.lat | no | number | Latitude in decimal degrees, with lon: the store serving that point. |
| store.lon | no | number | Longitude in decimal degrees; only read together with lat. |
| limit | no | integer (1-100) |  |

Response fields (each row of data; every field present, null when the source had nothing):

| Field | Type |
|---|---|
| productId | string |
| variantId | string |
| storeScope | string |
| storeId | string |
| vendorProductId | string |
| productName | string |
| brand | string |
| price | number |
| mrp | number |
| discountPct | number |
| packSize | string |
| inStock | boolean |
| stockCount | integer |
| rating | number |
| ratingCount | integer |
| category | string |
| rank | integer |
| sponsored | boolean |
| images | list of string |
| productUrl | string |
| description | string |
| countryOfOrigin | string |
| manufacturer | string |
| seller | string |
| specifications | any |
| latitude | number |
| longitude | number |
| details | object |

`details` is always the last field: everything else the source sent for that row, under our own field names. Its keys depend on the source that answered, so read them defensively; it is `{}` when there is nothing more.

Example request:

```bash
curl -X POST https://apiforagents.dev/v1/zepto \
  -H "Authorization: Bearer $AFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"op":"search","query":"Tata Salt","store":{"city":"Delhi","pincode":"110001"},"limit":20}'
```

Example response rows (made-up names, real field names; a live row carries every field above):

```json
[
  {
    "productName": "Dish Wash Liquid, Lemon",
    "brand": "Shinex",
    "price": 99,
    "mrp": 115,
    "discountPct": 14,
    "packSize": "500 ml",
    "inStock": true,
    "category": "Cleaning",
    "rank": 1,
    "rating": 4.3,
    "ratingCount": 1200,
    "productId": "213580421",
    "variantId": "381638891",
    "storeId": "4133013222",
    "vendorProductId": "3270065864",
    "images": [
      "https://img.zeptonow.com/dish-wash-liquid-lemon.jpg"
    ],
    "productUrl": "https://www.zeptonow.com/dish-wash-liquid-lemon-1000",
    "details": {}
  },
  {
    "productName": "Dish Wash Bar",
    "brand": "Shinex",
    "price": 30,
    "mrp": 30,
    "discountPct": 0,
    "packSize": "200 g",
    "inStock": true,
    "category": "Cleaning",
    "rank": 2,
    "rating": 4.3,
    "ratingCount": 1200,
    "productId": "1242557009",
    "variantId": "962932821",
    "storeId": "265047964",
    "vendorProductId": "4128143963",
    "images": [
      "https://img.zeptonow.com/dish-wash-bar.jpg"
    ],
    "productUrl": "https://www.zeptonow.com/dish-wash-bar-1001",
    "details": {}
  }
]
```

Try it in the playground: https://apiforagents.dev/dashboard/run?platform=zepto&op=search (sign in first).

### category

One category page at one store. Names must be the app's own menu names; a name that is not on the menu is refused and nothing is charged.

| Field | Required | Type | Meaning |
|---|---|---|---|
| category | yes | string (≤80 chars) | The top-level aisle as the app names it ("Dairy, Bread & Eggs"). |
| subCategory | yes | string (≤80 chars) | The shelf inside it, again as the app names it ("Milk"). Both are required: the listing is one shelf at one store. |
| store | yes | object |  |
| store.storeId | no | string | The dark store's own id, when a previous answer or a store URL gave you one. The most exact way to name a store; wins over the others. |
| store.city | no | string | The city the pincode is in ("Agra"). Helps the pincode resolve to the right store; ignored when storeId or lat/lon are given. |
| store.pincode | no | string | A 6-digit Indian postal code ("282003"); the nearest serving store is used. Give city too when the pincode is ambiguous. |
| store.lat | no | number | Latitude in decimal degrees, with lon: the store serving that point. |
| store.lon | no | number | Longitude in decimal degrees; only read together with lat. |
| limit | no | integer (1-100) |  |

Response fields (each row of data; every field present, null when the source had nothing):

| Field | Type |
|---|---|
| productId | string |
| variantId | string |
| storeScope | string |
| storeId | string |
| vendorProductId | string |
| productName | string |
| brand | string |
| price | number |
| mrp | number |
| discountPct | number |
| packSize | string |
| inStock | boolean |
| stockCount | integer |
| rating | number |
| ratingCount | integer |
| category | string |
| rank | integer |
| sponsored | boolean |
| images | list of string |
| productUrl | string |
| description | string |
| countryOfOrigin | string |
| manufacturer | string |
| seller | string |
| specifications | any |
| latitude | number |
| longitude | number |
| details | object |

`details` is always the last field: everything else the source sent for that row, under our own field names. Its keys depend on the source that answered, so read them defensively; it is `{}` when there is nothing more.

Example request:

```bash
curl -X POST https://apiforagents.dev/v1/zepto \
  -H "Authorization: Bearer $AFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"op":"category","category":"Atta Rice Oil Dals","subCategory":"Atta","store":{"city":"Bengaluru","pincode":"560001"},"limit":50}'
```

Example response rows (made-up names, real field names; a live row carries every field above):

```json
[
  {
    "productName": "Potato Chips, Salted",
    "brand": "Crunchio",
    "price": 20,
    "mrp": 20,
    "discountPct": 0,
    "packSize": "52 g",
    "inStock": true,
    "category": "Snacks",
    "rank": 1,
    "rating": 4.3,
    "ratingCount": 1200,
    "productId": "1498328296",
    "variantId": "2377874407",
    "storeId": "3345945435",
    "vendorProductId": "1303579314",
    "images": [
      "https://img.zeptonow.com/potato-chips-salted.jpg"
    ],
    "productUrl": "https://www.zeptonow.com/potato-chips-salted-1000",
    "details": {}
  },
  {
    "productName": "Roasted Peanuts",
    "brand": "Nutbox",
    "price": 55,
    "mrp": 60,
    "discountPct": 8,
    "packSize": "200 g",
    "inStock": true,
    "category": "Snacks",
    "rank": 2,
    "rating": 4.3,
    "ratingCount": 1200,
    "productId": "877985001",
    "variantId": "2418411808",
    "storeId": "3612682689",
    "vendorProductId": "4241202604",
    "images": [
      "https://img.zeptonow.com/roasted-peanuts.jpg"
    ],
    "productUrl": "https://www.zeptonow.com/roasted-peanuts-1001",
    "details": {}
  }
]
```

Try it in the playground: https://apiforagents.dev/dashboard/run?platform=zepto&op=category (sign in first).

### history (free)

The stored price/stock series of products already held at a store. Free.

| Field | Required | Type | Meaning |
|---|---|---|---|
| subjects | yes | list of string (1-10 items) |  |
| store | yes | object |  |
| store.storeId | no | string | The dark store's own id, when a previous answer or a store URL gave you one. The most exact way to name a store; wins over the others. |
| store.city | no | string | The city the pincode is in ("Agra"). Helps the pincode resolve to the right store; ignored when storeId or lat/lon are given. |
| store.pincode | no | string | A 6-digit Indian postal code ("282003"); the nearest serving store is used. Give city too when the pincode is ambiguous. |
| store.lat | no | number | Latitude in decimal degrees, with lon: the store serving that point. |
| store.lon | no | number | Longitude in decimal degrees; only read together with lat. |
| metric | no | enum |  Values: price, mrp, discount_pct, stock_count, rating, rating_count. |
| days | no | integer (1-730) |  |

Request shape:

```json
{
  "op": "history",
  "subjects": [
    "example"
  ],
  "store": {
    "pincode": "560001"
  }
}
```

Try it in the playground: https://apiforagents.dev/dashboard/run?platform=zepto&op=history (sign in first).

## Notes for the agent

Measured Zepto data, one operation per call. A product's price and stock at ONE dark store, right now. Every op takes `store`: a storeId, or a pincode (with city), or lat/lon. Prices, MRP, discounts and stock are per store and every fetch adds a point to that product's price history at that store. ops: products (full detail for up to ten zepto.com product URLs at the store. Price, MRP, discount, stock count, rating, seller, manufacturer, specifications), search (what a shopper at that store sees for a query. Listings with price, stock and rank), category (one page of the app's own menu at that store; names must match the app exactly, e.g. category "Atta Rice Oil Dals", subCategory "Atta". The pair must belong together), history (stored price/stock series for products already held, free). Ops are independent. Issue several as PARALLEL tool calls. Fresh fetches are charged per record; your own answer is free while fresh.
