# Unit Price Normalizer (`superfreshlabs/unit-price-normalizer`) Actor

Calculate prices per kg, liter or item from supplied product data. Exact arithmetic, explicit currencies and review flags for ambiguous quantities. No scraping, guessing missing sizes or currency conversion.

- **URL**: https://apify.com/superfreshlabs/unit-price-normalizer.md
- **Developed by:** [Chris Norman](https://apify.com/superfreshlabs) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$100.00 / 1,000 completed normalization reports

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

## Unit Price Normalizer

Calculate comparable prices per kg, liter or item from supplied pack data. Explicit currencies, exact arithmetic, ambiguity flags. No scraping or currency conversion.

### Input and output

Up to 1,000 product rows. Supported mass, volume and count units. Every product retains a result or review reason. No fetching URLs, inferring sizes, product equivalence or currency conversion.

Fictional input example:

```json
{
  "products": [
    {
      "id": "small",
      "price": "3.10",
      "currency": "USD",
      "quantityText": "500 g"
    },
    {
      "id": "review",
      "price": "5",
      "currency": "USD",
      "quantityText": "family size"
    }
  ]
}
```

Fictional report example (the dataset returns an array containing this report):

```json
{
  "results": [
    {
      "index": 0,
      "status": "normalized",
      "reasons": [],
      "input": {
        "id": "small",
        "price": "3.10",
        "currency": "USD",
        "quantityText": "500 g"
      },
      "currency": "USD",
      "dimension": "mass",
      "canonicalUnit": "kg",
      "normalizedQuantity": "0.5",
      "unitPrice": "6.200000"
    },
    {
      "index": 1,
      "status": "needs_review",
      "reasons": [
        "quantityText_ambiguous_or_unsupported_quantity_text"
      ],
      "input": {
        "id": "review",
        "price": "5",
        "currency": "USD",
        "quantityText": "family size"
      }
    }
  ],
  "summary": {
    "inputRows": 2,
    "normalizedRows": 1,
    "needsReviewRows": 1
  },
  "comparisons": []
}
```

The output is one report item in the default dataset, not one billed item per source row. No external source is fetched. Use authorized nonsensitive or redacted input. Input and results are stored by Apify under its retention/access rules; this is not a browser-local service.

### Calling from an agent

After publication, discover this Actor through Apify Store / the Apify MCP server, inspect its input schema and current pricing, then run it with a bounded budget. Retrieve the default dataset only after a successful run. Check review flags; a completed diagnostic report may describe invalid input records. Never assume reviewed data is safe to import or execute.

### Pricing and delivery

Trial price: USD 0.10 per completed report, not per input row. Check the current Store pricing before running; that listing is authoritative. One paid event `report`, with no paid startup/default-dataset events and no platform-usage passthrough. Set a spending budget before starting. Demand and margin remain unvalidated. The adapter supports FREE/unpriced testing and this single-event PPE model and rejects other paid configurations.

Invalid batch input fails before our custom charge. Reports containing row-level review findings are completed reports. Storage and billing are not transactional: a delivery/billing error is marked uncertain where possible and is never retried automatically. Existing dataset/status evidence blocks restarting the same run. Inspect delivery and charges before any manual retry; a new run is a new purchase.

Built by SuperFresh Labs. No customer results, usage or income claimed.

# Actor input Schema

## `products` (type: `array`):

Each object supplies id, price, currency, and quantityText (e.g. 500g or 6x330ml) or quantity {value,unit,packCount}. price/value accept a decimal string or JSON number; avoid locale separators. Supported units: mg,g,kg,ml,cl,l,each,ct,pcs. packCount defaults to 1. Optional comparisonGroup explicitly asserts comparable products; comparisons never cross currencies or dimensions. Optional sourceUrl is metadata only. Row validation remains explicit in output; no missing quantity is guessed.

## Actor input object example

```json
{
  "products": [
    {
      "id": "rice-500",
      "price": "2.50",
      "currency": "USD",
      "comparisonGroup": "plain-rice",
      "quantityText": "500g"
    },
    {
      "id": "rice-1kg",
      "price": "4.00",
      "currency": "USD",
      "comparisonGroup": "plain-rice",
      "quantity": {
        "value": "1",
        "unit": "kg",
        "packCount": 1
      }
    }
  ]
}
```

# Actor output Schema

## `report` (type: `string`):

Up to 1,000 product rows. Supported mass, volume and count units. Every product retains a result or review reason. No fetching URLs, inferring sizes, product equivalence or currency conversion. One report item in a JSON array.

# 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 = {
    "products": [
        {
            "id": "rice-500",
            "price": "2.50",
            "currency": "USD",
            "comparisonGroup": "plain-rice",
            "quantityText": "500g"
        },
        {
            "id": "rice-1kg",
            "price": "4.00",
            "currency": "USD",
            "comparisonGroup": "plain-rice",
            "quantity": {
                "value": "1",
                "unit": "kg",
                "packCount": 1
            }
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("superfreshlabs/unit-price-normalizer").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 = { "products": [
        {
            "id": "rice-500",
            "price": "2.50",
            "currency": "USD",
            "comparisonGroup": "plain-rice",
            "quantityText": "500g",
        },
        {
            "id": "rice-1kg",
            "price": "4.00",
            "currency": "USD",
            "comparisonGroup": "plain-rice",
            "quantity": {
                "value": "1",
                "unit": "kg",
                "packCount": 1,
            },
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("superfreshlabs/unit-price-normalizer").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 '{
  "products": [
    {
      "id": "rice-500",
      "price": "2.50",
      "currency": "USD",
      "comparisonGroup": "plain-rice",
      "quantityText": "500g"
    },
    {
      "id": "rice-1kg",
      "price": "4.00",
      "currency": "USD",
      "comparisonGroup": "plain-rice",
      "quantity": {
        "value": "1",
        "unit": "kg",
        "packCount": 1
      }
    }
  ]
}' |
apify call superfreshlabs/unit-price-normalizer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,superfreshlabs/unit-price-normalizer"
        }
    }
}
```

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/Hxkg9ysQPAp6E0iZi/builds/m34DRBIiCNeO6Y9C2/openapi.json
