# UK Grocery Price Matrix — Compare Supermarket Prices by EAN (`studio-amba/uk-grocery-price-matrix`) Actor

Compare grocery prices across Tesco, Sainsbury's, Asda, Morrisons, Waitrose and Aldi UK in one run. Matches products by EAN barcode with a fuzzy-name fallback and flags the cheapest retailer per product.

- **URL**: https://apify.com/studio-amba/uk-grocery-price-matrix.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 $3.00 / 1,000 matrix rows

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## UK Grocery Price Matrix

Compare grocery prices across Tesco, Sainsbury's, Asda, Morrisons, Waitrose and Aldi UK in a single run. Give it a product name or an EAN barcode, and it returns one row per product per retailer: the price, any promotion, and whether that retailer carries the product at all.

This actor does not scrape a website itself. It runs our six UK supermarket scrapers in parallel, matches what comes back by EAN barcode (with a fuzzy product-name fallback when a barcode is missing), and builds the comparison matrix from the results.

### Why use this actor?

CPG pricing teams, category managers and price-comparison sites need to know one thing constantly: what does this SKU cost at every major UK grocer, right now. Pulling that by hand from six retailer sites is slow and the barcode matching is the annoying part. This actor does the fan-out and the matching in one call and returns a flat table you can pivot in a spreadsheet or load into a pricing dashboard.

### What it returns

Each row in the output is one product at one retailer. If a retailer doesn't stock the product, you still get a row for it, marked `available: false`, so you can tell "we checked and it's not there" apart from "we didn't check."

