{
  "openapi": "3.0.3",
  "info": {
    "title": "Exceli Public API",
    "version": "1.0.0",
    "description": "Public REST JSON API for Exceli — 500+ Excel functions with Persian + 6 translated locales (fa, en, de, fr, tr, az, ar). CORS enabled. No auth. Rate limit 60 req/min per IP.",
    "contact": { "url": "https://exceli.ir", "name": "Exceli" },
    "license": { "name": "MIT" }
  },
  "servers": [
    { "url": "http://localhost:8070", "description": "Local dev (php -S)" },
    { "url": "https://exceli.ir", "description": "Production" }
  ],
  "paths": {
    "/api/v1": {
      "get": {
        "summary": "API info",
        "operationId": "getInfo",
        "responses": {
          "200": { "description": "API info", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Envelope" } } } }
        }
      }
    },
    "/api/v1/functions": {
      "get": {
        "summary": "List functions",
        "operationId": "listFunctions",
        "parameters": [
          { "name": "q", "in": "query", "schema": { "type": "string" }, "description": "Search term (title, slug, description)" },
          { "name": "category", "in": "query", "schema": { "type": "string" }, "description": "Filter by category slug e.g. math-trig, logical, text" },
          { "name": "sort", "in": "query", "schema": { "type": "string", "enum": ["popular","alpha","views"], "default": "popular" } },
          { "name": "page", "in": "query", "schema": { "type": "integer", "minimum": 1, "default": 1 } },
          { "name": "per_page", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } },
          { "name": "lang", "in": "query", "schema": { "type": "string", "enum": ["fa","en","de","fr","tr","az","ar"], "default": "fa" } }
        ],
        "responses": {
          "200": { "description": "Paginated function list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FunctionListEnvelope" } } } },
          "429": { "description": "Rate limited" }
        }
      }
    },
    "/api/v1/function/{slug}": {
      "get": {
        "summary": "Get single function",
        "operationId": "getFunction",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[a-z0-9.\\-]+$" }, "description": "Function slug e.g. sum, vlookup, xlookup" },
          { "name": "lang", "in": "query", "schema": { "type": "string", "enum": ["fa","en","de","fr","tr","az","ar"], "default": "fa" } }
        ],
        "responses": {
          "200": { "description": "Function detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FunctionEnvelope" } } } },
          "404": { "description": "Not found" }
        }
      }
    },
    "/api/v1/categories": {
      "get": {
        "summary": "List categories with counts",
        "operationId": "listCategories",
        "parameters": [ { "name": "lang", "in": "query", "schema": { "type": "string", "enum": ["fa","en","de","fr","tr","az","ar"], "default": "fa" } } ],
        "responses": { "200": { "description": "Categories", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CategoryListEnvelope" } } } } }
      }
    },
    "/api/v1/search": {
      "get": {
        "summary": "Search functions",
        "operationId": "searchFunctions",
        "parameters": [
          { "name": "q", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 20 } },
          { "name": "lang", "in": "query", "schema": { "type": "string", "enum": ["fa","en","de","fr","tr","az","ar"] } }
        ],
        "responses": { "200": { "description": "Search results" } }
      }
    },
    "/api/v1/random": {
      "get": {
        "summary": "Random function",
        "operationId": "randomFunction",
        "parameters": [ { "name": "lang", "in": "query", "schema": { "type": "string", "enum": ["fa","en","de","fr","tr","az","ar"] } } ],
        "responses": { "200": { "description": "Random function" } }
      }
    }
  },
  "components": {
    "schemas": {
      "Envelope": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "type": "object" }, "meta": { "type": "object" }, "error": { "type": "string" } } },
      "FunctionBrief": {
        "type": "object",
        "properties": {
          "slug": { "type": "string", "example": "sum" },
          "title": { "type": "string", "example": "SUM" },
          "category": { "type": "string", "example": "math-trig" },
          "description": { "type": "string" },
          "syntax": { "type": "string", "example": "=SUM(number1, [number2], ...)" },
          "popularity": { "type": "integer" },
          "views": { "type": "integer" },
          "output": { "type": "string" },
          "version": { "type": "string" },
          "url": { "type": "string" }
        }
      },
      "Function": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "title": { "type": "string" },
          "category": { "type": "string" },
          "applications": { "type": "array", "items": { "type": "string" } },
          "syntax": { "type": "string" },
          "description": { "type": "string" },
          "output": { "type": "string" },
          "version": { "type": "string" },
          "volatile": { "type": "boolean" },
          "dynamicArray": { "type": "boolean" },
          "popularity": { "type": "integer" },
          "views": { "type": "integer" },
          "args": { "type": "array", "items": { "$ref": "#/components/schemas/Arg" } },
          "examples": { "type": "array", "items": { "$ref": "#/components/schemas/Example" } },
          "tips": { "type": "array", "items": { "type": "string" } },
          "errors": { "type": "array", "items": { "$ref": "#/components/schemas/FuncError" } },
          "related": { "type": "array", "items": { "type": "string" } },
          "links": { "type": "object", "properties": { "url": { "type": "string" }, "canonical": { "type": "string" }, "api": { "type": "string" } } }
        }
      },
      "Arg": { "type": "object", "properties": { "name": { "type": "string" }, "type": { "type": "string" }, "required": { "type": "boolean" }, "desc": { "type": "string" } } },
      "Example": { "type": "object", "properties": { "title": { "type": "string" }, "code": { "type": "string" } } },
      "FuncError": { "type": "object", "properties": { "code": { "type": "string", "example": "#VALUE!" }, "desc": { "type": "string" }, "fix": { "type": "string" } } },
      "Category": { "type": "object", "properties": { "slug": { "type": "string" }, "title": { "type": "string" }, "en": { "type": "string" }, "count": { "type": "integer" }, "icon": { "type": "string" }, "color": { "type": "string" }, "url": { "type": "string" }, "api": { "type": "string" } } },
      "Meta": { "type": "object", "properties": { "total": { "type": "integer" }, "page": { "type": "integer" }, "per_page": { "type": "integer" }, "pages": { "type": "integer" }, "lang": { "type": "string" } } },
      "FunctionListEnvelope": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/FunctionBrief" } }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "FunctionEnvelope": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "$ref": "#/components/schemas/Function" }, "meta": { "type": "object" } } },
      "CategoryListEnvelope": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/Category" } }, "meta": { "type": "object" } } }
    }
  }
}
