{
  "openapi": "3.0.1",
  "info": {
    "title": "CRM Contact Cleanup & Duplicate Review",
    "description": "Review your CRM export before importing. Compare website, email and address formatting suggestions, spot possible duplicates, and retain original information. No contact verification or automatic merging. Base price: $0.10 per 1,000 accepted review rows.",
    "version": "4.1",
    "x-build-id": "W5w48aw89TpmKXwXU"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/critd~contact-cleanup/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-critd-contact-cleanup",
        "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/critd~contact-cleanup/runs": {
      "post": {
        "operationId": "runs-sync-critd-contact-cleanup",
        "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/critd~contact-cleanup/run-sync": {
      "post": {
        "operationId": "run-sync-critd-contact-cleanup",
        "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": {
          "inputSource": {
            "title": "Input source",
            "enum": [
              "example",
              "confidentialRecords",
              "source",
              "records"
            ],
            "type": "string",
            "description": "Choose one input route and fill only its data field. Clear previously entered data when switching. Both inline arrays are encrypted in stored run input; uploaded files and results are not encrypted by this setting. The 12-row fictional example uses the normal priced workflow ($0.0012 at base price)."
          },
          "confidentialRecords": {
            "title": "Confidential Records",
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "description": "Paste a whole-row JSON array using recordId, url, email and address for supported fields. Both this field and Records receive Apify secret protection in stored run input. Use exactly one inline field or Source. This setting does not extend to uploaded files, source storage, result files or historical plaintext inputs; manage their access and retention separately.",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "recordId": {
                  "title": "Record ID",
                  "type": "string",
                  "description": "Optional source identifier to map output rows back to your system. It is not required to be unique and does not authorize automatic dedupe or merge.",
                  "editor": "textfield",
                  "nullable": true,
                  "maxLength": 256
                },
                "url": {
                  "title": "URL",
                  "type": "string",
                  "description": "Optional supplied website URL or bare domain to normalize. Malformed values remain row diagnostics; this Actor does not crawl the site or prove reachability.",
                  "editor": "textfield",
                  "nullable": true,
                  "maxLength": 4096
                },
                "email": {
                  "title": "Email",
                  "type": "string",
                  "description": "Optional supplied email address to normalize for cleanup and matching signals. This Actor does not verify deliverability, inbox existence, or inbox ownership.",
                  "editor": "textfield",
                  "nullable": true,
                  "maxLength": 320
                },
                "address": {
                  "title": "Address",
                  "type": "string",
                  "description": "Optional supplied U.S.-leaning address text to normalize for cleanup and comparison-key signals. This Actor does not certify postal deliverability or geocode addresses.",
                  "editor": "textarea",
                  "nullable": true,
                  "maxLength": 1024
                }
              }
            }
          },
          "source": {
            "title": "Source",
            "required": [
              "type"
            ],
            "type": "object",
            "description": "Use an existing CSV, JSON Lines or JSON array file, or an Apify Dataset. Map your columns and run Preview Only first. Tested profiles: 1,000 accepted rows with 6 source fields; separately, 12 rows with 261 fields. Other size/width combinations are not established by those tests.",
            "properties": {
              "type": {
                "title": "Source Route",
                "type": "string",
                "description": "Choose where your rows are stored, then fill only the fields for that source.",
                "editor": "select",
                "enum": [
                  "file",
                  "dataset",
                  "keyValueStore"
                ],
                "enumTitles": [
                  "File upload",
                  "Dataset",
                  "Key-value store record"
                ]
              },
              "file": {
                "title": "File",
                "type": "string",
                "description": "Upload your CSV, JSON Lines or JSON array. This selects an Apify Key-Value Store file; arbitrary web URLs are not supported. Uploaded file contents are not encrypted by the inline secret setting.",
                "editor": "fileupload",
                "nullable": true,
                "maxLength": 4096,
                "example": "apify://key-value-stores/synthetic-source/records/contacts.csv"
              },
              "datasetId": {
                "title": "Source Dataset",
                "type": "string",
                "description": "Select the Dataset containing your contact rows. Only READ access is requested. Leave file and Key-Value Store fields empty.",
                "editor": "resourcePicker",
                "resourceType": "dataset",
                "resourcePermissions": [
                  "READ"
                ],
                "nullable": true,
                "maxLength": 256,
                "example": "synthetic-dataset-name"
              },
              "storeId": {
                "title": "Source Key-Value Store",
                "type": "string",
                "description": "Select the Key-Value Store containing your file. Only READ access is requested; enter its record key below.",
                "editor": "resourcePicker",
                "resourceType": "keyValueStore",
                "resourcePermissions": [
                  "READ"
                ],
                "nullable": true,
                "maxLength": 256,
                "example": "synthetic-source-store"
              },
              "recordKey": {
                "title": "KVS Record Key",
                "type": "string",
                "description": "The selected file key, for example contacts.csv or contacts.jsonl.",
                "editor": "textfield",
                "nullable": true,
                "maxLength": 512,
                "example": "contacts.jsonl"
              },
              "format": {
                "title": "Source Format",
                "type": "string",
                "description": "Choose the uploaded file format, or Auto-detect. Leave empty for Dataset sources.",
                "editor": "select",
                "nullable": true,
                "enum": [
                  "auto",
                  "csv",
                  "jsonl",
                  "json_array"
                ],
                "enumTitles": [
                  "Auto-detect",
                  "CSV with header",
                  "JSON Lines",
                  "JSON array"
                ],
                "example": "csv"
              },
              "fieldMap": {
                "title": "Match your columns",
                "type": "object",
                "description": "Enter source column names only when different from recordId, url, email or address. Leave unused controls unset. All other original columns are preserved.",
                "editor": "hidden",
                "additionalProperties": false,
                "example": {
                  "recordId": "crm_id",
                  "url": "website",
                  "email": "email_address",
                  "address": "mailing_address"
                },
                "properties": {
                  "recordId": {
                    "title": "Record ID Field",
                    "type": "string",
                    "description": "Column containing recordId. Leave unset to use recordId; do not enter a blank name.",
                    "nullable": true,
                    "maxLength": 256,
                    "editor": "textfield"
                  },
                  "url": {
                    "title": "URL Field",
                    "type": "string",
                    "description": "Column containing url. Leave unset to use url; do not enter a blank name.",
                    "nullable": true,
                    "maxLength": 256,
                    "editor": "textfield"
                  },
                  "email": {
                    "title": "Email Field",
                    "type": "string",
                    "description": "Column containing email. Leave unset to use email; do not enter a blank name.",
                    "nullable": true,
                    "maxLength": 256,
                    "editor": "textfield"
                  },
                  "address": {
                    "title": "Address Field",
                    "type": "string",
                    "description": "Column containing address. Leave unset to use address; do not enter a blank name.",
                    "nullable": true,
                    "maxLength": 256,
                    "editor": "textfield"
                  }
                }
              },
              "offset": {
                "title": "Dataset Offset",
                "type": "integer",
                "description": "Optional starting offset for type=dataset. It is ignored by other routes and rejected by Rust validation if mixed with them.",
                "editor": "number",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "columnMapping": {
            "title": "Match your columns",
            "type": "object",
            "description": "Enter source column names only when different from recordId, url, email or address. Leave unused controls unset. All other original columns are preserved.",
            "properties": {
              "recordId": {
                "title": "Record ID Field",
                "type": "string",
                "description": "Column containing recordId. Leave unset to use recordId; do not enter a blank name.",
                "nullable": true,
                "maxLength": 256,
                "editor": "textfield"
              },
              "url": {
                "title": "URL Field",
                "type": "string",
                "description": "Column containing url. Leave unset to use url; do not enter a blank name.",
                "nullable": true,
                "maxLength": 256,
                "editor": "textfield"
              },
              "email": {
                "title": "Email Field",
                "type": "string",
                "description": "Column containing email. Leave unset to use email; do not enter a blank name.",
                "nullable": true,
                "maxLength": 256,
                "editor": "textfield"
              },
              "address": {
                "title": "Address Field",
                "type": "string",
                "description": "Column containing address. Leave unset to use address; do not enter a blank name.",
                "nullable": true,
                "maxLength": 256,
                "editor": "textfield"
              }
            },
            "additionalProperties": false
          },
          "records": {
            "title": "Records (existing API field, encrypted)",
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "description": "Existing records API field: submit the same 1–1,000 whole-row JSON array. Apify now encrypts it in stored INPUT, just like Confidential Records. Use one inline field or Source, never both. This does not encrypt result files. Existing plaintext submissions remain valid; stored ciphertext is not a portable retry payload.",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "recordId": {
                  "title": "Record ID",
                  "type": "string",
                  "description": "Optional source identifier to map output rows back to your system. It is not required to be unique and does not authorize automatic dedupe or merge.",
                  "editor": "textfield",
                  "nullable": true,
                  "maxLength": 256
                },
                "url": {
                  "title": "URL",
                  "type": "string",
                  "description": "Optional supplied website URL or bare domain to normalize. Malformed values remain row diagnostics; this Actor does not crawl the site or prove reachability.",
                  "editor": "textfield",
                  "nullable": true,
                  "maxLength": 4096
                },
                "email": {
                  "title": "Email",
                  "type": "string",
                  "description": "Optional supplied email address to normalize for cleanup and matching signals. This Actor does not verify deliverability, inbox existence, or inbox ownership.",
                  "editor": "textfield",
                  "nullable": true,
                  "maxLength": 320
                },
                "address": {
                  "title": "Address",
                  "type": "string",
                  "description": "Optional supplied U.S.-leaning address text to normalize for cleanup and comparison-key signals. This Actor does not certify postal deliverability or geocode addresses.",
                  "editor": "textarea",
                  "nullable": true,
                  "maxLength": 1024
                }
              }
            }
          },
          "previewOnly": {
            "title": "Preview Only (check source, no files)",
            "type": "boolean",
            "description": "For stored data / file routes only. Check the source and prepare the workflow locally without publishing result files or billable Dataset rows. Success appears in the run status message, not in Output downloads. After checking the accepted count and stated capacity, turn this off and run cleanup. A preview does not prove import readiness or later storage/billing success."
          },
          "sourceMaxRows": {
            "title": "Source Row Cap",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Set an explicit cap for your source. Tested profiles: 1,000 accepted rows with 6 source fields; separately, 12 rows with 261 fields. Other combinations are not established by those tests. The 10,000 schema maximum and omitted-field fallback remain for compatibility, not as supported capacity. There is no default here because this control is source-only. Physical blank CSV/JSONL lines do not count; accepted rows without a usable mapped value do. Exceeding the cap fails rather than silently truncating."
          },
          "rowLimitBehavior": {
            "title": "If the source exceeds the row cap",
            "enum": [
              "fail_over_limit"
            ],
            "type": "string",
            "description": "The first accepted record beyond Source Row Cap stops the run before publishing results. Rows are never silently cut off."
          },
          "workflow": {
            "title": "Complete review file",
            "required": [],
            "type": "object",
            "description": "Choose how to compare the original rows with formatting suggestions before preparing your own approved import copy. Side by side (default) keeps original cells and appends suggestions. Replacement mode changes eligible URL, email and address cells and retains their displaced originals in generated fields. Neither mode verifies contacts or approves an import.",
            "properties": {
              "exportMode": {
                "title": "Export Mode",
                "type": "string",
                "description": "side_by_side preserves every original field first and appends generated workflow fields. replace_supported_fields changes only mapped URL, email, or address values that have an exact no-review safe replacement and retains displaced originals in generated fields.",
                "editor": "select",
                "default": "side_by_side",
                "prefill": "side_by_side",
                "enum": [
                  "side_by_side",
                  "replace_supported_fields"
                ],
                "enumTitles": [
                  "Side by side: originals plus suggestions",
                  "Replace eligible cells; retain originals separately"
                ],
                "example": "side_by_side"
              },
              "exportFormat": {
                "title": "Export Format",
                "type": "string",
                "description": "CSV: a UTF-8 table with original and review columns. JSON: a structured array retaining native JSON value types. These are complete review files; prepare and test a separate approved import copy.",
                "editor": "select",
                "default": "csv",
                "prefill": "csv",
                "enum": [
                  "csv",
                  "json"
                ],
                "enumTitles": [
                  "CSV",
                  "JSON"
                ],
                "example": "csv"
              },
              "generatedFieldNamespace": {
                "title": "Generated Field Namespace",
                "type": "string",
                "description": "Base prefix for generated workflow fields. Use 1-64 ASCII alphanumeric characters beginning with a lowercase letter. Rust deterministically selects a numbered collision-free derivative when an original field already uses this prefix.",
                "editor": "textfield",
                "default": "contactCleanup",
                "prefill": "contactCleanup",
                "example": "contactCleanup",
                "minLength": 1,
                "maxLength": 64,
                "pattern": "^[a-z][A-Za-z0-9]{0,63}$"
              }
            },
            "default": {
              "exportMode": "side_by_side",
              "exportFormat": "csv",
              "generatedFieldNamespace": "contactCleanup"
            },
            "additionalProperties": false
          },
          "fieldGroups": {
            "title": "Legacy field selection (inactive)",
            "minItems": 1,
            "uniqueItems": true,
            "type": "array",
            "description": "Accepted compatibility control retained for saved inputs and API callers. Contact cleanup does not use it to change current workflow behavior or as a runtime-version selector. All three supported fields are evaluated regardless of this value.",
            "items": {
              "type": "string",
              "enum": [
                "url",
                "email",
                "address"
              ],
              "enumTitles": [
                "URL",
                "Email",
                "Address"
              ]
            },
            "default": [
              "url",
              "email",
              "address"
            ]
          },
          "reviewStrictness": {
            "title": "Legacy strictness (inactive)",
            "enum": [
              "minimal",
              "standard",
              "strict"
            ],
            "type": "string",
            "description": "Accepted compatibility control retained for saved inputs and API callers. Contact cleanup does not use it to change current workflow behavior or as a runtime-version selector. Review decisions use fixed rules; Minimal and Strict do not change this workflow.",
            "default": "standard"
          },
          "legacyMatchMode": {
            "title": "Legacy match setting (inactive)",
            "enum": [
              "off",
              "keys_only",
              "keys_and_candidates"
            ],
            "type": "string",
            "description": "Accepted compatibility control retained for saved inputs and API callers. Contact cleanup does not use it to change current workflow behavior or as a runtime-version selector. Possible-match files are always produced; Off does not disable matching. The omitted-input default remains keys_only and the Console prefill remains keys_and_candidates.",
            "default": "keys_only"
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}