# CSV Schema Gate — Locale-Aware Import Preflight (`mick_mouse/my-actor-1`) Actor

Validate CSV required cells, uniqueness, declared decimal separators and explicit dates. Preserve leading-zero IDs and get row/column diagnostics before importing data into automation workflows. No inferred types or external URLs.

- **URL**: https://apify.com/mick_mouse/my-actor-1.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 $20.00 / 1,000 completed csv validation 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 Schema Gate

Validate a UTF-8 CSV export against explicit column rules before an import. Detect missing required cells, duplicates, malformed locale-specific decimals and invalid calendar dates. Leading-zero IDs remain strings. No type inference or source-system connection.

### Output

One JSON report in the default dataset: `status` (`valid` or `invalid`), `recordCount`, `errorCount`, `columns`, and `errors` with 1-based data record number, exact column header and code (`required`, `not_unique`, `invalid_decimal`, `invalid_date`). A completed report with invalid cells is normal useful output, not an Actor failure. Invalid request structure or CSV parsing fails the run without a custom report event.

Optional `includePreview` adds original records, canonical records and proposed changes. Cells failing conversion retain their original values: do not import a preview while status is invalid.

### Example

```json
{
  "csv": "id;amount;date\n001;1.234,50;2026-10-26\n002;1234,500;2026-02-30",
  "delimiter": ";",
  "schema": {
    "id": {"type": "text", "required": true, "unique": true},
    "amount": {"type": "decimal", "decimal_separator": ",", "group_separator": ".", "unique": true},
    "date": {"type": "date", "format": "%Y-%m-%d"}
  },
  "includePreview": false
}
```

This example identifies record 2's duplicate numeric amount and February 30. `001` remains `001`. Decimal uniqueness compares numeric values, so `1,00` and `1,000` are equal when comma is the declared decimal separator.

### Rules and parsing

Supply CSV text, not a URL. Declare comma, semicolon, tab or pipe delimiter. Schema keys must match exact column headers: headers must be nonempty, unique and have no surrounding whitespace. Headers are never silently renamed. UTF-8 BOM is accepted.

Rules support `type` (`text`, `decimal`, `date`; default `text`), `required` and `unique` booleans. Decimal rules accept `decimal_separator` (`.` or `,`) and `group_separator` (empty, `.`, `,` or space); they must differ. Grouped numbers require groups of three. No currency symbols, exponents, NaN, whitespace or parenthesized negatives.

Dates require explicit `format`: `%Y-%m-%d`, `%d/%m/%Y` or `%m/%d/%Y`, with exact widths and calendar validity. No timestamps or timezone inference. Empty cells become null; optional empty cells skip type and uniqueness checks. Other strings, including whitespace, remain unchanged. Completely blank physical lines are skipped. Record indexes count parsed data records, not physical lines.

### Pricing unit

One completed report requests one `validation-report` event, regardless of row count or validation status. Check the Pricing tab for the current price and any automatic Actor start event. No separate custom per-row charge. Malformed requests do not trigger the custom report event; start/platform charges can still apply.

### Limits

- At most 1,000,000 serialized input bytes, 10,000 data records and 200 columns.
- Maximum serialized output 8,000,000 bytes; disable preview or split the input if larger.
- No URLs, Excel/PDF/image parsing, conditional rules, regex rules, fuzzy matching, cross-file reconciliation, sum checks, ERP writes or accounting certification.
- Formula-like text is returned as data, never executed. Downstream spreadsheet exports need their own formula-injection protection.

### Privacy

The hosted Actor receives input through Apify and stores the report in the default dataset. Apify retains inputs, run metadata and storage under its settings/policies. Do not assume zero retention. Only submit data you are authorized to process. The application does not call an LLM, fetch external URLs or log cell contents. Configure platform access and retention for your needs.

### Automation

Call through the Apify API or a compatible Apify MCP client using the same JSON input. A successful run returns one report, including when the CSV fails declared cell rules. Inspect `status` before a downstream import. This is a deterministic validation aid, not proof that the underlying records are factually correct.

# Actor input Schema

## `csv` (type: `string`):

CSV text with unique exact headers; not a URL.

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

Explicit delimiter.

## `schema` (type: `object`):

Exact header names mapped to explicit rules.

## `includePreview` (type: `boolean`):

Include original and canonical records; inspect validation status.

## Actor input object example

```json
{
  "csv": "id;amount;date\n001;1.234,50;2026-10-26\n002;1234,500;2026-02-30",
  "delimiter": ";",
  "schema": {
    "id": {
      "type": "text",
      "required": true,
      "unique": true
    },
    "amount": {
      "type": "decimal",
      "decimal_separator": ",",
      "group_separator": ".",
      "unique": true
    },
    "date": {
      "type": "date",
      "format": "%Y-%m-%d"
    }
  },
  "includePreview": true
}
```

# Actor output Schema

## `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 = {
    "csv": `id;amount;date
001;1.234,50;2026-10-26
002;1234,500;2026-02-30`,
    "delimiter": ";",
    "schema": {
        "id": {
            "type": "text",
            "required": true,
            "unique": true
        },
        "amount": {
            "type": "decimal",
            "decimal_separator": ",",
            "group_separator": ".",
            "unique": true
        },
        "date": {
            "type": "date",
            "format": "%Y-%m-%d"
        }
    },
    "includePreview": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("mick_mouse/my-actor-1").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 = {
    "csv": """id;amount;date
001;1.234,50;2026-10-26
002;1234,500;2026-02-30""",
    "delimiter": ";",
    "schema": {
        "id": {
            "type": "text",
            "required": True,
            "unique": True,
        },
        "amount": {
            "type": "decimal",
            "decimal_separator": ",",
            "group_separator": ".",
            "unique": True,
        },
        "date": {
            "type": "date",
            "format": "%Y-%m-%d",
        },
    },
    "includePreview": True,
}

# Run the Actor and wait for it to finish
run = client.actor("mick_mouse/my-actor-1").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 '{
  "csv": "id;amount;date\\n001;1.234,50;2026-10-26\\n002;1234,500;2026-02-30",
  "delimiter": ";",
  "schema": {
    "id": {
      "type": "text",
      "required": true,
      "unique": true
    },
    "amount": {
      "type": "decimal",
      "decimal_separator": ",",
      "group_separator": ".",
      "unique": true
    },
    "date": {
      "type": "date",
      "format": "%Y-%m-%d"
    }
  },
  "includePreview": true
}' |
apify call mick_mouse/my-actor-1 --silent --output-dataset

```

## MCP server setup

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

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/6KYu5LCbCPAimf7qT/builds/2J4zSAtwpUDekHghL/openapi.json
