{
  "openapi": "3.0.3",
  "info": {
    "title": "Chimera NAS REST API",
    "description": "REST API for managing Chimera NAS server configuration including users, VFS mounts, NFS exports, SMB shares, and S3 buckets.",
    "version": "1.0.0",
    "license": {
      "name": "LGPL-2.1-only",
      "url": "https://spdx.org/licenses/LGPL-2.1-only.html"
    }
  },
  "servers": [
    {
      "url": "/api/v1",
      "description": "Chimera NAS REST API v1"
    }
  ],
  "security": [{"bearerAuth": []}, {"basicAuth": []}],
  "paths": {
    "/config": {
      "get": {
        "summary": "Get server configuration",
        "description": "Returns the running server configuration as a JSON document compatible with the chimera.json file format, reconstructed from live runtime state. The \"users\" section (passwords) and the \"server\" section are omitted, and the internal \"root\" mount is excluded.",
        "operationId": "getConfig",
        "tags": ["Config"],
        "responses": {
          "200": {
            "description": "Server configuration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Config"
                }
              }
            }
          }
        }
      }
    },
    "/auth/login": {
      "post": {
        "summary": "Authenticate",
        "description": "Authenticate with username and password to obtain a JWT token.",
        "operationId": "login",
        "tags": ["Authentication"],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authentication successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users": {
      "get": {
        "summary": "List builtin users",
        "description": "Returns a list of all builtin (pinned) users in the system.",
        "operationId": "listUsers",
        "tags": ["Users"],
        "responses": {
          "200": {
            "description": "List of users",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/User"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      },
      "post": {
        "summary": "Create user",
        "description": "Creates a new builtin user.",
        "operationId": "createUser",
        "tags": ["Users"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "User created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Failed to create user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      }
    },
    "/users/{username}": {
      "get": {
        "summary": "Get user",
        "description": "Returns details for a specific user.",
        "operationId": "getUser",
        "tags": ["Users"],
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "User not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete user",
        "description": "Deletes a user from the system.",
        "operationId": "deleteUser",
        "tags": ["Users"],
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "User deleted"
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "User not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/mounts": {
      "get": {
        "summary": "List VFS mounts",
        "description": "Returns a list of all VFS mounts.",
        "operationId": "listMounts",
        "tags": ["VFS Mounts"],
        "responses": {
          "200": {
            "description": "List of mounts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Mount"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      },
      "post": {
        "summary": "Create VFS mount",
        "description": "Creates a new VFS mount.",
        "operationId": "createMount",
        "tags": ["VFS Mounts"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MountCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Mount created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              }
            }
          },
          "400": {
            "description": "Bad request (missing required field or malformed options)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "A mount with that name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Failed to create mount",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      }
    },
    "/mounts/{name}": {
      "get": {
        "summary": "Get VFS mount",
        "description": "Returns details for a specific VFS mount.",
        "operationId": "getMount",
        "tags": ["VFS Mounts"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Mount details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mount"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "Mount not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete VFS mount",
        "description": "Deletes a VFS mount.",
        "operationId": "deleteMount",
        "tags": ["VFS Mounts"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Mount deleted"
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "Mount not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/exports": {
      "get": {
        "summary": "List NFS exports",
        "description": "Returns a list of all NFS exports.",
        "operationId": "listExports",
        "tags": ["NFS Exports"],
        "responses": {
          "200": {
            "description": "List of exports",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Export"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      },
      "post": {
        "summary": "Create NFS export",
        "description": "Creates a new NFS export.",
        "operationId": "createExport",
        "tags": ["NFS Exports"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Export created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - export name or export_id already in use",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Failed to create export",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      }
    },
    "/exports/{name}": {
      "get": {
        "summary": "Get NFS export",
        "description": "Returns details for a specific NFS export.",
        "operationId": "getExport",
        "tags": ["NFS Exports"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Export details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Export"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "Export not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete NFS export",
        "description": "Deletes an NFS export.",
        "operationId": "deleteExport",
        "tags": ["NFS Exports"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Export deleted"
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "Export not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/shares": {
      "get": {
        "summary": "List SMB shares",
        "description": "Returns a list of all SMB shares.",
        "operationId": "listShares",
        "tags": ["SMB Shares"],
        "responses": {
          "200": {
            "description": "List of shares",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Share"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      },
      "post": {
        "summary": "Create SMB share",
        "description": "Creates a new SMB share.",
        "operationId": "createShare",
        "tags": ["SMB Shares"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShareCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Share created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Failed to create share",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      }
    },
    "/shares/{name}": {
      "get": {
        "summary": "Get SMB share",
        "description": "Returns details for a specific SMB share.",
        "operationId": "getShare",
        "tags": ["SMB Shares"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Share details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Share"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "Share not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete SMB share",
        "description": "Deletes an SMB share.",
        "operationId": "deleteShare",
        "tags": ["SMB Shares"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Share deleted"
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "Share not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/buckets": {
      "get": {
        "summary": "List S3 buckets",
        "description": "Returns a list of all S3 buckets.",
        "operationId": "listBuckets",
        "tags": ["S3 Buckets"],
        "responses": {
          "200": {
            "description": "List of buckets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Bucket"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      },
      "post": {
        "summary": "Create S3 bucket",
        "description": "Creates a new S3 bucket.",
        "operationId": "createBucket",
        "tags": ["S3 Buckets"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BucketCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Bucket created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Failed to create bucket",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          }
        }
      }
    },
    "/buckets/{name}": {
      "get": {
        "summary": "Get S3 bucket",
        "description": "Returns details for a specific S3 bucket.",
        "operationId": "getBucket",
        "tags": ["S3 Buckets"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Bucket details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Bucket"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "Bucket not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete S3 bucket",
        "description": "Deletes an S3 bucket.",
        "operationId": "deleteBucket",
        "tags": ["S3 Buckets"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Bucket deleted"
          },
          "401": {
            "description": "Unauthorized - missing or invalid Bearer token"
          },
          "404": {
            "description": "Bucket not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "basicAuth": {
        "type": "http",
        "scheme": "basic"
      }
    },
    "schemas": {
      "LoginRequest": {
        "type": "object",
        "required": ["username", "password"],
        "properties": {
          "username": {
            "type": "string",
            "description": "Username"
          },
          "password": {
            "type": "string",
            "description": "Password"
          }
        }
      },
      "LoginResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "JWT token"
          },
          "expires_in": {
            "type": "integer",
            "description": "Token expiry in seconds"
          }
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string",
            "description": "Username"
          },
          "uid": {
            "type": "integer",
            "description": "User ID"
          },
          "gid": {
            "type": "integer",
            "description": "Primary group ID"
          },
          "gids": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Supplementary group IDs"
          },
          "pinned": {
            "type": "boolean",
            "description": "Whether user is pinned (builtin)"
          }
        }
      },
      "UserCreate": {
        "type": "object",
        "required": ["username"],
        "properties": {
          "username": {
            "type": "string",
            "description": "Username (required)"
          },
          "password": {
            "type": "string",
            "description": "Password (optional)"
          },
          "smbpasswd": {
            "type": "string",
            "description": "SMB/NTLM password hash (optional)"
          },
          "uid": {
            "type": "integer",
            "description": "User ID (optional, defaults to 0 if omitted)"
          },
          "gid": {
            "type": "integer",
            "description": "Primary group ID (optional, defaults to 0 if omitted)"
          },
          "gids": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "maxItems": 64,
            "description": "Supplementary group IDs (optional, at most 64; more than 64 returns 400 Bad Request)"
          }
        }
      },
      "Mount": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Mount name (the VFS mount path)"
          },
          "module": {
            "type": "string",
            "description": "VFS module backing the mount (e.g. linux, memfs)"
          },
          "path": {
            "type": "string",
            "description": "Backing path passed to the module"
          },
          "options": {
            "type": "string",
            "description": "Comma-separated key[=value] options string; only present when the mount was created with options"
          }
        }
      },
      "MountCreate": {
        "type": "object",
        "required": ["name", "module", "path"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Mount name (the VFS mount path)"
          },
          "module": {
            "type": "string",
            "description": "VFS module backing the mount (e.g. linux, memfs)"
          },
          "path": {
            "type": "string",
            "description": "Backing path passed to the module"
          },
          "options": {
            "type": "string",
            "description": "Optional comma-separated key[=value] options string"
          }
        }
      },
      "Export": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Export name"
          },
          "path": {
            "type": "string",
            "description": "VFS path"
          },
          "export_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4095,
            "description": "Stable export identifier embedded in NFS file handles"
          }
        }
      },
      "ExportCreate": {
        "type": "object",
        "required": ["name", "path"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Export name"
          },
          "path": {
            "type": "string",
            "description": "VFS path"
          },
          "export_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4095,
            "description": "Optional explicit export id (1..4095); auto-assigned when omitted. Must match across clustered servers exporting the same directory so file handles stay valid on failover."
          }
        }
      },
      "Share": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Share name"
          },
          "path": {
            "type": "string",
            "description": "VFS path"
          }
        }
      },
      "ShareCreate": {
        "type": "object",
        "required": ["name", "path"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Share name"
          },
          "path": {
            "type": "string",
            "description": "VFS path"
          }
        }
      },
      "Bucket": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Bucket name"
          },
          "path": {
            "type": "string",
            "description": "VFS path"
          }
        }
      },
      "BucketCreate": {
        "type": "object",
        "required": ["name", "path"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Bucket name"
          },
          "path": {
            "type": "string",
            "description": "VFS path"
          }
        }
      },
      "Config": {
        "type": "object",
        "description": "Server configuration in chimera.json format. Excludes the users section (passwords) and the server section; the internal root mount is excluded from mounts.",
        "properties": {
          "mounts": {
            "type": "object",
            "description": "VFS mounts keyed by mount name (the internal root mount is excluded)",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "module": {
                  "type": "string",
                  "description": "VFS module name"
                },
                "path": {
                  "type": "string",
                  "description": "Backend path"
                },
                "options": {
                  "type": "string",
                  "description": "Comma-separated key[=value] options string; only present when the mount was created with options"
                }
              }
            }
          },
          "exports": {
            "type": "object",
            "description": "NFS exports keyed by export name",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string",
                  "description": "VFS path"
                },
                "export_id": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 4095,
                  "description": "Stable export identifier embedded in NFS file handles"
                }
              }
            }
          },
          "shares": {
            "type": "object",
            "description": "SMB shares keyed by share name",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string",
                  "description": "VFS path"
                }
              }
            }
          },
          "buckets": {
            "type": "object",
            "description": "S3 buckets keyed by bucket name",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string",
                  "description": "VFS path"
                }
              }
            }
          }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Success message"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error type"
          },
          "message": {
            "type": "string",
            "description": "Error message"
          }
        }
      }
    }
  }
}
