Clean a CSV
A CSV exported from one system and imported into another almost never arrives clean: stray whitespace around values, mojibake from a mismatched character encoding, blank rows left by a spreadsheet tool, and numbers stored as text all creep in. This clean CSV API fixes those issues in a single pass so downstream code can trust the data instead of defending against it.
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
Why 'just a CSV' is rarely clean
CSV looks like the simplest possible data format, and that simplicity is exactly why it accumulates mess: there is no schema to enforce a type, no standard to require a specific encoding, and every spreadsheet application has its own opinion about trailing commas, quoting, and blank rows. A file exported from an accounting tool, opened once in a spreadsheet program, and re-saved by a colleague can pick up leading and trailing spaces on every field, a byte-order mark at the top, a handful of rows that are entirely empty, and phone numbers or ZIP codes that lost their leading zeros because a cell got auto-converted to a number.
What the cleaning pass covers
You call POST /data/clean-csv with your file and get a task_id back immediately, since cleaning runs as an asynchronous job. The service trims leading and trailing whitespace from every field, detects and corrects common character-encoding mismatches so accented letters and special characters render correctly, removes rows that are entirely empty, and normalizes obvious types — turning text like ' 42 ' into a proper number and consistent boolean-looking strings into true booleans — while leaving genuinely ambiguous values untouched rather than guessing.
A brief note on why encoding breaks so often
CSV predates any universal text-encoding standard, so a file written on one system as Latin-1 and opened on another expecting UTF-8 turns accented characters into garbled symbols, a problem anyone who has exported data across regions or older systems has run into. Because the CSV format itself carries no declaration of which encoding it uses, tools have to detect it heuristically, which is exactly the kind of fiddly, error-prone step that is better handled once, automatically, than repeated by hand in every downstream script.
Where cleaning belongs in a pipeline
Place this step immediately after ingesting any CSV from an external source: a client upload, a legacy system export, a partner's data feed, or a scheduled file drop. Clean before you deduplicate, clean before you load into a database, and clean before you hand a file to any process that assumes well-formed types, since garbage-in problems compound fast once bad data reaches a downstream join or aggregation.
Delivery, pricing, and status
The cleaned CSV is delivered by a signed webhook, recommended for ingestion pipelines, or a signed link valid for 24 hours; source and output are deleted after the retention window and never used for training. Pricing is a flat $0.002 per request regardless of row count, and a failed task — such as a file that is not parseable as CSV at all — is never charged after the standard three retries. This endpoint is live now.
What you can do with it
Sanitize client-uploaded spreadsheets
Clean CSVs uploaded through a customer-facing import form before they touch your database, catching stray whitespace and encoding issues before they cause a bad record.
Fix legacy exports before migration
Run old system exports through cleaning to correct encoding mismatches and strip blank rows left by years of manual edits, ahead of a one-time data migration.
Prepare partner data feeds for automated ingestion
Clean a recurring CSV feed from a partner or vendor on a schedule, so type inconsistencies never reach the scripts that depend on clean numeric and boolean fields.
Pre-process files before deduplication
Clean whitespace and blank rows first so a subsequent dedupe pass compares genuinely equivalent values instead of missing matches because of trailing spaces.
FAQ
How do I clean a CSV file with an API?
Send the file to POST /data/clean-csv, which returns a task_id right away; the cleaned CSV arrives at your signed webhook or a signed link once processing finishes.
Is the clean CSV API free?
The tool above runs free in your browser. The API is paid — each call draws from your prepaid ForHosting KIT balance: top up from $10.00 (it never expires), pay each request's published price, and a call with no balance returns HTTP 402. No subscription, no tokens, and a failed task is never charged.
What exactly counts as 'cleaning'?
Trimming whitespace from every field, correcting common encoding mismatches, removing entirely empty rows, and normalizing obviously numeric or boolean text into proper types.
Will it change values it isn't sure about?
No. Ambiguous values are left untouched rather than guessed at, so the process fixes clear formatting problems without silently altering data whose meaning isn't certain.
Does it fix encoding issues like garbled accented characters?
Yes. Common character-encoding mismatches are detected and corrected so accented letters and special characters render properly instead of appearing as garbled symbols.
Can I clean large CSV files?
Yes, within the size limits published for the endpoint; pricing stays a flat fee per request regardless of how many rows the file contains.
Can I clean CSVs in bulk?
Yes. Each request is an independent asynchronous task, so you can submit many files in parallel and collect each cleaned result by webhook as it completes.
Does cleaning remove duplicate rows too?
No, cleaning focuses on whitespace, encoding, empty rows, and type normalization; use the separate deduplication endpoint to remove duplicate rows by chosen columns.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/data/clean-csv \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"…"}'const res = await fetch("https://api.kit.forhosting.com/data/clean-csv", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/data/clean-csv",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/data/clean-csv", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/data/clean-csv", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "data.clean_csv",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |