{
  "name": "HyperFormula Edge Calc Service",
  "version": "0.6.0",
  "description": "Stateless spreadsheet calculation API. Send data (JSON or CSV) and formulas, get computed results. Supports 400+ Excel-compatible functions, named columns, and declarative groupBy aggregation.",
  "endpoint": "/api/calc",
  "method": "POST",
  "contentType": "application/json",
  "rateLimit": {
    "requests": 60,
    "windowSeconds": 60
  },
  "limits": {
    "maxRows": 50000,
    "maxCols": 50,
    "maxBodyBytes": 50000000,
    "maxFormulaLength": 2000,
    "maxFormulas": 100,
    "maxCellChars": 10000,
    "maxGroups": 10000
  },
  "parameters": {
    "data": {
      "type": "array of arrays",
      "required": "one of data or csv is required",
      "description": "2D array of cell values. Strings starting with '=' are evaluated as formulas. Row 0 is row 1 in formulas (A1, B1, ...). Mutually exclusive with 'csv'."
    },
    "csv": {
      "type": "string",
      "required": "one of data or csv is required",
      "description": "Raw CSV string. Parsed server-side into a 2D grid. Numeric values auto-detected. Supports quoted fields. Mutually exclusive with 'data'. Easiest way for AI agents to send data.",
      "example": "Region,Revenue,Cost\nEurope,1000,800\nAsia,2000,1500"
    },
    "headers": {
      "type": "boolean",
      "required": false,
      "description": "When true, row 1 is treated as column names. Formulas can reference columns by name (e.g. =SUM(Revenue)). Column names with spaces are sanitized (spaces→underscores). Response meta.columns shows the mapping. Required for groupBy."
    },
    "formulas": {
      "type": "array of strings",
      "required": false,
      "description": "Array of formulas (each starting with '='). All evaluated in one pass. Returns array of results in same order. Mutually exclusive with 'groupBy'. With headers:true, use column names directly.",
      "example": [
        "=SUM(Revenue)",
        "=AVERAGE(Cost)",
        "=COUNTIF(Region,\"Europe\")"
      ]
    },
    "groupBy": {
      "type": "object",
      "required": false,
      "description": "Declarative aggregation. Groups data by a column and computes aggregates per group. Requires headers:true. Mutually exclusive with formulas. Returns array of {group, ...aggregates} objects. Rows with a blank value in the 'by' column are skipped. Group values match exactly (case-sensitive). Up to 10,000 distinct groups.",
      "properties": {
        "by": {
          "type": "string",
          "description": "Column name to group by"
        },
        "aggregates": {
          "type": "object",
          "description": "Map of column name → aggregate function. Supported: SUM, AVERAGE, COUNT, MIN, MAX, MEDIAN"
        }
      },
      "example": {
        "by": "Region",
        "aggregates": {
          "Revenue": "SUM",
          "Units": "SUM"
        }
      }
    }
  },
  "modes": {
    "formulas": {
      "description": "Evaluate formulas, get array of results",
      "params": "data/csv + formulas"
    },
    "grid": {
      "description": "Embedded formulas in data cells, returns full evaluated grid",
      "params": "data/csv (with '=' formulas in cells)"
    },
    "groupBy": {
      "description": "Declarative aggregation by groups",
      "params": "csv/data + headers:true + groupBy"
    }
  },
  "examples": {
    "formulas": {
      "data": [
        [
          10,
          20
        ],
        [
          30,
          40
        ]
      ],
      "formulas": [
        "=SUM(A1:A2)",
        "=SUM(B1:B2)",
        "=AVERAGE(A1:B2)"
      ]
    },
    "csv_with_named_columns": {
      "csv": "name,score\nAlice,85\nBob,92\nCarol,78",
      "headers": true,
      "formulas": [
        "=SUM(score)",
        "=AVERAGE(score)"
      ]
    },
    "groupBy": {
      "csv": "Region,Revenue,Units\nEurope,1000,5\nAsia,2000,3\nEurope,1500,8",
      "headers": true,
      "groupBy": {
        "by": "Region",
        "aggregates": {
          "Revenue": "SUM",
          "Units": "SUM"
        }
      }
    },
    "embedded": {
      "data": [
        [
          "a",
          "b",
          "sum"
        ],
        [
          1,
          2,
          "=A2+B2"
        ],
        [
          3,
          4,
          "=A3+B3"
        ]
      ]
    }
  },
  "commonFormulas": [
    "SUM",
    "AVERAGE",
    "COUNT",
    "COUNTA",
    "COUNTIF",
    "COUNTIFS",
    "SUMIF",
    "SUMIFS",
    "MIN",
    "MAX",
    "MEDIAN",
    "IF",
    "IFS",
    "IFERROR",
    "AND",
    "OR",
    "NOT",
    "VLOOKUP",
    "HLOOKUP",
    "XLOOKUP",
    "INDEX",
    "MATCH",
    "UNIQUE",
    "SORT",
    "FILTER",
    "LEFT",
    "RIGHT",
    "MID",
    "LEN",
    "TRIM",
    "CONCATENATE",
    "SUBSTITUTE",
    "ROUND",
    "ROUNDUP",
    "ROUNDDOWN",
    "ABS",
    "MOD",
    "POWER",
    "DATE",
    "YEAR",
    "MONTH",
    "DAY",
    "TODAY",
    "NOW",
    "TEXT",
    "VALUE",
    "LARGE",
    "SMALL",
    "RANK"
  ],
  "columnReference": "Columns are letters: A=0, B=1, C=2, ... Z=25, AA=26. Rows are 1-indexed. With headers:true, use column names directly in formulas instead of cell references.",
  "links": {
    "openapi": "/openapi.json",
    "mcp": "/mcp",
    "formulaDocs": "https://hyperformula.handsontable.com/guide/built-in-functions.html"
  }
}