```json
[
    {
        "query": "heinz baked beans",
        "productName": "Heinz Baked Beans 415g",
        "brand": "Heinz",
        "ean": "5000157024671",
        "retailer": "Tesco",
        "price": 1.35,
        "promoPrice": null,
        "pricePerUnit": "£0.33/100g",
        "currency": "GBP",
        "available": true,
        "url": "https://www.tesco.com/groceries/en-GB/products/...",
        "imageUrl": "https://digitalcontent.api.tesco.com/...",
        "matchType": "ean",
        "cheapestRetailer": "Aldi",
        "priceSpreadPct": 22.7,
        "absenceReason": null
    },
    {
        "query": "heinz baked beans",
        "productName": "Heinz Baked Beans 415g",
        "brand": "Heinz",
        "ean": "5000157024671",
        "retailer": "Aldi",
        "price": 1.10,
        "promoPrice": null,
        "pricePerUnit": "£0.27/100g",
        "currency": "GBP",
        "available": true,
        "url": "https://www.aldi.co.uk/heinz-baked-beans/p/...",
        "imageUrl": "https://...",
        "matchType": "ean",
        "cheapestRetailer": "Aldi",
        "priceSpreadPct": 22.7,
        "absenceReason": null
    },
    {
        "query": "heinz baked beans",
        "productName": "Heinz Baked Beans 415g",
        "brand": null,
        "ean": "5000157024671",
        "retailer": "Waitrose",
        "price": null,
        "promoPrice": null,
        "pricePerUnit": null,
        "currency": "GBP",
        "available": false,
        "url": null,
        "imageUrl": null,
        "matchType": "ean",
        "cheapestRetailer": "Aldi",
        "priceSpreadPct": 22.7,
        "absenceReason": "not_found"
    }
]
````

### Use cases

- **CPG pricing managers** tracking how their products are priced across the big six UK grocers, spotting where a retailer is undercutting the recommended shelf price.
- **Price-comparison sites** that need a live, EAN-matched feed instead of manually reconciling six product catalogues.
- **Category managers** building a competitor price index for a shopping basket of SKUs, refreshed on a schedule.
- **EAN/GTIN matching** for any team that has a barcode list and wants to know which UK grocers stock each code and at what price.

### How to scrape UK supermarket price data

1. Enter one or more products in **Search Queries**, one per line. A product name (`heinz baked beans`) or an EAN barcode (`5000157024671`) both work.
2. Choose which **Retailers** to include. Leave all six selected for the full matrix, or narrow it down if you only care about a subset.
3. Set **Max Items Per Source** to control how many candidate products each retailer contributes per query.
4. Run the actor. All selected retailers are queried in parallel per query, so adding retailers doesn't multiply the run time.
5. Open the dataset. Each matched product has one row per retailer: a price row where it's carried, an absence row where it isn't.
6. Use `cheapestRetailer` and `priceSpreadPct` to sort straight to the products with the widest price gaps.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `searchQueries` | array | Product names or EAN barcodes to price-check. Defaults to `["heinz baked beans"]`. |
| `retailers` | array | Which of the six retailers to include (`tesco`, `sainsburys`, `asda`, `morrisons`, `waitrose`, `aldi`). Empty means all. |
| `maxItemsPerSource` | integer | Max candidate products considered per retailer per query (1-50, default 15). |
| `timeoutPerSourceSecs` | integer | Max seconds to wait for each retailer scraper before treating it as failed (30-600, default 150). |
| `proxyConfiguration` | object | Proxy settings passed to the underlying retailer scrapers. UK residential is recommended. |

#### Example input

```json
{
    "searchQueries": ["heinz baked beans", "cadbury dairy milk"],
    "retailers": ["tesco", "sainsburys", "asda", "morrisons", "waitrose", "aldi"],
    "maxItemsPerSource": 15,
    "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "GB" }
}
```

### Output

| Field | Type | Description |
|-------|------|-------------|
| `query` | string | The search query this row was matched against |
| `productName` | string | Canonical product name |
| `brand` | string | Product brand, when exposed |
| `ean` | string | Normalized EAN barcode used for matching, or null |
| `retailer` | string | Tesco, Sainsbury's, Asda, Morrisons, Waitrose or Aldi |
| `price` | number | Regular price in GBP, null on an absence row |
| `promoPrice` | number | Current promotional price, when on offer |
| `pricePerUnit` | string | Retailer-formatted unit price |
| `currency` | string | Always `GBP` |
| `available` | boolean | False on an absence row |
| `url` | string | Product page URL at that retailer |
| `imageUrl` | string | Product image URL |
| `matchType` | string | `ean` (barcode match) or `name` (fuzzy match) |
| `cheapestRetailer` | string | Retailer with the lowest price for this product |
| `priceSpreadPct` | number | Percentage gap between the highest and lowest price found |
| `absenceReason` | string | `not_found` (retailer checked, doesn't carry it) or `source_failed` (that retailer's scraper timed out or errored) |

### Matching logic

Products are matched across retailers primarily by EAN/GTIN barcode, with leading zeros stripped. When one side has no barcode, the actor falls back to fuzzy name matching: product names are normalized (lowercased, punctuation stripped) and compared by token overlap, with a match requiring at least 60% overlap. `matchType` on every row tells you which method produced that group.

### Search coverage

All six retailers are queried through keyword search (as of the July 2026 update; Asda via its Algolia index, Morrisons via its platform search endpoint, Waitrose via its public product sitemap with full detail-page fetches). `absenceReason: "not_in_sample"` can still appear in rare fallback situations and deliberately does NOT claim the retailer lacks the product; a true `not_found` means the retailer's search returned no match.

### FAQ

**Does this actor scrape the retailer websites itself?**
No. It calls our own Tesco, Sainsbury's, Asda, Morrisons, Waitrose and Aldi UK scrapers and combines their output. Each of those actors is also available separately on the Store.

**Why does Aldi show a price but I can't add it to a basket?**
Aldi UK doesn't run an online supermarket. Its catalogue is browse-only, so Aldi's `price` field reflects the current in-store price shown on aldi.co.uk, not something purchasable online. It's still a valid comparison price.

**Why does one retailer show `absenceReason: "source_failed"` on every row?**
That retailer's scraper timed out or errored for that query. A single failing retailer never blocks the run; it just shows up as failed instead of not\_found so you know the difference.

**Can I search by EAN barcode instead of product name?**
Yes. Put the barcode in `searchQueries` instead of a name. It works reliably on Tesco, Sainsbury's and Aldi (which pass it straight to their own search). On Asda it also works because Asda's output includes EAN data even without a search field. Morrisons and Waitrose don't expose EAN on their catalogue listings, so barcode queries against those two fall back to name matching, which usually won't find anything for a bare number.

**How is `priceSpreadPct` calculated?**
`(highest price - lowest price) / lowest price * 100`, using the promo price where one is active, across whichever retailers actually carry the matched product. It's null when only one retailer has the product.

**How many products can I check in one run?**
Add as many lines to `searchQueries` as you need. Each query launches its own round of retailer calls, so run time scales roughly linearly with the number of queries.

**Do I need my own proxy or Bright Data key?**
No. Proxy and anti-bot handling is managed inside each underlying retailer scraper. Just run this actor with the default settings.

### Limitations

- Matching quality depends on EAN coverage. Retailers that don't expose a barcode (Morrisons, Aldi, and Waitrose unless barcode fetching is enabled on that actor) rely on fuzzy name matching, which can occasionally group similar-but-different pack sizes together.
- Prices reflect each retailer's standard online delivery pricing at the time of the run and can vary by postcode or in-store.
- Data is scraped from public retailer websites and may change without notice.

### Related actors

This matrix is built on our standalone UK grocery scrapers, each of which you can also run on its own for a full-catalogue pull:

- [Tesco Scraper](https://apify.com/studio-amba/tesco-scraper)
- [Sainsbury's Scraper](https://apify.com/studio-amba/sainsburys-scraper)
- [Asda Scraper](https://apify.com/studio-amba/asda-scraper)
- [Morrisons Scraper](https://apify.com/studio-amba/morrisons-scraper)
- [Waitrose Scraper](https://apify.com/studio-amba/waitrose-scraper)

We run this comparison as a managed service too: scheduled runs, a fixed SKU list, and delivery to your inbox, Google Sheets, or API, maintenance included. See [studioamba.dev/services](https://studioamba.dev/services/) or email <hello@studioamba.dev> for a free data sample.

# Actor input Schema

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

Products to price-check, one per line. Use a product name (e.g. 'heinz baked beans') or an EAN/GTIN barcode (e.g. '5000157024671'). Both work, but barcode matching is most reliable on Tesco, Sainsbury's and Aldi, which support native search.

## `retailers` (type: `array`):

Which UK supermarkets to include in the comparison. Leave all selected for the full matrix.

## `maxItemsPerSource` (type: `integer`):

Maximum number of candidate products to consider from each retailer per query. Higher values catch more variants but take longer and cost more.

## `timeoutPerSourceSecs` (type: `integer`):

Maximum time to wait for each underlying retailer scraper to finish. A slow or failing retailer is skipped after this and reported as an absence row rather than blocking the whole run.

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

Proxy settings passed to the underlying retailer scrapers. UK residential is recommended so prices resolve correctly.

## Actor input object example

```json
{
  "searchQueries": [
    "heinz baked beans"
  ],
  "retailers": [
    "tesco",
    "sainsburys",
    "asda",
    "morrisons",
    "waitrose",
    "aldi"
  ],
  "maxItemsPerSource": 15,
  "timeoutPerSourceSecs": 150,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}
