{
  "openapi": "3.0.1",
  "info": {
    "title": "Dataset AI Enrich (LLM Classify, Extract, Summarise Rows)",
    "description": "Runs one plain-English instruction against every row of any Apify dataset, CSV/Excel/JSON file URL or JSON array and writes the answer back as new structured columns: classify, extract, score, summarise, translate. No API key needed (tokens billed via apify/openrouter). Pay per enriched row.",
    "version": "0.1",
    "x-build-id": "kK61pnYH5GazcHQOl"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nerolabs~dataset-ai-enrich/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nerolabs-dataset-ai-enrich",
        "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-ai-enrich/runs": {
      "post": {
        "operationId": "runs-sync-nerolabs-dataset-ai-enrich",
        "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-ai-enrich/run-sync": {
      "post": {
        "operationId": "run-sync-nerolabs-dataset-ai-enrich",
        "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",
        "required": [
          "prompt"
        ],
        "properties": {
          "datasetId": {
            "title": "Dataset to enrich",
            "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 JSON Lines)",
            "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 with sharing set to 'Anyone with the link can view'). Format detected automatically. Up to 100 MB."
          },
          "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"
          },
          "data": {
            "title": "Data (inline)",
            "type": "array",
            "description": "A JSON array of records to enrich, for ad-hoc data instead of a dataset ID or file URL."
          },
          "prompt": {
            "title": "Instruction (applied to every row)",
            "type": "string",
            "description": "Plain-English instruction applied to each row on its own. Use {{field}} placeholders to insert that row's values (dotted paths like {{address.city}} work). Only the fields you reference are sent to the model; if you reference none, every field is sent. Examples: classify, extract a value, score 1 to 10, summarise, translate, normalise a job title, decide yes/no."
          },
          "outputFields": {
            "title": "Output columns",
            "type": "array",
            "description": "The new columns the model must fill in for every row, as a JSON list of {\"name\", \"type\", \"description\"}. Types: string (default), number, boolean, array, object. The description tells the model exactly what goes in the column (allowed values, units, language). Leave empty to get one free-text column called 'aiResponse'."
          },
          "systemPrompt": {
            "title": "Extra context (optional)",
            "type": "string",
            "description": "Optional background the model should know for every row: your industry, the categories you use, the language to answer in, edge-case rules."
          },
          "model": {
            "title": "Model",
            "enum": [
              "anthropic/claude-haiku-4.5",
              "anthropic/claude-sonnet-4.5",
              "openai/gpt-4.1-nano",
              "openai/gpt-4.1-mini",
              "openai/gpt-4o-mini",
              "openai/gpt-5-mini",
              "google/gemini-2.5-flash-lite",
              "google/gemini-2.5-flash",
              "deepseek/deepseek-v3.2",
              "mistralai/mistral-small-3.2-24b-instruct"
            ],
            "type": "string",
            "description": "Which model answers. Claude Haiku 4.5 is the default: fast, accurate on classification and extraction, about $0.001 of tokens per typical row. Cheaper options for simple labelling: GPT-4.1 nano, Gemini 2.5 Flash Lite, Mistral Small. Stronger options for nuanced judgement: Claude Sonnet 4.5, GPT-5 mini.",
            "default": "anthropic/claude-haiku-4.5"
          },
          "customModel": {
            "title": "Custom model id (optional, overrides Model)",
            "type": "string",
            "description": "Any model id from openrouter.ai/models in vendor/model form, e.g. anthropic/claude-opus-4.5 or meta-llama/llama-3.3-70b-instruct."
          },
          "openRouterApiKey": {
            "title": "Your own OpenRouter API key (optional)",
            "type": "string",
            "description": "If set, requests go straight to openrouter.ai on your own key and no token cost is billed through Apify. Leave empty to use Apify's built-in proxy with no key at all."
          },
          "previewRows": {
            "title": "Preview: only process the first N rows",
            "minimum": 0,
            "type": "integer",
            "description": "Test your instruction cheaply before running everything: set to 5 or 10, check the output columns, then set back to 0 for the full run.",
            "default": 0
          },
          "maxRows": {
            "title": "Maximum rows to process",
            "minimum": 1,
            "maximum": 50000,
            "type": "integer",
            "description": "A cost guard. Rows beyond this are not loaded. Hard ceiling 50,000 per run.",
            "default": 1000
          },
          "rowsPerRequest": {
            "title": "Rows per model request",
            "minimum": 1,
            "maximum": 25,
            "type": "integer",
            "description": "How many rows share one model call. Higher is cheaper (the instruction is sent once per call) and faster; lower is safer for long texts. 5 is a good default; use 1 for very long rows.",
            "default": 5
          },
          "concurrency": {
            "title": "Parallel requests",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many model calls run at once.",
            "default": 4
          },
          "maxInputCharsPerField": {
            "title": "Max characters per field sent to the model",
            "minimum": 100,
            "maximum": 50000,
            "type": "integer",
            "description": "Longer values are cut (with a '[truncated]' marker) so one huge text field can't run up the token bill.",
            "default": 4000
          },
          "maxOutputTokensPerRow": {
            "title": "Max answer length per row (tokens)",
            "minimum": 20,
            "maximum": 1000,
            "type": "integer",
            "description": "150 covers a label plus a short summary; raise it for long summaries or translations.",
            "default": 150
          },
          "temperature": {
            "title": "Temperature",
            "minimum": 0,
            "maximum": 2,
            "type": "integer",
            "description": "0 (default) for consistent, repeatable answers, which is what classification and extraction need. Only raise it for creative rewriting. Whole number 0 to 2.",
            "default": 0
          },
          "skipIfEmpty": {
            "title": "Skip rows whose referenced fields are all empty",
            "type": "boolean",
            "description": "On (default): a row with nothing in any {{field}} the instruction uses is written out with 'aiSkipped: true' and never sent to the model or charged.",
            "default": true
          },
          "includeOriginalFields": {
            "title": "Keep the original fields in the output",
            "type": "boolean",
            "description": "On (default): each output row is the original row plus the new columns. Off: only the new columns (plus aiModel/aiError).",
            "default": true
          },
          "outputDatasetName": {
            "title": "Also append to a named dataset",
            "type": "string",
            "description": "Optional. A name (3 to 63 letters, digits or hyphens). Enriched rows are appended to a dataset with this name in your account, created on the first run, so scheduled runs accumulate in one place. Not charged again."
          },
          "exportFormats": {
            "title": "Export file formats",
            "uniqueItems": true,
            "type": "array",
            "description": "Also save the enriched rows as a real downloadable file in the run's key-value store. CSV opens anywhere; XLSX opens in Excel and Google Sheets.",
            "items": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx"
              ],
              "enumTitles": [
                "CSV (.csv)",
                "Excel (.xlsx)"
              ]
            }
          },
          "webhookUrl": {
            "title": "Webhook URL (optional)",
            "type": "string",
            "description": "Optional. If set, the enriched rows (plus download links and a summary) are POSTed here as JSON the moment the run finishes. Works with a Zapier/Make/n8n catch-hook, your own API, or a Slack incoming webhook. Only charged on a confirmed HTTP 2xx; a failed delivery is 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}