{
  "openapi": "3.0.1",
  "info": {
    "title": "SQL for Datasets: Join, Merge & Dedupe Files",
    "description": "Run SQL on Apify datasets and CSV, JSON or Parquet files with DuckDB. Join, merge, dedupe, filter, group and transform data in one query. Presets for dedupe, VLOOKUP join and merge. Only-new-rows mode. Save rows to a dataset or a CSV, JSON or Parquet file.",
    "version": "0.1",
    "x-build-id": "ZLnAZFhf7BJHCz7tv"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/maliksaid~sql-over-datasets/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-maliksaid-sql-over-datasets",
        "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/maliksaid~sql-over-datasets/runs": {
      "post": {
        "operationId": "runs-sync-maliksaid-sql-over-datasets",
        "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/maliksaid~sql-over-datasets/run-sync": {
      "post": {
        "operationId": "run-sync-maliksaid-sql-over-datasets",
        "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": {
          "query": {
            "title": "SQL query",
            "type": "string",
            "description": "DuckDB SQL. Each input is a table: dataset1, dataset2, file1, file2, record1 and so on, or the name you give it with 'name = ...'. You can run several statements separated by semicolons. The last one must return rows. Leave empty when you use a preset. With no inputs and no query, the Actor runs a sample on two public CSV files."
          },
          "preset": {
            "title": "Preset",
            "enum": [
              "custom",
              "merge",
              "dedupe",
              "join"
            ],
            "type": "string",
            "description": "Your SQL query runs the query above. Merge stacks all inputs and matches columns by name. Remove duplicates keeps the first row per key. Join (VLOOKUP) adds the columns of the second input to the first one by key.",
            "default": "custom"
          },
          "keyColumns": {
            "title": "Key columns",
            "type": "array",
            "description": "Column names for Remove duplicates, Join and Only new rows. Remove duplicates without keys compares whole rows. Only new rows without keys compares whole rows.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "joinType": {
            "title": "Join type",
            "enum": [
              "left",
              "inner",
              "full",
              "right",
              "anti"
            ],
            "type": "string",
            "description": "Used by the Join preset. Left keeps every row of the first input. Inner keeps rows with a match only. Full keeps every row of both inputs. Right keeps every row of the second input. Anti keeps the rows of the first input that have no match, with the first input's columns only.",
            "default": "left"
          },
          "addMatchColumn": {
            "title": "Add match column",
            "type": "boolean",
            "description": "Used by the Join preset. Adds a `_matched` column: true when the row found a match in both inputs, false when it did not.",
            "default": false
          },
          "datasetIds": {
            "title": "Apify datasets",
            "type": "array",
            "description": "Pick datasets, for example the results of other Actors. They become the tables dataset1, dataset2 and so on. The Actor only reads them."
          },
          "fileUrls": {
            "title": "File URLs",
            "type": "array",
            "description": "Links to CSV, TSV, JSON, JSON Lines or Parquet files, one per line. They become file1, file2 and so on. Write 'name = https://...' to choose the table name. The Actor reads robots.txt on each host and refuses local and private network addresses.",
            "items": {
              "type": "string"
            }
          },
          "keyValueStoreId": {
            "title": "Key-value store with files",
            "type": "string",
            "description": "Optional. Pick one of your key-value stores that holds CSV, JSON or Parquet files. The Actor only reads this store."
          },
          "keyValueStoreKeys": {
            "title": "Record keys",
            "type": "array",
            "description": "Keys of the records to read from the store above. They become record1, record2 and so on. Write 'name = key' to choose the table name.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "saveToDataset": {
            "title": "Save rows to the dataset",
            "type": "boolean",
            "description": "Save each result row as one dataset item. You can then export the dataset from Apify as JSON, CSV, Excel or XML.",
            "default": true
          },
          "fileFormat": {
            "title": "Also save a file",
            "enum": [
              "none",
              "csv",
              "json",
              "jsonl",
              "parquet"
            ],
            "type": "string",
            "description": "Save the whole result as one file in the run's key-value store, under the key result.csv, result.json, result.jsonl or result.parquet.",
            "default": "none"
          },
          "onlyNewRows": {
            "title": "Only new rows",
            "type": "boolean",
            "description": "Save only rows that earlier runs with the same monitor name did not save. Schedule the Actor with this on to get a feed of new rows. Uses Key columns when you give them.",
            "default": false
          },
          "monitorName": {
            "title": "Monitor name",
            "type": "string",
            "description": "Name of the memory that Only new rows uses. Use a different name for each separate job. Inputs that still send the old field `stateKey` keep working.",
            "default": "default"
          },
          "maxRows": {
            "title": "Maximum rows",
            "minimum": 0,
            "type": "integer",
            "description": "Save at most this many result rows. The default keeps test runs short and cheap. Set 0 to save every row.",
            "default": 100
          },
          "maxFileMegabytes": {
            "title": "Maximum input size (MB)",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "Stop when one input file or dataset is larger than this. Inputs are saved to disk, so they can be larger than the run's memory.",
            "default": 200
          },
          "queryTimeoutSecs": {
            "title": "Query time limit (seconds)",
            "minimum": 10,
            "maximum": 3600,
            "type": "integer",
            "description": "Stop the query when it runs longer than this.",
            "default": 300
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}