```

# 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 = {
    "searchQueries": [
        "heinz baked beans"
    ],
    "retailers": [
        "tesco",
        "sainsburys",
        "asda",
        "morrisons",
        "waitrose",
        "aldi"
    ],
    "maxItemsPerSource": 15,
    "timeoutPerSourceSecs": 150,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GB"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/uk-grocery-price-matrix").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 = {
    "searchQueries": ["heinz baked beans"],
    "retailers": [
        "tesco",
        "sainsburys",
        "asda",
        "morrisons",
        "waitrose",
        "aldi",
    ],
    "maxItemsPerSource": 15,
    "timeoutPerSourceSecs": 150,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB",
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "heinz baked beans"
  ],
  "retailers": [
    "tesco",
    "sainsburys",
    "asda",
    "morrisons",
    "waitrose",
    "aldi"
  ],
  "maxItemsPerSource": 15,
  "timeoutPerSourceSecs": 150,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}' |
apify call studio-amba/uk-grocery-price-matrix --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/uk-grocery-price-matrix",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "UK Grocery Price Matrix — Compare Supermarket Prices by EAN",
        "description": "Compare grocery prices across Tesco, Sainsbury's, Asda, Morrisons, Waitrose and Aldi UK in one run. Matches products by EAN barcode with a fuzzy-name fallback and flags the cheapest retailer per product.",
        "version": "0.1",
        "x-build-id": "B5zjmQCNdYgJkzJ1b"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/studio-amba~uk-grocery-price-matrix/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-studio-amba-uk-grocery-price-matrix",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/studio-amba~uk-grocery-price-matrix/runs": {
            "post": {
                "operationId": "runs-sync-studio-amba-uk-grocery-price-matrix",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/studio-amba~uk-grocery-price-matrix/run-sync": {
            "post": {
                "operationId": "run-sync-studio-amba-uk-grocery-price-matrix",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchQueries": {
                        "title": "Search Queries",
                        "type": "array",
                        "description": "Products to price-check, one per line. Use a product name (e.g. 'heinz baked beans') or an EAN/GTIN barcode (e.g. '5000157024671'). Both work, but barcode matching is most reliable on Tesco, Sainsbury's and Aldi, which support native search.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "retailers": {
                        "title": "Retailers",
                        "type": "array",
                        "description": "Which UK supermarkets to include in the comparison. Leave all selected for the full matrix.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "tesco",
                                "sainsburys",
                                "asda",
                                "morrisons",
                                "waitrose",
                                "aldi"
                            ],
                            "enumTitles": [
                                "Tesco",
                                "Sainsbury's",
                                "Asda",
                                "Morrisons",
                                "Waitrose",
                                "Aldi"
                            ]
                        }
                    },
                    "maxItemsPerSource": {
                        "title": "Max Items Per Source",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of candidate products to consider from each retailer per query. Higher values catch more variants but take longer and cost more.",
                        "default": 15
                    },
                    "timeoutPerSourceSecs": {
                        "title": "Timeout Per Source (seconds)",
                        "minimum": 30,
                        "maximum": 600,
                        "type": "integer",
                        "description": "Maximum time to wait for each underlying retailer scraper to finish. A slow or failing retailer is skipped after this and reported as an absence row rather than blocking the whole run.",
                        "default": 150
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings passed to the underlying retailer scrapers. UK residential is recommended so prices resolve correctly."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
