Cleans up to 150 messy JSON rows
Cleans up to 150 messy JSON rows: removes duplicates (exact, normalized or fuzzy), flattens nested JSON, trims and fixes emails, phone numbers and URLs, strips HTML, turns number and true/false text into real types, drops empty fields, keeps, removes or renames columns. Returns clean rows plus a report of what changed. $0.002 per row sent, $0.002 minimum. Same engine as nerolabs/dataset-cleaner-exporter.
Answeringour last check, 2026-10-21
1 of 1checks answered this week
56 msmedian answer time
$0.004listed price per call
$0.004price it asked us
Paid test badge: not yet. The checks above are free: we call the tool without paying and read the payment request it sends back. The Verified badge needs paid calls whose answers match the promised output, and nobody can buy a badge.
Endpoint
POST https://x402-agent-tools.nerolabs.workers.dev/data/clean
| Category | Everything else |
|---|---|
| Provider host | x402-agent-tools.nerolabs.workers.dev |
| Networks | eip155:8453 |
| Payment schemes | exact |
| Self-reported calls, 30 days | 0 from 0 payers (the provider's figure, not ours) |
Our checks, last 30 days
| Day | Result | HTTP | Asked | Time |
|---|---|---|---|---|
| 2026-10-21 | valid payment request | 402 | $0.004 | 56 ms |
Example input (from the provider)
{
"body": {
"dedupKeys": [
"email"
],
"dedupMode": "normalized",
"rows": [
{
"email": "ANA@SILVA.CO.UK ",
"name": " Ana Silva ",
"phone": "0117 496 0012"
},
{
"email": "ana@silva.co.uk",
"name": "Ana Silva",
"phone": "01174960012"
}
]
},
"bodyType": "json",
"method": "POST",
"type": "http"
}
Promised output schema (from the provider)
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"input": {
"additionalProperties": false,
"properties": {
"body": {
"additionalProperties": false,
"properties": {
"cleanFields": {
"description": "Default true. Normalize emails, phone numbers and URLs, detected by field name or value shape.",
"type": "boolean"
},
"coerceTypes": {
"description": "Default false. Turn \"42\" into 42 and \"true\" into true. Leading-zero values like \"007\" stay text.",
"type": "boolean"
},
"columnRenameMap": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"additionalProperties": {
"type": "string"
},
"type": "object"
}
],
"description": "Rename columns after keep/remove, as [\"oldName:newName\"] or {\"oldName\":\"newName\"}, for example {\"Details_founded\":\"founded\"}."
},
"columnsToKeep": {
"description": "Keep only these columns (flattened names). Takes priority over columnsToRemove.",
"items": {
"type": "string"
},
"type": "array"
},
"columnsToRemove": {
"description": "Drop these columns (flattened names). Ignored if columnsToKeep is set.",
"items": {
"type": "string"
},
"type": "array"
},
"dedupKeys": {
"description": "Fields that identify a duplicate, for example [\"Email\"]. Empty compares the whole row. Use the final column names: flattened (Details_founded) and renamed. Exact and case-sensitive. Rows where every key is empty count as duplicates of each other.",
"items": {
"type": "string"
},
"type": "array"
},
"dedupMode": {
"description": "How duplicates are found. normalized (default) ignores case and whitespace; exact needs identical values; fuzzy also merges near-duplicates (up to 100 rows and 1000 characters of key text, so name a short field in dedupKeys); none keeps every row.",
"enum": [
"none",
"exact",
"normalized",
"fuzzy"
],
"type": "string"
},
"dropEmptyFields": {
"description": "Default false. Remove null and empty fields from each row.",
"type": "boolean"
},
"emptyToNull": {
"description": "Default true. Blank text becomes null.",
"type": "boolean"
},
"expandArrayField": {
"description": "Optional. One top-level array field (for example \"offers\") to explode into one row per entry, repeating the other fields. Object entries become columns. The expanded total must stay within the row limit.",
"type": "string"
},
"flatten": {
"description": "Default true. Turn nested objects into flat columns. Arrays become one JSON-text cell.",
"type": "boolean"
},
"flattenSeparator": {
"description": "Joins nested key paths when flattening. Default \"_\".",
"type": "string"
},
"keepStrategy": {
"description": "Which duplicate survives: most_complete (default, fewest empty fields), first or last.",
"enum": [
"most_complete",
"first",
"last"
],
"type": "string"
},
"maxItems": {
"description": "Optional cap: read at most this many rows and return at most this many. 0 (default) means no cap.",
"minimum": 0,
"type": "integer"
},
"outputFormat": {
"description": "json (default) returns rows; csv returns the same result as CSV text in \"csv\" instead.",
"enum": [
"json",
"csv"
],
"type": "string"
},
"rows": {
"description": "The rows to clean. Each row is a JSON object; keys may differ between rows and values may be nested.",
"items": {
"type": "object"
},
"type": "array"
},
"similarityThreshold": {
"description": "Fuzzy mode only. 0.5 to 0.99, default 0.9. Higher is stricter.",
"maximum": 0.99,
"minimum": 0.5,
"type": "number"
},
"stripHtml": {
"description": "Default false. Remove HTML tags and decode common entities in text.",
"type": "boolean"
}
},
"required": [
"rows"
],
"type": "object"
},
"bodyType": {
"enum": [
"json",
"form-data",
"text"
],
"type": "string"
},
"method": {
"enum": [
"POST"
],
"type": "string"
},
"type": {
"const": "http",
"type": "string"
}
},
"required": [
"type",
"method",
"bodyType",
"body"
],
"type": "object"
},
"output": {
"properties": {
"example": {
"type": "object"
},
"type": {
"type": "string"
}
},
"required": [
"type"
],