# CSV Profiler - Instant Data Quality Report for Any CSV (`eliai/csv-profiler`) Actor

Profile any CSV by URL or paste: per-column types, null rates, unique counts, min/max/mean/median/stddev, top values, quality warnings (mostly-null, mixed-type, constants, identifiers). Up to 200k rows. $0.003 per file whatever its size, no start fee — vs $0.015+ measured incumbents.

- **URL**: https://apify.com/eliai/csv-profiler.md
- **Developed by:** [Broke to Built](https://apify.com/eliai) (community)
- **Categories:** Developer tools, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 profiled csv files

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## CSV Profiler — Instant Data Quality Report for Any CSV

Point it at a CSV URL or paste raw CSV — get a full data profile back in seconds: per-column types, null rates, unique counts, min/max/mean/median/stddev, top values, and plain-English quality warnings. Up to 200,000 rows per file, online, by API, or as an agent tool via Apify MCP.

Before you import, join, train on, or bill against a dataset, you want to know: which columns are secretly half-empty, which "numeric" column has strings in it, which field is a constant, which is really an ID. That is exactly what this profile answers — the first 10 minutes of every data-cleaning session, automated.

### What you get

- **rowCount / columnCount**
- **columns** — for each column: inferred `type` (integer/float/string/date/boolean), `nullPct`, `unique`, numeric stats (min/max/mean/median/stddev) or string length range, and the top 5 values with counts
- **warnings** — mostly-null columns, mixed-type columns, constants, possible identifiers, parse errors
- **Fail-soft**: an unfetchable or empty file never fails the run — it returns `{ok: false, error}` and is **never charged**.

### Input

```json
{ "url": "https://example.com/data.csv", "maxRows": 5000 }
```

Also: `urls` (bulk array, one profile each) and `csv` (paste raw text). Headerless files get `col_1, col_2, …` automatically.

### Output (real run — the classic Titanic dataset)

```json
{
  "ok": true,
  "rowCount": 891,
  "columnCount": 12,
  "columns": [
    {
      "name": "Age",
      "type": "float",
      "nullPct": 19.87,
      "unique": 88,
      "stats": { "min": 0.42, "max": 80, "mean": 29.7, "median": 28, "stddev": 14.52 },
      "topValues": [{ "value": "24", "count": 30 }]
    }
  ],
  "warnings": ["Column \"Cabin\" is 77.1% null.", "Column \"PassengerId\" has all-unique values (possible identifier)."]
}
```

### Pricing

**$0.003 per file profiled** — however many rows and columns it has (up to the 200k-row cap). No start fee. Unfetchable and empty files are never charged.

Measured against store incumbents (2026-08-07): q\_services/csv-json-data-quality-profiler charges $0.01 start + $0.005 per item, perryay/data-validator-profiler $0.02 start + $0.01 per batch-profile. One file here costs $0.003 vs $0.015–$0.03 there.

### Honest limits

- Types are inferred from values, majority-rules per column; a column of ZIP codes reads as `integer` (leading zeros stripped by whatever wrote the CSV, not by us — we treat values as text until classified).
- `maxRows` (default 5,000, max 200,000) caps profiling depth; rows beyond it are not read. Stats describe the profiled slice.
- Delimiter/quoting handled by Papa Parse 5.5 (pinned); exotic fixed-width or multi-table sheets are out of scope.
- Dates are detected for ISO-like formats (`2024-01-15`, with optional time); `01/15/2024` classifies as string — deliberate, since its meaning is locale-ambiguous.

### FAQ

**How do I use this for data validation in a pipeline?**
Profile the incoming file, then assert on the record: reject when `warnings` is non-empty, when a required column's `nullPct` exceeds your threshold, or when a column's `type` changed since the last delivery.

**What does "possible identifier" mean?**
Every non-null value in the column is unique — a strong signal it is a key, not a feature. Useful for spotting columns to exclude from ML training.

**Can it handle files without headers?**
Yes — when no header row is detected, columns become `col_1, col_2, …` and everything else works the same.

**How are booleans detected?**
true/false, yes/no, y/n, t/f, 1/0 (case-insensitive) — majority-rules with the other candidates per column.

**Why did some rows come back `ok: false`?**
The URL 404'd, timed out, or returned empty content. Recorded with the exact error, never charged.

### Use from code or AI agents

```bash
curl -s "https://api.apify.com/v2/acts/EliAI~csv-profiler/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -X POST -H 'Content-Type: application/json' \
  -d '{"url": "https://example.com/export.csv"}'
```

Agents: connect [Apify MCP](https://mcp.apify.com) and call the `EliAI/csv-profiler` tool.

- **Capability:** profile one or many CSV files — column types, null rates, stats, top values, quality warnings
- **Required input:** `url`/`urls` or `csv`
- **Returns:** one profile record per file; `columns` + `warnings` summarize data quality
- **Bounded:** `maxRows` caps rows read; failures isolate per file
- **Side effects:** none

# Actor input Schema

## `url` (type: `string`):

Public URL of a CSV file to profile.

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

Paste raw CSV content here instead of a URL. If both are provided, both are profiled.

## `maxRows` (type: `integer`):

Cap the number of data rows analyzed (1 - 200000).

## `urls` (type: `array`):

Multiple CSV file URLs to profile in one run — one profile record each.

## Actor input object example

```json
{
  "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
  "csv": "name,age,city\nAda,36,London\nAlan,41,Wilmslow\nGrace,85,Arlington",
  "maxRows": 5000,
  "urls": [
    "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
  ]
}
```

# Actor output Schema

## `results` (type: `string`):

Every item this run produced, as JSON.

## `resultsCsv` (type: `string`):

The same items as a spreadsheet-ready CSV.

# 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 = {
    "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
    "csv": `name,age,city
Ada,36,London
Alan,41,Wilmslow
Grace,85,Arlington`,
    "urls": [
        "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("eliai/csv-profiler").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 = {
    "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
    "csv": """name,age,city
Ada,36,London
Alan,41,Wilmslow
Grace,85,Arlington""",
    "urls": ["https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"],
}

# Run the Actor and wait for it to finish
run = client.actor("eliai/csv-profiler").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 '{
  "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
  "csv": "name,age,city\\nAda,36,London\\nAlan,41,Wilmslow\\nGrace,85,Arlington",
  "urls": [
    "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
  ]
}' |
apify call eliai/csv-profiler --silent --output-dataset

```

## MCP server setup

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

```

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/gcKVmPdB5gL04TeWv/builds/Q5H3Z5uDunumPBJof/openapi.json
