{
  "openapi": "3.0.1",
  "info": {
    "title": "Airtable Data Quality Scan - Find Duplicates",
    "description": "Scan any Airtable base for the problems inside the cells: duplicate records, blank primary values, email and URL fields holding neither, child records with no parent, and formulas erroring on specific rows. Every finding carries the record ID and a direct link to the row.",
    "version": "1.0",
    "x-build-id": "SKIuGjjMpd6X4WOch"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/mediocre_interest~airtable-data-quality-scan/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-mediocre_interest-airtable-data-quality-scan",
        "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/mediocre_interest~airtable-data-quality-scan/runs": {
      "post": {
        "operationId": "runs-sync-mediocre_interest-airtable-data-quality-scan",
        "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/mediocre_interest~airtable-data-quality-scan/run-sync": {
      "post": {
        "operationId": "run-sync-mediocre_interest-airtable-data-quality-scan",
        "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": {
          "airtableToken": {
            "title": "Airtable personal access token",
            "type": "string",
            "description": "Your Airtable personal access token, carrying the \"data.records:read\" and \"schema.bases:read\" scopes and access to the base you want to scan. Create one at https://airtable.com/create/tokens. Leave it empty to scan a bundled sample base instead: that path runs offline, reads nothing of yours, and costs nothing."
          },
          "baseId": {
            "title": "Base ID",
            "type": "string",
            "description": "The base to scan, one per run. It starts with \"app\" and is the first path segment of the base URL. Used only when a token is set; with the token empty the bundled sample base is scanned instead."
          },
          "tableIds": {
            "title": "Tables",
            "type": "array",
            "description": "Scan only these tables, named by table ID (they start with \"tbl\"). Leave empty to scan every table in the base.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "issueTypes": {
            "title": "Problems to look for",
            "type": "array",
            "description": "Which problems to report. Leave all six selected to scan for everything.",
            "items": {
              "type": "string",
              "enum": [
                "duplicate",
                "emptyKeyField",
                "typeViolation",
                "unlinkedRecord",
                "formulaError",
                "staleRecord"
              ],
              "enumTitles": [
                "Duplicate records",
                "Blank primary field",
                "Invalid email or URL value",
                "Child record with no parent",
                "Formula erroring on some records",
                "Record not modified recently"
              ]
            },
            "default": [
              "duplicate",
              "emptyKeyField",
              "typeViolation",
              "unlinkedRecord",
              "formulaError",
              "staleRecord"
            ]
          },
          "incrementalSince": {
            "title": "Only records modified since",
            "type": "string",
            "description": "Scan only records modified on or after this moment, which Airtable filters before sending them. Leave empty to scan every record."
          },
          "duplicateFields": {
            "title": "Match duplicates on these fields",
            "type": "array",
            "description": "Match duplicates on these fields, named exactly as they appear in Airtable. All of them must agree. Leave empty to match on each table's primary field, corroborated by its email, URL and phone fields. Naming fields that exclude the primary field finds more, and reports it at lower confidence.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "duplicateMatching": {
            "title": "How closely values must agree",
            "enum": [
              "normalised",
              "normalisedStripPunctuation",
              "fuzzy"
            ],
            "type": "string",
            "description": "How closely two values must agree to count as the same record.",
            "default": "normalised"
          },
          "staleAfterDays": {
            "title": "Stale after (days)",
            "minimum": 0,
            "type": "integer",
            "description": "Report a record as stale when it has not been modified for this many days. The table needs a \"Last modified time\" field for this; without one, staleness is reported as unknown rather than as clean.",
            "default": 365
          },
          "maxRecordsPerRun": {
            "title": "Maximum records per run",
            "minimum": 1,
            "type": "integer",
            "description": "Stop after reading this many records across the whole base. 50,000 is Airtable's own per-base record limit on the Team plan. A table the cap stops partway through keeps the duplicates it found and is marked as truncated.",
            "default": 50000
          },
          "includeHtmlReport": {
            "title": "Save an HTML report",
            "type": "boolean",
            "description": "Also save a shareable HTML report of the findings to the key-value store.",
            "default": true
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}