# Freight Invoice & Surcharge Auditor (`afkdigital/newapi75-freight-invoice-surcharge-auditor`) Actor

Review freight invoice CSV/XLSX against your own contract tariffs with Decimal calculations, fuel and dimensional weight evidence. No OCR or carrier login.

- **URL**: https://apify.com/afkdigital/newapi75-freight-invoice-surcharge-auditor.md
- **Developed by:** [AFK Digital](https://apify.com/afkdigital) (community)
- **Categories:** Business, E-commerce
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$12.00 / 1,000 successfully reviewed unique shipments

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

## Freight Invoice & Surcharge Auditor

Compare structured freight invoices with **your own contract rate card and surcharge rules**. Get a reproducible expected charge, invoice difference, source row references and a package-by-package Decimal calculation. Use the results to prioritize a billing review.

This Actor does not obtain carrier tariffs, estimate zones, access carrier accounts, run OCR or use an LLM. A positive variance is **not a confirmed overcharge or refund entitlement**. Contract exclusions, separate packages, credit notes and corrections can require human reconciliation.

### Quick start

The prefilled input contains 16 realistic synthetic invoice rows covering 11 unique shipments. Seven shipments can be calculated; four require manual reconciliation. It uses simulated contract rates, not a carrier's confidential tariff. Expected result events: **7 × $0.012 = $0.084**.

Replace both file descriptors with your files and supply explicit surcharge rules. JSON details, CSV details, a currency-separated JSON summary and an HTML review report appear in the Output tab. The default Dataset contains one row per unique shipment ID.

#### Files

Each of `invoiceFile` and `rateCardFile` is a JSON descriptor:

- UTF-8 CSV: `{"format":"csv","text":"shipment_id,...\n..." }`
- XLSX: `{"format":"xlsx","base64":"BASE64_FILE_BYTES","sheet":"Data"}`
- Existing Apify upload: `{"format":"csv","url":"https://api.apify.com/v2/key-value-stores/STORE_ID/records/invoice.csv"}`

Upload your file to an Apify key-value store and use its HTTPS record URL. Select its store under fileStores to grant this run read-only access. Embedded CSV/base64 needs no storage permission. Arbitrary remote URLs, URL query strings (including embedded tokens), redirects, local file paths and legacy XLS/XLSM are rejected. Supply format explicitly when the record key has no extension. Multiple-sheet workbooks require an explicit sheet name. Data stays in the run's Apify storage; choose suitable account access and retention settings.

### Invoice columns

Column names below are canonical and case-sensitive. Monetary values are plain decimal text, without currency symbols, grouping separators or exponent notation. Dates are ISO YYYY-MM-DD. Decimal inputs support up to 12 fractional digits and absolute values up to 1 trillion. Weight is **kg**, dimensions are **cm**.

| Column | Meaning |
|---|---|
| shipment_id | Required string, unique customer shipment identity; all charge lines and packages share this ID |
| package_id | String; omitted/blank means one DEFAULT package |
| tracking_number | Required package tracking string; use text cells in XLSX to preserve leading zeroes |
| service, zone | Exact customer-defined contract identifiers; no fuzzy matching |
| invoice_date | Required ISO date; explicitly used as the **tariff rating date in v1** |
| actual_weight, billed_weight | Actual kg used for rating and invoiced kg used for comparison |
| length_cm, width_cm, height_cm | All three dimensions required; explicit three zeroes indicate no dimensional weight applies |
| charge_type | TRANSPORT, FUEL or an exact customer surcharge code |
| record_type | CHARGE, CREDIT or ADJUSTMENT; credits/adjustments require manual reconciliation |
| amount | Signed line amount; negative CHARGE is not automatically interpreted as a credit |
| currency | Exact three-uppercase-letter code; optional input currency fills only blank invoice currency |

Repeat package metadata on each charge line or leave supplemental metadata blank. Conflicting nonblank values stop that shipment's calculation. If your contract rates by shipping date rather than invoice date, map the agreed contract rating date into invoice_date; the output invoice_date then represents that supplied rating date. V1 cannot independently reconcile multiple rating dates for one package.

### Rate card columns

Every applicable row must explicitly provide:

| Column | Rule |
|---|---|
| rate_id | Your contract reference |
| effective_from, effective_to | Inclusive ISO date range |
| service, zone, currency | Exact match to package metadata |
| weight_from_exclusive, weight_to_inclusive | Lower-exclusive / upper-inclusive band, applied to rounded rated kg |
| base_charge, per_kg_charge | Gross transport = base + per-kg × rated kg; set either explicitly to 0 when unused |
| weight_increment_kg | Positive rounding increment; rated kg rounds **up** |
| dimensional_divisor | cm³/kg divisor; 0 explicitly disables dimensional rating, and then nonzero dimensions are rejected |
| minimum_charge | Nonnegative transport floor |
| minimum_order | BEFORE_DISCOUNT or AFTER_DISCOUNT |
| discount_percent | 0–100, affects transport only |
| discount_order | BEFORE_FUEL or AFTER_FUEL |
| fuel_percent | Explicit 0–100; use 0 for no fuel |
| fuel_basis | TRANSPORT or TRANSPORT_AND_ELIGIBLE_SURCHARGES |
| currency_decimals | Integer 0–4, explicit contract monetary precision |

For each candidate tariff, dimensional kg = length × width × height / divisor. Rated kg = ceil(max(actual kg, dimensional kg) / increment) × increment. Exactly one dated band must match. Missing/overlapping tariffs produce a null expected charge.

Gross transport is rounded HALF_UP. BEFORE_DISCOUNT applies the minimum to gross transport then the discount; AFTER_DISCOUNT applies the minimum after discount. BEFORE_FUEL calculates fuel from that final discounted transport. AFTER_FUEL uses transport before discount for fuel, then applies the transport discount/final minimum. Extras are never discounted. Each component is rounded HALF_UP to the explicit currency precision before summing. Contracts needing another sequence, tier accumulation, piecewise rates, taxes, duties, currency conversion, or discount on surcharges are outside v1; do not represent them using guessed rules.

Example: base 10 + 2/kg × 3 kg = 16; minimum 15 BEFORE_DISCOUNT; 10% discount BEFORE_FUEL gives 14.40; fuel 20% gives 2.88; expected total **17.28 USD**. With 50×40×30 cm and divisor 5000, rated weight is 12 kg and expected total is **36.72 USD**.

### Surcharge rules

`surchargeRules` is an array of exact dated rules, for example:

```json
[{
  "rule_id": "REMOTE-2026",
  "code": "REMOTE",
  "service": "GROUND",
  "zone": "2",
  "currency": "USD",
  "effective_from": "2026-01-01",
  "effective_to": "2026-12-31",
  "kind": "FIXED",
  "value": "5",
  "fuel_eligible": true,
  "applies_when": "INVOICE_CODE_PRESENT"
}]
```

Supported kinds: FIXED and PERCENT_TRANSPORT (percentage of final discounted transport). ALWAYS applies the rule to every matching package even if its charge code is missing from the invoice. INVOICE_CODE_PRESENT applies only when that code is present; **it cannot discover an omitted conditional surcharge**. Rules apply once per package. Every rule requires an explicit boolean fuel_eligible. This affects fuel only with TRANSPORT_AND_ELIGIBLE_SURCHARGES. Multiple applicable rules for a code, or an invoiced code without an explicit matching rule, produce an uncalculable result.

No surcharge rules means you explicitly supply no extra-charge rules beyond the tariff's fuel. It does not certify that your contract has no additional conditions.

### Column mapping and limits

`columnMapping`: `{"invoice":{"shipment_id":"Shipment Reference","amount":"Net Amount"},"rateCard":{"zone":"Contract Zone"}}`. Map canonical keys to exact source headers. Canonical/source collisions and duplicate source mappings are rejected.

`tolerance` is a nonnegative absolute Decimal (default 0.01, maximum 1000), independently applied in each currency. No conversion is performed.

Hard limits: 10 MiB per file, 50,000 invoice rows, 10,000 rate rows, 1,000 surcharge rules, 128 columns, 4,096 characters per cell, 64 MiB expanded XLSX, 1,000 ZIP members and 2 million visited XLSX cells. `maxShipments` defaults to 1,000 and supports 1–10,000; excess unique IDs reject the whole input before charging. Default memory 256 MB; hard run timeout 240 seconds.

Only CSV and XLSX are supported. Formulas and error cells on the selected sheet, macros, embedded objects and external workbook connections/relationships are rejected; nothing is executed. XLSX shipment/package/tracking identifiers must be text. Customer rows, invoice amounts and file contents are not written to application logs. Error logs contain only fixed diagnostic codes.

### Findings and exports

Evidence row indexes count source records including the header and blank records; XLSX indexes are worksheet rows.

Output fields: shipment_id, tracking_number, service, invoice_date, billed_weight, expected_charge, invoiced_charge, difference, currency, finding_type, evidence_rows, calculation_breakdown. Additional fields: reason, billable, review_flags.

All monetary values are **decimal strings** (or null) to preserve precision. Difference = invoiced minus expected. WITHIN_TOLERANCE, POSITIVE_VARIANCE_REVIEW and NEGATIVE_VARIANCE_REVIEW are calculated comparisons. UNCALCULABLE_REVIEW has expected_charge/difference null with a reason and no shipment event.

Duplicate identical invoice rows and repeated charge codes within one package are ambiguous and uncalculable. Tracking reuse across different shipment IDs is flagged for context, without labeling either as an overcharge. Distinct package_id values are rated separately under one shipment ID. CREDIT/ADJUSTMENT records, missing tariffs and conflicting metadata are uncalculable; their invoice rows remain available for review. A null top-level service/tracking/date can mean different values across packages; package evidence retains the calculation.

- DETAILS: complete JSON array.
- DETAILS.csv: flat columns; nested calculations/evidence serialized as JSON cells. Potential spreadsheet formula prefixes are escaped with an apostrophe, including negative strings; JSON preserves original values.
- SUMMARY: counts and totals per currency, **calculable shipments only**.
- REPORT: readable HTML review summary.
- Default Dataset: same one-row-per-shipment results; export JSON/CSV through Apify.

### Pricing and billing

**$0.012 per successfully calculated and saved unique shipment_id ($12 per 1,000).** Platform run usage is included in this event price. No start event, no separate invoice-line, fuel-line or package event.

Uncalculable shipments, credit/correction reviews and ambiguous duplicates are **free**. File/input errors and technical failures add no event for failed work; already saved successful shipments before a later failure remain billed. The runtime validates the active event price and rejects unexpected extra billing events.

Set Apify's maximum total charge per run as well as maxShipments. The run stops before saving the next billable shipment when the budget cannot cover it; the summary identifies omitted shipments. Previously saved shipment IDs are skipped on resurrection without recharging. An interruption between saving and charging may leave a free result. Uniqueness is per run; a new run performs and bills a new review. Apify may charge separate post-run storage/export operations according to your plan.

### Development and versions

Product NEWAPI75, software 1.0.0. Python 3.13; apify 4.2.1 (Apache-2.0), openpyxl 3.1.5 (MIT), defusedxml 0.7.1 (PSF), httpx 0.28.1 (BSD-3-Clause). Pinned dependencies are in requirements.txt. Their published package metadata was checked on 2026-11-06.

`python -m unittest discover -s tests -v` runs controlled financial, ambiguity, parsing and billing tests. Fixtures are synthetic; no carrier account or paid data service is required.

Official implementation references: [Apify PPE](https://docs.apify.com/actors/monetize/pay-per-event), [Python SDK charging](https://docs.apify.com/sdk/python/docs/concepts/pay-per-event), [openpyxl formula behavior](https://openpyxl.readthedocs.io/en/stable/simple_formulae.html), [Python Decimal](https://docs.python.org/3/library/decimal.html).

AFK Data Team / AFK Mesh.

# Actor input Schema

## `invoiceFile` (type: `object`):

File descriptor: {format:csv,text:...}, {format:xlsx,base64:...} or {format:csv|xlsx,url:HTTPS Apify KVS record URL}. No query string. XLSX sheet optional, required for multiple sheets. UTF-8 CSV, kg/cm, ISO dates. Formulas/macros rejected. See README columns.

## `rateCardFile` (type: `object`):

Same file descriptors as invoiceFile. Explicit tariff rows required; no external rates or zones are inferred.

## `surchargeRules` (type: `array`):

Explicit rule objects. See README for date, zone, service, kind, value, fuel_eligible and applies_when fields.

## `columnMapping` (type: `object`):

{invoice:{canonical:source_header},rateCard:{canonical:source_header}}. Identity columns must be text in XLSX.

## `currency` (type: `string`):

ISO currency only when missing from invoice rows. Never overrides an existing currency. No FX conversion.

## `tolerance` (type: `string`):

Nonnegative decimal in each shipment currency, e.g. 0.01. At most 1000.

## `maxShipments` (type: `integer`):

Input above this limit fails before charging. Extra charge lines/packages share the shipment event.

## `fileStores` (type: `array`):

When using record URLs, select the key-value stores containing your invoice and rate card. Not needed for embedded CSV/base64.

## Actor input object example

```json
{
  "invoiceFile": {
    "format": "csv",
    "text": "shipment_id,package_id,tracking_number,service,zone,invoice_date,actual_weight,billed_weight,length_cm,width_cm,height_cm,charge_type,record_type,amount,currency\r\nS-CORRECT,P1,TRK-S-CORRECT,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-CORRECT,P1,TRK-S-CORRECT,GROUND,2,2026-06-01,3,3,0,0,0,FUEL,CHARGE,2.88,USD\r\nS-VARIANCE,P1,TRK-S-VARIANCE,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,20,USD\r\nS-DIM,P1,TRK-S-DIM,GROUND,2,2026-06-01,3,3,50,40,30,TRANSPORT,CHARGE,36.72,USD\r\nS-PERIOD,P1,TRK-S-PERIOD,GROUND,2,2026-07-01,3,3,0,0,0,TRANSPORT,CHARGE,28.08,USD\r\nS-CREDIT,P1,TRK-S-CREDIT,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CREDIT,-5,USD\r\nS-MISSING,P1,TRK-S-MISSING,GROUND,9,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-DUP,P1,TRK-S-DUP,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-DUP,P1,TRK-S-DUP,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-MULTI,P1,TRK-S-MULTI,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,USD\r\nS-MULTI,P2,TRK-S-MULTI,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,USD\r\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,REMOTE,CHARGE,5,USD\r\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,FUEL,CHARGE,3.88,USD\r\nS-EUR,P1,TRK-S-EUR,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,EUR\r\nS-ADJUST,P1,TRK-S-ADJUST,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,ADJUSTMENT,2,USD\r\n"
  },
  "rateCardFile": {
    "format": "csv",
    "text": "rate_id,effective_from,effective_to,service,zone,currency,weight_from_exclusive,weight_to_inclusive,base_charge,per_kg_charge,weight_increment_kg,dimensional_divisor,minimum_charge,minimum_order,discount_percent,discount_order,fuel_percent,fuel_basis,currency_decimals\r\nR1,2026-01-01,2026-06-30,GROUND,2,USD,0,100,10,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT_AND_ELIGIBLE_SURCHARGES,2\r\nR2,2026-07-01,2026-12-31,GROUND,2,USD,0,100,20,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT,2\r\nEUR1,2026-01-01,2026-12-31,GROUND,2,EUR,0,100,10,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT,2\r\n"
  },
  "surchargeRules": [
    {
      "rule_id": "REM1",
      "code": "REMOTE",
      "service": "GROUND",
      "zone": "2",
      "currency": "USD",
      "effective_from": "2026-01-01",
      "effective_to": "2026-12-31",
      "kind": "FIXED",
      "value": "5",
      "fuel_eligible": true,
      "applies_when": "INVOICE_CODE_PRESENT"
    }
  ],
  "columnMapping": {},
  "currency": "USD",
  "tolerance": "0.01",
  "maxShipments": 1000
}
```

# Actor output Schema

## `detailsJson` (type: `string`):

No description

## `detailsCsv` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `report` (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 = {
    "invoiceFile": {
        "format": "csv",
        "text": "shipment_id,package_id,tracking_number,service,zone,invoice_date,actual_weight,billed_weight,length_cm,width_cm,height_cm,charge_type,record_type,amount,currency\r\nS-CORRECT,P1,TRK-S-CORRECT,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-CORRECT,P1,TRK-S-CORRECT,GROUND,2,2026-06-01,3,3,0,0,0,FUEL,CHARGE,2.88,USD\r\nS-VARIANCE,P1,TRK-S-VARIANCE,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,20,USD\r\nS-DIM,P1,TRK-S-DIM,GROUND,2,2026-06-01,3,3,50,40,30,TRANSPORT,CHARGE,36.72,USD\r\nS-PERIOD,P1,TRK-S-PERIOD,GROUND,2,2026-07-01,3,3,0,0,0,TRANSPORT,CHARGE,28.08,USD\r\nS-CREDIT,P1,TRK-S-CREDIT,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CREDIT,-5,USD\r\nS-MISSING,P1,TRK-S-MISSING,GROUND,9,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-DUP,P1,TRK-S-DUP,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-DUP,P1,TRK-S-DUP,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-MULTI,P1,TRK-S-MULTI,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,USD\r\nS-MULTI,P2,TRK-S-MULTI,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,USD\r\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,REMOTE,CHARGE,5,USD\r\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,FUEL,CHARGE,3.88,USD\r\nS-EUR,P1,TRK-S-EUR,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,EUR\r\nS-ADJUST,P1,TRK-S-ADJUST,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,ADJUSTMENT,2,USD\r\n"
    },
    "rateCardFile": {
        "format": "csv",
        "text": "rate_id,effective_from,effective_to,service,zone,currency,weight_from_exclusive,weight_to_inclusive,base_charge,per_kg_charge,weight_increment_kg,dimensional_divisor,minimum_charge,minimum_order,discount_percent,discount_order,fuel_percent,fuel_basis,currency_decimals\r\nR1,2026-01-01,2026-06-30,GROUND,2,USD,0,100,10,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT_AND_ELIGIBLE_SURCHARGES,2\r\nR2,2026-07-01,2026-12-31,GROUND,2,USD,0,100,20,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT,2\r\nEUR1,2026-01-01,2026-12-31,GROUND,2,EUR,0,100,10,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT,2\r\n"
    },
    "surchargeRules": [
        {
            "rule_id": "REM1",
            "code": "REMOTE",
            "service": "GROUND",
            "zone": "2",
            "currency": "USD",
            "effective_from": "2026-01-01",
            "effective_to": "2026-12-31",
            "kind": "FIXED",
            "value": "5",
            "fuel_eligible": true,
            "applies_when": "INVOICE_CODE_PRESENT"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("afkdigital/newapi75-freight-invoice-surcharge-auditor").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 = {
    "invoiceFile": {
        "format": "csv",
        "text": """shipment_id,package_id,tracking_number,service,zone,invoice_date,actual_weight,billed_weight,length_cm,width_cm,height_cm,charge_type,record_type,amount,currency\r
S-CORRECT,P1,TRK-S-CORRECT,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r
S-CORRECT,P1,TRK-S-CORRECT,GROUND,2,2026-06-01,3,3,0,0,0,FUEL,CHARGE,2.88,USD\r
S-VARIANCE,P1,TRK-S-VARIANCE,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,20,USD\r
S-DIM,P1,TRK-S-DIM,GROUND,2,2026-06-01,3,3,50,40,30,TRANSPORT,CHARGE,36.72,USD\r
S-PERIOD,P1,TRK-S-PERIOD,GROUND,2,2026-07-01,3,3,0,0,0,TRANSPORT,CHARGE,28.08,USD\r
S-CREDIT,P1,TRK-S-CREDIT,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CREDIT,-5,USD\r
S-MISSING,P1,TRK-S-MISSING,GROUND,9,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r
S-DUP,P1,TRK-S-DUP,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r
S-DUP,P1,TRK-S-DUP,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r
S-MULTI,P1,TRK-S-MULTI,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,USD\r
S-MULTI,P2,TRK-S-MULTI,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,USD\r
S-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\r
S-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,REMOTE,CHARGE,5,USD\r
S-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,FUEL,CHARGE,3.88,USD\r
S-EUR,P1,TRK-S-EUR,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,EUR\r
S-ADJUST,P1,TRK-S-ADJUST,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,ADJUSTMENT,2,USD\r
""",
    },
    "rateCardFile": {
        "format": "csv",
        "text": """rate_id,effective_from,effective_to,service,zone,currency,weight_from_exclusive,weight_to_inclusive,base_charge,per_kg_charge,weight_increment_kg,dimensional_divisor,minimum_charge,minimum_order,discount_percent,discount_order,fuel_percent,fuel_basis,currency_decimals\r
R1,2026-01-01,2026-06-30,GROUND,2,USD,0,100,10,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT_AND_ELIGIBLE_SURCHARGES,2\r
R2,2026-07-01,2026-12-31,GROUND,2,USD,0,100,20,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT,2\r
EUR1,2026-01-01,2026-12-31,GROUND,2,EUR,0,100,10,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT,2\r
""",
    },
    "surchargeRules": [{
            "rule_id": "REM1",
            "code": "REMOTE",
            "service": "GROUND",
            "zone": "2",
            "currency": "USD",
            "effective_from": "2026-01-01",
            "effective_to": "2026-12-31",
            "kind": "FIXED",
            "value": "5",
            "fuel_eligible": True,
            "applies_when": "INVOICE_CODE_PRESENT",
        }],
}

# Run the Actor and wait for it to finish
run = client.actor("afkdigital/newapi75-freight-invoice-surcharge-auditor").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 '{
  "invoiceFile": {
    "format": "csv",
    "text": "shipment_id,package_id,tracking_number,service,zone,invoice_date,actual_weight,billed_weight,length_cm,width_cm,height_cm,charge_type,record_type,amount,currency\\r\\nS-CORRECT,P1,TRK-S-CORRECT,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\\r\\nS-CORRECT,P1,TRK-S-CORRECT,GROUND,2,2026-06-01,3,3,0,0,0,FUEL,CHARGE,2.88,USD\\r\\nS-VARIANCE,P1,TRK-S-VARIANCE,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,20,USD\\r\\nS-DIM,P1,TRK-S-DIM,GROUND,2,2026-06-01,3,3,50,40,30,TRANSPORT,CHARGE,36.72,USD\\r\\nS-PERIOD,P1,TRK-S-PERIOD,GROUND,2,2026-07-01,3,3,0,0,0,TRANSPORT,CHARGE,28.08,USD\\r\\nS-CREDIT,P1,TRK-S-CREDIT,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CREDIT,-5,USD\\r\\nS-MISSING,P1,TRK-S-MISSING,GROUND,9,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\\r\\nS-DUP,P1,TRK-S-DUP,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\\r\\nS-DUP,P1,TRK-S-DUP,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\\r\\nS-MULTI,P1,TRK-S-MULTI,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,USD\\r\\nS-MULTI,P2,TRK-S-MULTI,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,USD\\r\\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,14.40,USD\\r\\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,REMOTE,CHARGE,5,USD\\r\\nS-REMOTE,P1,TRK-S-REMOTE,GROUND,2,2026-06-01,3,3,0,0,0,FUEL,CHARGE,3.88,USD\\r\\nS-EUR,P1,TRK-S-EUR,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,CHARGE,17.28,EUR\\r\\nS-ADJUST,P1,TRK-S-ADJUST,GROUND,2,2026-06-01,3,3,0,0,0,TRANSPORT,ADJUSTMENT,2,USD\\r\\n"
  },
  "rateCardFile": {
    "format": "csv",
    "text": "rate_id,effective_from,effective_to,service,zone,currency,weight_from_exclusive,weight_to_inclusive,base_charge,per_kg_charge,weight_increment_kg,dimensional_divisor,minimum_charge,minimum_order,discount_percent,discount_order,fuel_percent,fuel_basis,currency_decimals\\r\\nR1,2026-01-01,2026-06-30,GROUND,2,USD,0,100,10,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT_AND_ELIGIBLE_SURCHARGES,2\\r\\nR2,2026-07-01,2026-12-31,GROUND,2,USD,0,100,20,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT,2\\r\\nEUR1,2026-01-01,2026-12-31,GROUND,2,EUR,0,100,10,2,1,5000,15,BEFORE_DISCOUNT,10,BEFORE_FUEL,20,TRANSPORT,2\\r\\n"
  },
  "surchargeRules": [
    {
      "rule_id": "REM1",
      "code": "REMOTE",
      "service": "GROUND",
      "zone": "2",
      "currency": "USD",
      "effective_from": "2026-01-01",
      "effective_to": "2026-12-31",
      "kind": "FIXED",
      "value": "5",
      "fuel_eligible": true,
      "applies_when": "INVOICE_CODE_PRESENT"
    }
  ]
}' |
apify call afkdigital/newapi75-freight-invoice-surcharge-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afkdigital/newapi75-freight-invoice-surcharge-auditor"
        }
    }
}
```

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/1M6n6mxa0Tc8X7sag/builds/R8ELYIMSag2v4Vtwk/openapi.json
