{
  "openapi": "3.0.1",
  "info": {
    "title": "Dataset Cleaner & Exporter",
    "description": "Returns a deduplicated, flattened and cleaned copy of any Apify dataset, file or Google Sheet by URL, or JSON array, plus CSV and Excel files, named-dataset append and webhook delivery. Inputs: source, dedup keys, flatten, cleaning options. Agent-ready: pay per event (x402, MCP), per cleaned record.",
    "version": "0.1",
    "x-build-id": "oSuJWx6OGT7QDbuA9"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nerolabs~dataset-cleaner-exporter/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nerolabs-dataset-cleaner-exporter",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/nerolabs~dataset-cleaner-exporter/runs": {
      "post": {
        "operationId": "runs-sync-nerolabs-dataset-cleaner-exporter",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/nerolabs~dataset-cleaner-exporter/run-sync": {
      "post": {
        "operationId": "run-sync-nerolabs-dataset-cleaner-exporter",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "sourceDatasetId": {
            "title": "Source dataset",
            "type": "string",
            "description": "Pick an existing Apify dataset to clean, for example the output of another Actor run. Use this OR 'File URL' OR 'Inline data' below. Declaring it this way is what lets this Actor run with limited permissions: it may read the dataset you point at, and nothing else on your account."
          },
          "fileUrl": {
            "title": "File URL (CSV, Excel, JSON or Google Sheet)",
            "type": "string",
            "description": "Instead of a dataset, download the records to clean from a public link: a CSV or TSV file, an Excel .xlsx file (first sheet, header row), a JSON array or JSON Lines file, or a Google Sheet (paste the normal sheet link, sharing set to 'Anyone with the link can view'). The format is detected automatically. Up to 100 MB per run. The download is never charged; only cleaned records written out are. Ignored when 'Source dataset' is set."
          },
          "data": {
            "title": "Inline data",
            "type": "array",
            "description": "A JSON array of records to clean, for ad-hoc or piped data instead of a dataset ID or file URL."
          },
          "fileFormat": {
            "title": "File format",
            "enum": [
              "auto",
              "csv",
              "tsv",
              "json",
              "jsonl",
              "xlsx"
            ],
            "type": "string",
            "description": "Only needed if automatic detection gets the file URL's format wrong.",
            "default": "auto"
          },
          "flatten": {
            "title": "Flatten nested fields",
            "type": "boolean",
            "description": "Turn nested objects into flat scalar columns (e.g. address.city becomes address_city) so the result is spreadsheet-ready. Arrays are kept as a single JSON-text cell unless you set 'Field to expand into rows' below.",
            "default": true
          },
          "flattenSeparator": {
            "title": "Flatten separator",
            "type": "string",
            "description": "Character(s) used to join nested key paths when flattening.",
            "default": "_"
          },
          "expandArrayField": {
            "title": "Field to expand into rows",
            "type": "string",
            "description": "Optional. Name one top-level array-of-objects field (e.g. 'offers' or 'variants') to explode into multiple output rows, one per entry, with the rest of the record repeated. Leave empty to keep arrays as a single cell."
          },
          "dedupMode": {
            "title": "Deduplication mode",
            "enum": [
              "none",
              "exact",
              "normalized",
              "fuzzy"
            ],
            "type": "string",
            "description": "How to detect duplicate records. Exact = byte-identical values. Normalized = ignores case/whitespace differences. Fuzzy = also merges near-duplicates by similarity (recommended for datasets under 5,000 records). None = skip deduplication.",
            "default": "normalized"
          },
          "dedupKeys": {
            "title": "Deduplication keys",
            "type": "array",
            "description": "Field names that identify a duplicate (e.g. email, url). Leave empty to compare the whole record.",
            "items": {
              "type": "string"
            }
          },
          "similarityThreshold": {
            "title": "Fuzzy similarity threshold",
            "minimum": 0.5,
            "maximum": 0.99,
            "type": "number",
            "description": "Fuzzy mode only. 0.5 to 0.99. Higher means stricter, fewer records get merged. 0.9 is a good starting point.",
            "default": 0.9
          },
          "keepStrategy": {
            "title": "Which duplicate to keep",
            "enum": [
              "most_complete",
              "first",
              "last"
            ],
            "type": "string",
            "description": "When duplicates are found, which record survives.",
            "default": "most_complete"
          },
          "cleanFields": {
            "title": "Smart field cleaning",
            "type": "boolean",
            "description": "Auto-detect email, phone and URL fields by name or shape, and normalize them (lowercase emails, digit-only phones, lowercase URL host).",
            "default": true
          },
          "stripHtml": {
            "title": "Strip HTML",
            "type": "boolean",
            "description": "Remove HTML tags and decode common entities from text fields.",
            "default": false
          },
          "coerceTypes": {
            "title": "Coerce types",
            "type": "boolean",
            "description": "Convert numeric-looking and true/false-looking strings into real numbers and booleans.",
            "default": false
          },
          "emptyToNull": {
            "title": "Empty strings to null",
            "type": "boolean",
            "description": "Turn empty or blank string values into null for consistency.",
            "default": true
          },
          "dropEmptyFields": {
            "title": "Drop empty fields",
            "type": "boolean",
            "description": "Remove null/empty fields from each record entirely instead of keeping them.",
            "default": false
          },
          "columnsToKeep": {
            "title": "Columns to keep",
            "type": "array",
            "description": "Only these columns will be kept in the output (takes priority over 'Columns to remove'). Leave empty to keep all.",
            "items": {
              "type": "string"
            }
          },
          "columnsToRemove": {
            "title": "Columns to remove",
            "type": "array",
            "description": "These columns will be dropped from the output. Ignored if 'Columns to keep' is set.",
            "items": {
              "type": "string"
            }
          },
          "columnRenameMap": {
            "title": "Rename columns",
            "type": "array",
            "description": "Rename columns, one per line, in 'oldName:newName' format (e.g. 'address_city:city').",
            "items": {
              "type": "string"
            }
          },
          "maxItems": {
            "title": "Max output records",
            "minimum": 0,
            "type": "integer",
            "description": "Cap on output records (0 = no cap, up to the safety limit of 100,000). You are billed per output record and per exported file, so capping this caps your cost.",
            "default": 0
          },
          "outputDatasetName": {
            "title": "Also append to a named dataset",
            "type": "string",
            "description": "Optional. A name (3 to 63 letters, digits or hyphens, e.g. 'clean-leads'). The cleaned records are appended to a dataset with this name in your account, created on the first run, so a scheduled pipeline accumulates into one place instead of one dataset per run. Not charged again."
          },
          "exportFormats": {
            "title": "Export file formats",
            "type": "array",
            "description": "Which downloadable file(s) to generate alongside the cleaned dataset.",
            "items": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx"
              ]
            },
            "default": [
              "csv",
              "xlsx"
            ]
          },
          "webhookUrl": {
            "title": "Webhook URL (optional)",
            "type": "string",
            "description": "Optional. If set, the cleaned result (items, download links, and a summary) is POSTed here as JSON the moment this run finishes, so you don't have to come back and check the dataset yourself. Works with a Zapier/Make/n8n catch-hook, your own API endpoint, or a Slack incoming webhook. Only charged when the endpoint actually confirms receipt (HTTP 2xx); a failed delivery is reported as a warning in the run's output and costs nothing."
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}