# CSV Reconciliation Audit — Exact Keys & Amount Differences (`mick_mouse/my-actor`) Actor

Reconcile two CSV exports by unique keys. Detect amount differences and unmatched records with exact decimal arithmetic and explicit separators. Get a JSON report for agents and automation workflows. No bank access or currency conversion.

- **URL**: https://apify.com/mick_mouse/my-actor.md
- **Developed by:** [Miguel Stuardo](https://apify.com/mick_mouse) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $250.00 / 1,000 completed csv reconciliation 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

## CSV Reconciliation Audit

Compare two UTF-8 CSV exports by exact keys and identify amount differences before importing data into another workflow. Built for agent pipelines, automation developers and operations teams.

### What you receive

One JSON report in the default dataset, including:

- Matched records within the amount tolerance you specify.
- Amount discrepancies, with the signed difference (right minus left).
- Records found only in the left or right file.
- Summary counts, declared currency and matching policy.

### Example

```json
{
  "leftCsv": "id;amount\n001;1.234,56\n002;100,00",
  "rightCsv": "id;amount\n001;1.234,57\n002;90,00",
  "delimiter": ";",
  "keys": ["id"],
  "amountColumn": "amount",
  "decimalSeparator": ",",
  "groupSeparator": ".",
  "tolerance": "0.01",
  "currency": "CLP"
}
```

Record `001` matches within tolerance. Record `002` has a difference of `-10.00`. Identifiers remain strings, so leading zeros are preserved. Calculations use exact decimal arithmetic.

### Input requirements

Supply CSV text directly, not file URLs. Declare the delimiter, the normalized key column names, one amount column and its separators. Header normalization lowercases names, replaces non-word runs with underscores, and assigns unique suffixes when necessary. Inspect column names locally if your source has complex or duplicate headings.

The key can have multiple columns, but each combined key must be unique and nonempty in each file. The amount column cannot be part of the key. Both CSVs must use the same separators and currency. Currency is your declaration; the Actor does not verify currency against individual rows. Empty amounts, malformed numbers, inconsistent column counts or duplicate keys cause the run to fail without a custom report charge.

### Pricing unit

One completed report is one `reconciliation-report` event, regardless of matching or unmatched row count. The current configured event price must be checked in the Pricing tab before running. An automatic Actor start event may also apply as shown there. Invalid inputs do not trigger our custom report event; platform start or usage charges may still apply. No separate custom per-row charge is requested.

### Limits

- Total serialized input: 1,000,000 UTF-8 bytes.
- Up to 10,000 nonblank records and 200 columns per CSV.
- Maximum serialized report: 8,000,000 bytes; larger reports are rejected before a custom charge is attempted.
- One-to-one exact matching; no fuzzy matching, many-to-one aggregation or currency conversion.
- No Excel, PDF, image parsing, external URLs, bank connection or ERP writes.

The report is a data comparison, not confirmation that funds moved or accounting records are correct. A tolerance match does not prove that two transactions represent the same real-world event. Check key selection and results before acting.

### Privacy

This hosted version receives input through Apify and stores the output in the run's dataset. Apify also stores run inputs and platform metadata according to its settings and policies. Do not assume zero retention. Only send files you are authorized to process. The application does not call a language model, fetch external URLs, execute CSV formulas, or log file contents. Use your platform storage settings to manage access and retention.

### Automation

After publication, invoke this Actor with the Apify API or a compatible Apify MCP client using the input above. Publication, pricing and access settings are controlled by the publisher. This source package itself is not a live paid service.

# Actor input Schema

## `leftCsv` (type: `string`):

UTF-8 CSV content for the left side. No URLs.

## `rightCsv` (type: `string`):

UTF-8 CSV content for the right side. No URLs.

## `delimiter` (type: `string`):

Same delimiter in both CSVs.

## `keys` (type: `array`):

Normalized column names; each combined key must be unique and nonempty.

## `amountColumn` (type: `string`):

Normalized name of the one amount column, not a key.

## `decimalSeparator` (type: `string`):

Declare decimal separator explicitly.

## `groupSeparator` (type: `string`):

Use an empty string if numbers have no thousands separator. Must differ from decimal separator.

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

Nonnegative decimal with a dot, e.g. 0.01.

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

Declare the single currency used by both files; contents are not independently verified.

## Actor input object example

```json
{
  "leftCsv": "id;amount\n001;1.234,56\n002;100,00",
  "rightCsv": "id;amount\n001;1.234,57\n002;90,00",
  "delimiter": ";",
  "keys": [
    "id"
  ],
  "amountColumn": "amount",
  "decimalSeparator": ",",
  "groupSeparator": ".",
  "tolerance": "0.01",
  "currency": "CLP"
}
```

# Actor output Schema

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

Dataset array containing one completed report.

# 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 = {
    "leftCsv": `id;amount
001;1.234,56
002;100,00`,
    "rightCsv": `id;amount
001;1.234,57
002;90,00`,
    "keys": [
        "id"
    ],
    "amountColumn": "amount",
    "decimalSeparator": ",",
    "groupSeparator": ".",
    "currency": "CLP"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mick_mouse/my-actor").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 = {
    "leftCsv": """id;amount
001;1.234,56
002;100,00""",
    "rightCsv": """id;amount
001;1.234,57
002;90,00""",
    "keys": ["id"],
    "amountColumn": "amount",
    "decimalSeparator": ",",
    "groupSeparator": ".",
    "currency": "CLP",
}

# Run the Actor and wait for it to finish
run = client.actor("mick_mouse/my-actor").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 '{
  "leftCsv": "id;amount\\n001;1.234,56\\n002;100,00",
  "rightCsv": "id;amount\\n001;1.234,57\\n002;90,00",
  "keys": [
    "id"
  ],
  "amountColumn": "amount",
  "decimalSeparator": ",",
  "groupSeparator": ".",
  "currency": "CLP"
}' |
apify call mick_mouse/my-actor --silent --output-dataset

```

## MCP server setup

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

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/Tx4iw1qbgYp3GXare/builds/j0Pgm1j0ZFhE0pdyC/openapi.json
