{
  "openapi": "3.0.1",
  "info": {
    "title": "PDF Extractor: Bulk PDF to Text, Tables & Markdown from a CSV",
    "description": "Extracts text, tables and metadata from every PDF linked in an Apify dataset, CSV, Excel or Google Sheet, keeping your original columns. Inputs: datasetId or fileUrl or pdfUrls, urlField. Scans with no text layer are flagged, not guessed. Charged per document. Agent-ready: x402, MCP.",
    "version": "0.1",
    "x-build-id": "kGe1PJd323iIZ4ebf"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nerolabs~dataset-pdf-extract/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nerolabs-dataset-pdf-extract",
        "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-pdf-extract/runs": {
      "post": {
        "operationId": "runs-sync-nerolabs-dataset-pdf-extract",
        "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-pdf-extract/run-sync": {
      "post": {
        "operationId": "run-sync-nerolabs-dataset-pdf-extract",
        "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",
            "type": "string",
            "description": "An Apify dataset holding one row per PDF, for example the output of a scraper that collected document links. Every original column is kept and the extracted text, tables and metadata are added alongside. Use the picker rather than typing an ID."
          },
          "fileUrl": {
            "title": "File or Google Sheet URL",
            "type": "string",
            "description": "A public link to a CSV, TSV, Excel, JSON or JSON Lines file holding one row per PDF. A normal Google Sheets link works: share it as 'Anyone with the link can view'. Used when no dataset is given."
          },
          "fileFormat": {
            "title": "File format",
            "enum": [
              "auto",
              "csv",
              "tsv",
              "json",
              "jsonl",
              "xlsx"
            ],
            "type": "string",
            "description": "Leave on 'Detect automatically' unless the link has no file extension and the server reports the wrong content type.",
            "default": "auto"
          },
          "sheetName": {
            "title": "Excel sheet name",
            "type": "string",
            "description": "Which sheet to read from an Excel workbook. Defaults to the first sheet."
          },
          "pdfUrls": {
            "title": "PDF URLs",
            "type": "array",
            "description": "A plain list of PDF links, for a quick one-off run with no spreadsheet. Use the dataset, file or Google Sheet inputs above to keep your own columns alongside the results.",
            "items": {
              "type": "string"
            }
          },
          "data": {
            "title": "Rows",
            "type": "array",
            "description": "Rows as inline JSON, an alternative to a dataset or file. Each object needs a field holding the PDF link."
          },
          "urlField": {
            "title": "PDF URL field",
            "type": "string",
            "description": "The column holding the PDF link. Left empty it is detected automatically, preferring a column whose values end in .pdf over one merely named 'url'."
          },
          "textFormat": {
            "title": "Text output",
            "enum": [
              "plain",
              "markdown",
              "none"
            ],
            "type": "string",
            "description": "'Plain text' returns the reading-order text. 'Markdown' appends any detected tables as Markdown tables after the text, which is the friendliest shape for feeding an LLM. 'None' skips the text entirely, for runs that only want page counts, metadata or tables.",
            "default": "plain"
          },
          "extractTables": {
            "title": "Extract tables",
            "type": "boolean",
            "description": "Reconstruct tables from the position of the text on the page and return them as rows of cells. Plain text extraction loses table structure completely, so this is where most of the value is for invoices, statements and reports.",
            "default": true
          },
          "minTableRows": {
            "title": "Smallest table to report",
            "minimum": 2,
            "maximum": 50,
            "type": "integer",
            "description": "Minimum rows before a grid counts as a table. The default of 3 is a deliberate noise floor, because printed forms are built from aligned two-line boxes and report dozens of meaningless two-row 'tables'. Lower it to 2 for invoices whose line items are one header plus one row.",
            "default": 3
          },
          "includePageText": {
            "title": "Include per-page text",
            "type": "boolean",
            "description": "Add a 'pages' array with each page's text separately, on top of the combined text. Useful for citing a page number, and it makes rows considerably larger.",
            "default": false
          },
          "firstPage": {
            "title": "First page",
            "minimum": 1,
            "type": "integer",
            "description": "Start reading at this page (1 is the first). Leave empty to read from the beginning."
          },
          "lastPage": {
            "title": "Last page",
            "minimum": 1,
            "type": "integer",
            "description": "Stop reading after this page. Leave empty to read to the end. Handy for taking only the first few pages of long reports."
          },
          "maxCharsPerPdf": {
            "title": "Character limit per document",
            "minimum": 500,
            "maximum": 2000000,
            "type": "integer",
            "description": "Cuts the returned text at this many characters so one very long document cannot produce an unusable dataset row. The row records whether it was cut.",
            "default": 200000
          },
          "keep": {
            "title": "Which rows to keep",
            "enum": [
              "all",
              "extracted",
              "needs_ocr",
              "problems"
            ],
            "type": "string",
            "description": "Filtering happens after the document has been fetched and read, so it does not make a run cheaper. 'Problems only' is the quick way to find broken links in a large list.",
            "default": "all"
          },
          "keepOriginalFields": {
            "title": "Keep my original columns",
            "type": "boolean",
            "description": "Keep every column from the input row next to the extracted fields, so results line up with your own data. Turn off for text and metadata only.",
            "default": true
          },
          "concurrency": {
            "title": "Documents at a time",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many documents to download and parse in parallel. Keep it modest when every link points at the same server.",
            "default": 3
          },
          "requestTimeoutSecs": {
            "title": "Download timeout",
            "minimum": 5,
            "maximum": 300,
            "type": "integer",
            "description": "How long to wait for one document before giving up on it. A timed-out document is never charged.",
            "default": 60
          },
          "maxDocumentMb": {
            "title": "Largest document",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Documents bigger than this are skipped and not charged, rather than spending the run's memory on one enormous file.",
            "default": 50
          },
          "maxItems": {
            "title": "Maximum documents",
            "minimum": 1,
            "maximum": 50000,
            "type": "integer",
            "description": "A hard ceiling on how many rows are read from the input, as a safety net on a large dataset."
          },
          "exportFormats": {
            "title": "Export files",
            "type": "array",
            "description": "Also write the results as a real downloadable CSV or Excel file, linked from the run's output. Tables and per-page text are JSON-encoded into single cells so they fit a spreadsheet.",
            "items": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx"
              ],
              "enumTitles": [
                "CSV",
                "Excel (xlsx)"
              ]
            },
            "default": []
          },
          "outputDatasetName": {
            "title": "Append to named dataset",
            "type": "string",
            "description": "Also append every kept row to a named dataset that persists across runs, building one growing document archive. Not charged again."
          },
          "webhookUrl": {
            "title": "Webhook URL",
            "type": "string",
            "description": "POST the run summary to this URL when the run finishes, for Slack, Zapier, Make, n8n or your own API. Charged only on a confirmed 2xx response."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}