{
  "openapi": "3.0.1",
  "info": {
    "title": "Dataset to Postgres, Supabase & MySQL (Database Push)",
    "description": "Pushes any Apify dataset, file or Google Sheet by URL, or JSON array into a Postgres, Supabase, Neon or MySQL table: creates the table with typed columns, adds missing ones, inserts, upserts by key or replaces; dry run previews the SQL. Agent-ready: pay per event (x402, MCP), per row.",
    "version": "0.1",
    "x-build-id": "xLzjJ3Gs2v8PxWdS1"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nerolabs~dataset-to-database/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nerolabs-dataset-to-database",
        "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-to-database/runs": {
      "post": {
        "operationId": "runs-sync-nerolabs-dataset-to-database",
        "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-to-database/run-sync": {
      "post": {
        "operationId": "run-sync-nerolabs-dataset-to-database",
        "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": {
          "datasetId": {
            "title": "Dataset to push",
            "type": "string",
            "description": "Pick an existing Apify dataset (for example the output of any scraper run). Use this OR 'File URL' OR 'Data (inline)' 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 rows 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 rows written are."
          },
          "data": {
            "title": "Data (inline)",
            "type": "array",
            "description": "A JSON array of records to push, for ad-hoc 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"
          },
          "databaseType": {
            "title": "Database type",
            "enum": [
              "postgres",
              "mysql"
            ],
            "type": "string",
            "description": "Postgres covers Supabase, Neon, Amazon RDS for Postgres, Railway, Render and any self-hosted Postgres 12 or newer. MySQL covers MySQL 8, MariaDB 10.5 or newer, PlanetScale and Amazon RDS for MySQL.",
            "default": "postgres"
          },
          "connectionString": {
            "title": "Connection string (kept secret)",
            "type": "string",
            "description": "postgres://user:password@host:5432/database or mysql://user:password@host:3306/database. Supabase: Project Settings > Database > Connection string (the session or transaction pooler both work). Neon: the pooled connection string. Stored encrypted by Apify and never written to the log or the output. If the password contains special characters, percent-encode them (an @ becomes %40). Leave empty together with 'Dry run' to preview the table plan without connecting."
          },
          "sslMode": {
            "title": "SSL",
            "enum": [
              "auto",
              "require",
              "verify-full",
              "disable"
            ],
            "type": "string",
            "description": "'Auto' encrypts the connection to any host that is not localhost and accepts the provider's certificate chain, which is what Supabase, Neon, RDS and PlanetScale need. 'Verify full' also checks the certificate against public roots. 'Disable' sends plain TCP (local or private networks only).",
            "default": "auto"
          },
          "tableName": {
            "title": "Table name",
            "type": "string",
            "description": "The table to write to, for example 'leads' or 'public.leads' (schema.table). Created on the first run when 'Create table if missing' is on, with column types inferred from the data."
          },
          "writeMode": {
            "title": "Write mode",
            "enum": [
              "append",
              "upsert",
              "replace"
            ],
            "type": "string",
            "description": "'Append' inserts every row. 'Upsert' inserts new rows and updates existing ones matched on the key field(s), so a scheduled scraper keeps one row per key (a unique index on the key columns is created if the table has none). 'Replace' deletes every existing row and then inserts, except when the input has 0 rows, so an empty scrape can never wipe your table.",
            "default": "append"
          },
          "keyFields": {
            "title": "Key field(s) for upsert",
            "type": "array",
            "description": "Required for upsert: the field name(s) that identify a row across runs, for example 'email', 'sku', 'url', or several together. Rows with an empty key are skipped and reported. Nested fields are written with '_' (address.city becomes address_city).",
            "items": {
              "type": "string"
            }
          },
          "createTableIfMissing": {
            "title": "Create table if missing",
            "type": "boolean",
            "description": "Create the table on the first run, with one column per field and a type inferred from the data: BIGINT for whole numbers, DOUBLE PRECISION for decimals, BOOLEAN, TIMESTAMPTZ for ISO date-times, DATE, JSONB for objects and arrays, TEXT for everything else (MySQL: BIGINT, DOUBLE, TINYINT(1), DATETIME, DATE, JSON, TEXT). Mixed values fall back to TEXT, never a guess.",
            "default": true
          },
          "addMissingColumns": {
            "title": "Add missing columns to an existing table",
            "type": "boolean",
            "description": "When the table already exists, add a column for any field it does not have yet (ALTER TABLE ADD COLUMN). Turn off to write only the columns the table already has; extra fields are then dropped and listed in the run's warnings.",
            "default": true
          },
          "columnNaming": {
            "title": "Column naming",
            "enum": [
              "snake_case",
              "original"
            ],
            "type": "string",
            "description": "'snake_case' turns 'Company Name' into company_name and 'firstName' into first_name, which is what SQL users expect. 'Original' keeps the field names as they are, quoted.",
            "default": "snake_case"
          },
          "flattenNested": {
            "title": "Flatten nested objects into columns",
            "type": "boolean",
            "description": "address: {city: 'Lisbon'} becomes a column address_city. Arrays and objects that are not flattened are stored as JSON. Turn off to store every nested object as one JSON column.",
            "default": true
          },
          "addSyncColumns": {
            "title": "Add _synced_at and _apify_run_id columns",
            "type": "boolean",
            "description": "Stamp every written row with the run's UTC time and the Apify run ID, handy for 'what did the last sync touch' queries.",
            "default": false
          },
          "batchSize": {
            "title": "Rows per batch",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Rows per INSERT statement and per transaction. Each batch is written, charged and committed together, so a batch the budget cannot cover is rolled back. Reduced automatically when a table has many columns.",
            "default": 500
          },
          "dryRun": {
            "title": "Dry run (plan only, write nothing)",
            "type": "boolean",
            "description": "On: nothing is written and no row is charged; the output holds the inferred column types and the SQL that a real run would execute. Works without a connection string too (the table is then assumed to be missing). Turn off to write.",
            "default": false
          },
          "maxItems": {
            "title": "Maximum input rows",
            "minimum": 1,
            "type": "integer",
            "description": "Stop loading after this many rows (a cost guard for large inputs). There is a hard safety ceiling of 200,000 rows per run regardless."
          },
          "webhookUrl": {
            "title": "Webhook URL (optional)",
            "type": "string",
            "description": "Optional. If set, the run summary (table, rows written, columns added, warnings; never the rows themselves) is POSTed here as JSON the moment the push finishes, so a scheduled sync can tell Slack, Zapier, Make, n8n or your own API that the table is up to date. Only charged when the endpoint confirms receipt (HTTP 2xx); a failed delivery is reported as a warning 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}