{ "openapi": "3.1.0", "info": { "title": "aiquila", "version": "0.0.1", "description": "Private AI in your Nextcloud — chat, agents and MCP tools, with the AI provider you choose", "license": { "name": "AGPL-3.0-or-later", "identifier": "AGPL-3.0-or-later" } }, "components": { "securitySchemes": { "basic_auth": { "type": "http", "scheme": "basic" }, "bearer_auth": { "type": "http", "scheme": "bearer" } }, "schemas": {} }, "paths": { "/index.php/apps/aiquila/api/conversations": { "get": { "operationId": "conversation-index", "summary": "List all conversations for the current user", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "List of conversations", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "required": [ "id", "userId", "title", "model", "provider", "createdAt", "updatedAt", "projectId", "effort", "thinking", "thinkingBudget", "speedFast" ], "properties": { "id": { "type": "integer", "format": "int64" }, "userId": { "type": "string" }, "title": { "type": [ "string", "null" ] }, "model": { "type": "string" }, "provider": { "type": [ "string", "null" ] }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" }, "projectId": { "type": [ "integer", "null" ], "format": "int64" }, "effort": { "type": [ "string", "null" ] }, "thinking": { "type": [ "boolean", "null" ] }, "thinkingBudget": { "type": [ "integer", "null" ], "format": "int64" }, "speedFast": { "type": [ "boolean", "null" ] } } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "post": { "operationId": "conversation-create", "summary": "Create a new conversation", "description": "Provider and model are snapshotted so the conversation keeps answering from where it started even after the user changes their default. Omit both to follow the user's setting (`provider` stays null).", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "provider": { "type": [ "string", "null" ], "default": null, "description": "Provider to pin (null/'' follows the user's setting)" }, "model": { "type": [ "string", "null" ], "default": null, "description": "Model to pin (null/'' uses the provider's default)" } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The created conversation", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "userId", "title", "model", "provider", "createdAt", "updatedAt", "projectId", "effort", "thinking", "thinkingBudget", "speedFast" ], "properties": { "id": { "type": "integer", "format": "int64" }, "userId": { "type": "string" }, "title": { "type": [ "string", "null" ] }, "model": { "type": "string" }, "provider": { "type": [ "string", "null" ] }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" }, "projectId": { "type": [ "integer", "null" ], "format": "int64" }, "effort": { "type": [ "string", "null" ] }, "thinking": { "type": [ "boolean", "null" ] }, "thinkingBudget": { "type": [ "integer", "null" ], "format": "int64" }, "speedFast": { "type": [ "boolean", "null" ] } } } } } }, "400": { "description": "Unknown provider", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "403": { "description": "The provider is not permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/conversations/{id}": { "get": { "operationId": "conversation-show", "summary": "Get a conversation with its messages and files", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Conversation with messages", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "userId", "title", "model", "provider", "createdAt", "updatedAt", "projectId", "effort", "thinking", "thinkingBudget", "speedFast", "messages" ], "properties": { "id": { "type": "integer", "format": "int64" }, "userId": { "type": "string" }, "title": { "type": [ "string", "null" ] }, "model": { "type": "string" }, "provider": { "type": [ "string", "null" ] }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" }, "projectId": { "type": [ "integer", "null" ], "format": "int64" }, "effort": { "type": [ "string", "null" ] }, "thinking": { "type": [ "boolean", "null" ] }, "thinkingBudget": { "type": [ "integer", "null" ], "format": "int64" }, "speedFast": { "type": [ "boolean", "null" ] }, "messages": { "type": "array", "items": { "type": "object", "required": [ "id", "conversationId", "role", "content", "inputTokens", "outputTokens", "cacheCreationTokens", "cacheReadTokens", "latencyMs", "citations", "documents", "thinkingSummary", "createdAt", "files" ], "properties": { "id": { "type": "integer", "format": "int64" }, "conversationId": { "type": "integer", "format": "int64" }, "role": { "type": "string" }, "content": { "type": "string" }, "inputTokens": { "type": [ "integer", "null" ], "format": "int64" }, "outputTokens": { "type": [ "integer", "null" ], "format": "int64" }, "cacheCreationTokens": { "type": [ "integer", "null" ], "format": "int64" }, "cacheReadTokens": { "type": [ "integer", "null" ], "format": "int64" }, "latencyMs": { "type": [ "integer", "null" ], "format": "int64" }, "citations": { "type": [ "object", "null" ], "additionalProperties": { "type": "object" } }, "documents": { "type": [ "object", "null" ], "additionalProperties": { "type": "object" } }, "thinkingSummary": { "type": [ "string", "null" ] }, "createdAt": { "type": "integer", "format": "int64" }, "files": { "type": "array", "items": { "type": "object", "required": [ "id", "messageId", "filePath", "fileName", "mimeType", "createdAt" ], "properties": { "id": { "type": "integer", "format": "int64" }, "messageId": { "type": "integer", "format": "int64" }, "filePath": { "type": "string" }, "fileName": { "type": "string" }, "mimeType": { "type": [ "string", "null" ] }, "createdAt": { "type": "integer", "format": "int64" } } } } } } } } } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "put": { "operationId": "conversation-update", "summary": "Update a conversation (title, project link, effort, thinking and/or fast-mode override)", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "type": "string", "default": "", "description": "New title" }, "projectId": { "type": [ "integer", "null" ], "format": "int64", "default": null, "description": "Project ID to link (null to clear)" }, "effort": { "type": [ "string", "null" ], "default": null, "description": "Effort override (low…max; empty string clears)" }, "thinking": { "type": [ "string", "null" ], "default": null, "description": "Adaptive-thinking override ('on'/'off'; empty string clears)" }, "thinkingBudget": { "type": [ "string", "null" ], "default": null, "description": "Explicit thinking budget in tokens (empty string clears)" }, "speedFast": { "type": [ "string", "null" ], "default": null, "description": "Fast-mode override ('on'/'off'; empty string clears)" } } } } } }, "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Updated conversation", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "userId", "title", "model", "provider", "createdAt", "updatedAt", "projectId", "effort", "thinking", "thinkingBudget", "speedFast" ], "properties": { "id": { "type": "integer", "format": "int64" }, "userId": { "type": "string" }, "title": { "type": [ "string", "null" ] }, "model": { "type": "string" }, "provider": { "type": [ "string", "null" ] }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" }, "projectId": { "type": [ "integer", "null" ], "format": "int64" }, "effort": { "type": [ "string", "null" ] }, "thinking": { "type": [ "boolean", "null" ] }, "thinkingBudget": { "type": [ "integer", "null" ], "format": "int64" }, "speedFast": { "type": [ "boolean", "null" ] } } } } } }, "400": { "description": "Invalid effort, thinking, thinkingBudget or speedFast value", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "allowed" ], "properties": { "error": { "type": "string" }, "allowed": { "type": "array", "items": { "type": "string" } } } } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "403": { "description": "No provider is permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "delete": { "operationId": "conversation-destroy", "summary": "Delete a conversation and all its messages and files", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Deletion confirmed", "content": { "application/json": { "schema": { "type": "object", "required": [ "deleted" ], "properties": { "deleted": { "type": "boolean", "enum": [ true ] } } } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/conversations/{id}/messages": { "post": { "operationId": "conversation-message", "summary": "Send a message in a conversation and get Claude's response", "description": "Returns the whole turn as one JSON response. The web UI sends turns through the streaming variant (POST /api/conversations/{id}/messages/stream, server-sent events) and falls back to this endpoint when a stream cannot be opened, e.g. behind a reverse proxy that buffers text/event-stream. This endpoint is supported and suits scripts and API clients that want a single response rather than an event stream.", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "prompt": { "type": "string", "default": "", "description": "The user's message" }, "files": { "type": "array", "default": [], "description": "Optional file paths to attach", "items": { "type": "string" } } } } } } }, "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "User message and assistant response", "content": { "application/json": { "schema": { "type": "object", "required": [ "userMessage", "assistantMessage", "conversation" ], "properties": { "userMessage": { "type": "object", "additionalProperties": { "type": "object" } }, "assistantMessage": { "type": "object", "additionalProperties": { "type": "object" } }, "conversation": { "type": "object", "additionalProperties": { "type": "object" } } } } } } }, "400": { "description": "No prompt provided", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "403": { "description": "No provider is permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/conversations/{id}/model": { "put": { "operationId": "conversation-set-model", "summary": "Pin a provider and/or model on an existing conversation", "description": "Passing an empty provider unpins it, so the conversation follows the user's setting again. Changing the provider re-snapshots the model to that provider's default unless one is given explicitly — otherwise the conversation would carry a model id the new provider does not serve.", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "provider": { "type": [ "string", "null" ], "default": null, "description": "Provider to pin ('' unpins, null keeps unchanged)" }, "model": { "type": [ "string", "null" ], "default": null, "description": "Model to pin (null keeps unchanged)" } } } } } }, "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Updated conversation", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "userId", "title", "model", "provider", "createdAt", "updatedAt", "projectId", "effort", "thinking", "thinkingBudget", "speedFast" ], "properties": { "id": { "type": "integer", "format": "int64" }, "userId": { "type": "string" }, "title": { "type": [ "string", "null" ] }, "model": { "type": "string" }, "provider": { "type": [ "string", "null" ] }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" }, "projectId": { "type": [ "integer", "null" ], "format": "int64" }, "effort": { "type": [ "string", "null" ] }, "thinking": { "type": [ "boolean", "null" ] }, "thinkingBudget": { "type": [ "integer", "null" ], "format": "int64" }, "speedFast": { "type": [ "boolean", "null" ] } } } } } }, "400": { "description": "Unknown provider", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "403": { "description": "The provider is not permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/conversations/{id}/thinking": { "get": { "operationId": "conversation-thinking", "summary": "Effective thinking and effort for the next message in a conversation", "description": "Resolves the conversation's overrides, the user's and the instance defaults, and the rules of the model that would answer — some models always think, others cap the effort when thinking is off.", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Effective state. `state` is adaptive, budget, off or none (the provider has no thinking)", "content": { "application/json": { "schema": { "type": "object", "required": [ "model", "mode", "state", "alwaysOn", "effort", "budget", "adjustments" ], "properties": { "model": { "type": "string" }, "mode": { "type": "string" }, "state": { "type": "string" }, "alwaysOn": { "type": "boolean" }, "effort": { "type": [ "string", "null" ] }, "budget": { "type": [ "integer", "null" ], "format": "int64" }, "adjustments": { "type": "array", "items": { "type": "string" } } } } } } }, "403": { "description": "No provider is permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/conversations/{id}/duplicate": { "post": { "operationId": "conversation-duplicate", "summary": "Duplicate a conversation with all its messages and files", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The duplicated conversation", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "userId", "title", "model", "provider", "createdAt", "updatedAt", "projectId", "effort", "thinking", "thinkingBudget", "speedFast" ], "properties": { "id": { "type": "integer", "format": "int64" }, "userId": { "type": "string" }, "title": { "type": [ "string", "null" ] }, "model": { "type": "string" }, "provider": { "type": [ "string", "null" ] }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" }, "projectId": { "type": [ "integer", "null" ], "format": "int64" }, "effort": { "type": [ "string", "null" ] }, "thinking": { "type": [ "boolean", "null" ] }, "thinkingBudget": { "type": [ "integer", "null" ], "format": "int64" }, "speedFast": { "type": [ "boolean", "null" ] } } } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/conversations/search": { "get": { "operationId": "conversation-search", "summary": "Search messages across all conversations", "tags": [ "conversation" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "query", "in": "query", "description": "Search query", "schema": { "type": "string", "default": "" } }, { "name": "limit", "in": "query", "description": "Max results", "schema": { "type": "integer", "format": "int64", "default": 20 } }, { "name": "cursor", "in": "query", "description": "Pagination cursor (message ID)", "schema": { "type": "integer", "format": "int64", "default": 0 } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Matching messages", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "additionalProperties": { "type": "object" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/projects": { "get": { "operationId": "project-index", "summary": "List all projects for the current user", "tags": [ "project" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "List of projects with their paths", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "additionalProperties": { "type": "object" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "post": { "operationId": "project-create", "summary": "Create a new project", "tags": [ "project" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "title" ], "properties": { "title": { "type": "string", "description": "Project title" }, "description": { "type": "string", "default": "", "description": "Project description" }, "systemPrompt": { "type": "string", "default": "", "description": "System prompt for the project" }, "teamId": { "type": [ "string", "null" ], "default": null, "description": "Team that owns the project, which the user must belong to" } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The created project", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "400": { "description": "Title is missing, or a field is too long", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/projects/{id}": { "get": { "operationId": "project-show", "summary": "Get a project with its paths", "tags": [ "project" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Project ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Project with paths", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "put": { "operationId": "project-update", "summary": "Update a project", "description": "Omitted fields stay as they are, so renaming a project does not clear its description or system prompt.", "tags": [ "project" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "type": [ "string", "null" ], "default": null, "description": "New title (null keeps it)" }, "description": { "type": [ "string", "null" ], "default": null, "description": "New description ('' clears, null keeps it)" }, "systemPrompt": { "type": [ "string", "null" ], "default": null, "description": "New system prompt ('' clears, null keeps it)" }, "teamId": { "type": [ "string", "null" ], "default": null, "description": "Team that owns the project ('' makes it personal, null keeps it). Only its creator can change this" } } } } } }, "parameters": [ { "name": "id", "in": "path", "description": "Project ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Updated project", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "400": { "description": "Empty title, a field is too long, or a team the user cannot assign", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "delete": { "operationId": "project-destroy", "summary": "Delete a project and all its paths", "tags": [ "project" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Project ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Deletion confirmed", "content": { "application/json": { "schema": { "type": "object", "required": [ "deleted" ], "properties": { "deleted": { "type": "boolean", "enum": [ true ] } } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/projects/{id}/paths": { "post": { "operationId": "project-add-path", "summary": "Add a path to a project", "tags": [ "project" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "path" ], "properties": { "path": { "type": "string", "description": "File or directory path" }, "pathType": { "type": "string", "default": "file", "description": "Type: 'file' or 'directory'" } } } } } }, "parameters": [ { "name": "id", "in": "path", "description": "Project ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The created path", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "400": { "description": "Invalid path type", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/projects/{id}/paths/{pathId}": { "delete": { "operationId": "project-remove-path", "summary": "Remove a path from a project", "tags": [ "project" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Project ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "pathId", "in": "path", "description": "Path ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Deletion confirmed", "content": { "application/json": { "schema": { "type": "object", "required": [ "deleted" ], "properties": { "deleted": { "type": "boolean", "enum": [ true ] } } } } } }, "404": { "description": "Project or path not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/project-templates": { "get": { "operationId": "project_template-index", "summary": "List the caller's templates and the instance templates", "tags": [ "project_template" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Instance templates first, then the caller's own, each sorted by title", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "required": [ "id", "scope", "title", "description", "systemPrompt", "paths", "createdAt", "updatedAt" ], "properties": { "id": { "type": "integer", "format": "int64" }, "scope": { "type": "string" }, "title": { "type": "string" }, "description": { "type": [ "string", "null" ] }, "systemPrompt": { "type": [ "string", "null" ] }, "paths": { "type": "array", "items": { "type": "object", "required": [ "path", "pathType" ], "properties": { "path": { "type": "string" }, "pathType": { "type": "string", "enum": [ "file", "directory" ] } } } }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" } } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "post": { "operationId": "project_template-create", "summary": "Create a personal template", "description": "With `projectId`, the template starts as a copy of that project (one of the caller's own); the other parameters then override its fields.", "tags": [ "project_template" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "type": [ "string", "null" ], "default": null, "description": "Template title (required without projectId)" }, "description": { "type": [ "string", "null" ], "default": null, "description": "Description" }, "systemPrompt": { "type": [ "string", "null" ], "default": null, "description": "System prompt copied into new projects" }, "paths": { "type": [ "array", "null" ], "default": null, "description": "Path suggestions copied into new projects", "items": { "type": "object", "required": [ "path" ], "properties": { "path": { "type": "string" }, "pathType": { "type": "string" } } } }, "projectId": { "type": [ "integer", "null" ], "format": "int64", "default": null, "description": "Save this project as a template" } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The created template", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "scope", "title", "description", "systemPrompt", "paths", "createdAt", "updatedAt" ], "properties": { "id": { "type": "integer", "format": "int64" }, "scope": { "type": "string" }, "title": { "type": "string" }, "description": { "type": [ "string", "null" ] }, "systemPrompt": { "type": [ "string", "null" ] }, "paths": { "type": "array", "items": { "type": "object", "required": [ "path", "pathType" ], "properties": { "path": { "type": "string" }, "pathType": { "type": "string", "enum": [ "file", "directory" ] } } } }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" } } } } } }, "400": { "description": "Missing title, or a field is too long", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/project-templates/{id}": { "put": { "operationId": "project_template-update", "summary": "Update a personal template", "description": "Omitted fields stay as they are.", "tags": [ "project_template" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "type": [ "string", "null" ], "default": null, "description": "New title (null keeps it)" }, "description": { "type": [ "string", "null" ], "default": null, "description": "New description ('' clears, null keeps it)" }, "systemPrompt": { "type": [ "string", "null" ], "default": null, "description": "New system prompt ('' clears, null keeps it)" }, "paths": { "type": [ "array", "null" ], "default": null, "description": "New path suggestions (null keeps them)", "items": { "type": "object", "required": [ "path" ], "properties": { "path": { "type": "string" }, "pathType": { "type": "string" } } } } } } } } }, "parameters": [ { "name": "id", "in": "path", "description": "Template ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The updated template", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "scope", "title", "description", "systemPrompt", "paths", "createdAt", "updatedAt" ], "properties": { "id": { "type": "integer", "format": "int64" }, "scope": { "type": "string" }, "title": { "type": "string" }, "description": { "type": [ "string", "null" ] }, "systemPrompt": { "type": [ "string", "null" ] }, "paths": { "type": "array", "items": { "type": "object", "required": [ "path", "pathType" ], "properties": { "path": { "type": "string" }, "pathType": { "type": "string", "enum": [ "file", "directory" ] } } } }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" } } } } } }, "400": { "description": "Empty title, or a field is too long", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Template not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "delete": { "operationId": "project_template-destroy", "summary": "Delete a personal template", "description": "Projects already made from it are not touched.", "tags": [ "project_template" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Template ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Deleted", "content": { "application/json": { "schema": { "type": "object", "required": [ "deleted" ], "properties": { "deleted": { "type": "boolean", "enum": [ true ] } } } } } }, "404": { "description": "Template not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/project-templates/{id}/project": { "post": { "operationId": "project_template-create-project", "summary": "Create a project from a template", "description": "Copies the template's title, description, system prompt and paths into a new project owned by the caller. Works for the caller's own templates and for instance templates.", "tags": [ "project_template" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "type": [ "string", "null" ], "default": null, "description": "Title for the new project (default: the template's)" } } } } } }, "parameters": [ { "name": "id", "in": "path", "description": "Template ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The created project with its paths", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "400": { "description": "A field is too long", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Template not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/prompts": { "get": { "operationId": "prompt-index", "summary": "List the caller's prompts and the instance prompts", "tags": [ "prompt" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Instance prompts first, then the caller's own, each sorted by title", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "required": [ "id", "scope", "title", "description", "content", "createdAt", "updatedAt" ], "properties": { "id": { "type": "integer", "format": "int64" }, "scope": { "type": "string" }, "title": { "type": "string" }, "description": { "type": [ "string", "null" ] }, "content": { "type": "string" }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" } } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "post": { "operationId": "prompt-create", "summary": "Create a personal prompt", "tags": [ "prompt" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "title", "content" ], "properties": { "title": { "type": "string", "description": "Title shown in the picker" }, "content": { "type": "string", "description": "Prompt text" }, "description": { "type": [ "string", "null" ], "default": null, "description": "Optional description" } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The created prompt", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "scope", "title", "description", "content", "createdAt", "updatedAt" ], "properties": { "id": { "type": "integer", "format": "int64" }, "scope": { "type": "string" }, "title": { "type": "string" }, "description": { "type": [ "string", "null" ] }, "content": { "type": "string" }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" } } } } } }, "400": { "description": "Missing title or content, or a field is too long", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/prompts/{id}": { "put": { "operationId": "prompt-update", "summary": "Update a personal prompt", "description": "Omitted fields stay as they are.", "tags": [ "prompt" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "type": [ "string", "null" ], "default": null, "description": "New title (null keeps it)" }, "content": { "type": [ "string", "null" ], "default": null, "description": "New text (null keeps it)" }, "description": { "type": [ "string", "null" ], "default": null, "description": "New description ('' clears, null keeps it)" } } } } } }, "parameters": [ { "name": "id", "in": "path", "description": "Prompt ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "The updated prompt", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "scope", "title", "description", "content", "createdAt", "updatedAt" ], "properties": { "id": { "type": "integer", "format": "int64" }, "scope": { "type": "string" }, "title": { "type": "string" }, "description": { "type": [ "string", "null" ] }, "content": { "type": "string" }, "createdAt": { "type": "integer", "format": "int64" }, "updatedAt": { "type": "integer", "format": "int64" } } } } } }, "400": { "description": "A field is empty or too long", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Prompt not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "delete": { "operationId": "prompt-destroy", "summary": "Delete a personal prompt", "tags": [ "prompt" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Prompt ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Deleted", "content": { "application/json": { "schema": { "type": "object", "required": [ "deleted" ], "properties": { "deleted": { "type": "boolean", "enum": [ true ] } } } } } }, "404": { "description": "Prompt not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/ask": { "post": { "operationId": "chat-ask", "summary": "Send a single-turn prompt to Claude, optionally with attached files", "tags": [ "chat" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "prompt": { "type": "string", "default": "", "description": "The user's question or instruction" }, "context": { "type": "string", "default": "", "description": "Optional context to provide alongside the prompt" }, "files": { "type": "array", "default": [], "description": "Optional list of Nextcloud file paths to include as context", "items": { "type": "string" } } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Claude response with model info and token usage", "content": { "application/json": { "schema": { "type": "object", "required": [ "response", "model", "usage" ], "properties": { "response": { "type": "string" }, "model": { "type": "string" }, "usage": { "type": "object", "required": [ "input_tokens", "output_tokens" ], "properties": { "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" } } } } } } } }, "403": { "description": "No provider is permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "400": { "description": "No prompt was provided", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "One of the attached files was not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "413": { "description": "Prompt or context exceeds the 5 MB content limit", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "429": { "description": "Rate limit exceeded (10 requests per minute)", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "An attached file could not be read", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/chat": { "post": { "operationId": "chat-chat", "summary": "Send a multi-turn conversation to Claude", "tags": [ "chat" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "messages": { "type": "array", "default": [], "description": "Conversation messages", "items": { "type": "object", "required": [ "role", "content" ], "properties": { "role": { "type": "string" }, "content": { "type": "string" } } } }, "system": { "type": [ "string", "null" ], "default": null, "description": "Optional system prompt" }, "options": { "type": "object", "default": {}, "description": "Optional model parameters (stop_sequences; temperature, top_p and top_k reach only the OpenAI-compatible providers)", "additionalProperties": { "type": "object" } } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Claude response with model info and token usage", "content": { "application/json": { "schema": { "type": "object", "required": [ "response", "model", "usage" ], "properties": { "response": { "type": "string" }, "model": { "type": "string" }, "usage": { "type": "object", "required": [ "input_tokens", "output_tokens" ], "properties": { "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" } } } } } } } }, "403": { "description": "No provider is permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "400": { "description": "Messages array is missing or empty", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "413": { "description": "Combined message content exceeds the 5 MB content limit", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "429": { "description": "Rate limit exceeded (10 requests per minute)", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/summarize": { "post": { "operationId": "chat-summarize", "summary": "Summarize text content with Claude", "tags": [ "chat" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "content": { "type": "string", "default": "", "description": "The text content to summarize" } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Claude summary with model info and token usage", "content": { "application/json": { "schema": { "type": "object", "required": [ "response", "model", "usage" ], "properties": { "response": { "type": "string" }, "model": { "type": "string" }, "usage": { "type": "object", "required": [ "input_tokens", "output_tokens" ], "properties": { "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" } } } } } } } }, "403": { "description": "No provider is permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "400": { "description": "No content was provided", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "413": { "description": "Content exceeds the 5 MB content limit", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "429": { "description": "Rate limit exceeded (10 requests per minute)", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/analyze-file": { "post": { "operationId": "chat-analyze-file", "summary": "Analyze a Nextcloud file with Claude (vision for images, document for PDFs, text for others)", "tags": [ "chat" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "filePath": { "type": "string", "default": "", "description": "Path to the file within the user's Nextcloud storage" }, "prompt": { "type": "string", "default": "Analyze and describe this file.", "description": "Instruction or question about the file" } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Claude analysis with model info and token usage", "content": { "application/json": { "schema": { "type": "object", "required": [ "response", "model", "usage" ], "properties": { "response": { "type": "string" }, "model": { "type": "string" }, "usage": { "type": "object", "required": [ "input_tokens", "output_tokens" ], "properties": { "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" } } } } } } } }, "403": { "description": "No provider is permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "400": { "description": "No filePath provided or prompt is invalid", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "File not found at the given path", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "413": { "description": "Prompt exceeds the 5 MB content limit", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "429": { "description": "Rate limit exceeded (10 requests per minute)", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/settings": { "post": { "operationId": "settings-save", "summary": "Save user-level API key", "tags": [ "settings" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "api_key": { "type": "string", "default": null, "description": "Personal API key for the scoped provider (leave empty to clear)" }, "model": { "type": [ "string", "null" ], "default": null, "description": "Preferred model ID for the scoped provider ('' clears the override, null keeps it unchanged)" }, "provider": { "type": [ "string", "null" ], "default": null, "description": "Active provider override ('' clears, e.g. 'anthropic'/'mistral', null keeps unchanged). Also scopes api_key/model in this call." }, "default_system_prompt": { "type": [ "string", "null" ], "default": null, "description": "Default instructions added to every chat after the instance instructions ('' clears, null keeps unchanged)" }, "default_verbose": { "type": [ "string", "null" ], "default": null, "description": "Enable verbose mode by default ('1' or null to keep unchanged)" }, "task_success_notifications": { "type": [ "string", "null" ], "default": null, "description": "Notify when an AI task completes ('1'/'0', null to keep unchanged)" }, "task_failure_notifications": { "type": [ "string", "null" ], "default": null, "description": "Notify when an AI task fails ('1'/'0', null to keep unchanged)" }, "native_mcp_enabled": { "type": [ "string", "null" ], "default": null, "description": "User override for native-MCP ('1' opt in, '0' opt out, '' clears override, null keeps unchanged)" } } } } } }, "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Settings saved successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "status" ], "properties": { "status": { "type": "string" } } } } } }, "400": { "description": "Unknown provider, or the default instructions are too long", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "403": { "description": "The provider is not permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "get": { "operationId": "settings-get", "summary": "Get current user settings and available Claude models", "tags": [ "settings" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "403": { "description": "No provider is permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "200": { "description": "User settings and available models", "content": { "application/json": { "schema": { "type": "object", "required": [ "provider", "userProvider", "providers", "hasUserKey", "userModel", "availableModels", "defaultSystemPrompt", "instanceInstructions", "maxPromptLength", "defaultVerbose", "taskSuccessNotifications", "taskFailureNotifications", "nativeMcpUserOverride", "nativeMcpAdminDefault", "nativeMcpEffective" ], "properties": { "provider": { "type": "string" }, "userProvider": { "type": "string" }, "providers": { "type": "array", "items": { "type": "object", "required": [ "id", "label", "configured", "hasUserKey", "userModel", "availableModels" ], "properties": { "id": { "type": "string" }, "label": { "type": "string" }, "configured": { "type": "boolean" }, "hasUserKey": { "type": "boolean" }, "userModel": { "type": "string" }, "availableModels": { "type": "array", "items": { "type": "string" } } } } }, "hasUserKey": { "type": "boolean" }, "userModel": { "type": "string" }, "availableModels": { "type": "array", "items": { "type": "string" } }, "defaultSystemPrompt": { "type": "string" }, "instanceInstructions": { "type": "string" }, "maxPromptLength": { "type": "integer", "format": "int64" }, "defaultVerbose": { "type": "boolean" }, "taskSuccessNotifications": { "type": "boolean" }, "taskFailureNotifications": { "type": "boolean" }, "nativeMcpUserOverride": { "type": "string" }, "nativeMcpAdminDefault": { "type": "boolean" }, "nativeMcpEffective": { "type": "boolean" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/providers": { "get": { "operationId": "provider_settings-index", "summary": "List providers with their user-writable settings", "description": "Returns one entry per registered provider: label, capability flags, model list, and the user-scope fields with their current values. API keys are reported as `hasValue` booleans only — the key itself never leaves the credential manager.", "tags": [ "provider_settings" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "refresh", "in": "query", "description": "'1' to bypass the cached model lists and re-query every provider", "schema": { "type": [ "string", "null" ], "default": null } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Provider settings for the current user", "content": { "application/json": { "schema": { "type": "object", "required": [ "defaultProvider", "userProvider", "adminProvider", "providers" ], "properties": { "defaultProvider": { "type": "string" }, "userProvider": { "type": "string" }, "adminProvider": { "type": "string" }, "providers": { "type": "array", "items": { "type": "object", "additionalProperties": { "type": "object" } } } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/providers/{providerId}": { "post": { "operationId": "provider_settings-update", "summary": "Save user-scope settings for one provider", "description": "Field values are `{fieldId: value}` pairs matching the schema returned by the index endpoint. An empty value clears the user override so the instance default applies again. Fields that are not user-writable are reported back in `rejected` and left untouched.", "tags": [ "provider_settings" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "values": { "type": "object", "default": {}, "description": "Field id => value pairs", "additionalProperties": { "type": "object" } }, "makeDefault": { "type": [ "string", "null" ], "default": null, "description": "'1' to also make this the user's default provider" } } } } } }, "parameters": [ { "name": "providerId", "in": "path", "description": "Provider to configure", "required": true, "schema": { "type": "string" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Settings saved", "content": { "application/json": { "schema": { "type": "object", "required": [ "status", "rejected" ], "properties": { "status": { "type": "string" }, "rejected": { "type": "array", "items": { "type": "string" } } } } } } }, "400": { "description": "Unknown provider or invalid value", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "403": { "description": "The provider is not permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/providers/{providerId}/status": { "get": { "operationId": "provider_settings-status", "summary": "Report whether a provider is reachable and serving the configured model", "description": "Backs the status light on the personal settings page: the light describes what *this user* gets, so the probe runs against their own key when they have one and the inherited instance key otherwise.", "tags": [ "provider_settings" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "providerId", "in": "path", "description": "Provider to check", "required": true, "schema": { "type": "string" } }, { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", "required": true, "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Current provider health", "content": { "application/json": { "schema": { "type": "object", "required": [ "providerId", "state", "reason", "message", "model" ], "properties": { "providerId": { "type": "string" }, "state": { "type": "string" }, "reason": { "type": "string" }, "message": { "type": "string" }, "model": { "type": "string" } } } } } }, "400": { "description": "Unknown provider", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "403": { "description": "The provider is not permitted for this user", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/oauth/mcp-client": { "get": { "operationId": "mcp_server-client-metadata", "summary": "Client ID Metadata Document of this instance's MCP client", "description": "Its URL is the client_id AIquila presents to authorization servers that support Client ID Metadata Documents; they fetch it to learn the client's name and redirect URI.", "tags": [ "mcp_server" ], "security": [ {}, { "bearer_auth": [] }, { "basic_auth": [] } ], "responses": { "200": { "description": "Client metadata (draft-ietf-oauth-client-id-metadata-document)", "content": { "application/json": { "schema": { "type": "object", "required": [ "client_id", "client_name", "client_uri", "redirect_uris", "grant_types", "response_types", "token_endpoint_auth_method", "token_endpoint_auth_methods_supported" ], "properties": { "client_id": { "type": "string" }, "client_name": { "type": "string" }, "client_uri": { "type": "string" }, "redirect_uris": { "type": "array", "items": { "type": "string" } }, "grant_types": { "type": "array", "items": { "type": "string" } }, "response_types": { "type": "array", "items": { "type": "string" } }, "token_endpoint_auth_method": { "type": "string" }, "token_endpoint_auth_methods_supported": { "type": "array", "items": { "type": "string" } } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers": { "get": { "operationId": "coworker-index", "summary": "List all coworkers for the current user", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "responses": { "200": { "description": "List of coworkers", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "additionalProperties": { "type": "object" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "post": { "operationId": "coworker-create", "summary": "Create a new coworker", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "responses": { "200": { "description": "The created coworker", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "400": { "description": "Invalid coworker configuration", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/templates": { "get": { "operationId": "coworker-templates", "summary": "List coworker templates and available task types", "description": "Built-in templates first (`scope: builtin`), then the ones an admin published for the instance (`scope: instance`).", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "responses": { "200": { "description": "Templates and task types", "content": { "application/json": { "schema": { "type": "object", "required": [ "templates", "taskTypes" ], "properties": { "templates": { "type": "array", "items": { "type": "object", "additionalProperties": { "type": "object" } } }, "taskTypes": { "type": "array", "items": { "type": "object", "required": [ "id", "label", "family" ], "properties": { "id": { "type": "string" }, "label": { "type": "string" }, "family": { "type": "string" } } } } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "post": { "operationId": "coworker-create-from-template", "summary": "Create a coworker from a built-in or instance template", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "templateId": { "type": "string", "default": "", "description": "Template identifier" } } } } } }, "responses": { "200": { "description": "The created coworker", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "400": { "description": "Invalid coworker configuration", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Unknown template", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/tools": { "get": { "operationId": "coworker-tools", "summary": "List the MCP tools an agent coworker may be allowed to call", "description": "The tools of the instance's enabled MCP servers, which the chat offers every user too. Only names and descriptions; a server that cannot be reached is left out.", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "responses": { "200": { "description": "Tools, by name", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "required": [ "name", "description" ], "properties": { "name": { "type": "string" }, "description": { "type": "string" } } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/trigger-policy": { "get": { "operationId": "coworker-trigger-policy", "summary": "Whether the current user may use coworker triggers", "description": "Triggers start a coworker when files in its input folder change, or when its trigger URL is called. An administrator turns them on and chooses who may use them.", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "responses": { "200": { "description": "The policy for the current user", "content": { "application/json": { "schema": { "type": "object", "required": [ "allowed", "debounceSeconds", "maxRunsPerHour" ], "properties": { "allowed": { "type": "boolean" }, "debounceSeconds": { "type": "integer", "format": "int64" }, "maxRunsPerHour": { "type": "integer", "format": "int64" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}": { "get": { "operationId": "coworker-show", "summary": "Get a single coworker", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The coworker", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "put": { "operationId": "coworker-update", "summary": "Update a coworker", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The updated coworker", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "400": { "description": "Invalid coworker configuration", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "delete": { "operationId": "coworker-destroy", "summary": "Delete a coworker and its run history", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Coworker deleted", "content": { "application/json": { "schema": { "type": "object", "required": [ "deleted" ], "properties": { "deleted": { "type": "boolean" } } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/pause": { "post": { "operationId": "coworker-pause", "summary": "Pause a coworker", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The updated coworker", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/resume": { "post": { "operationId": "coworker-resume", "summary": "Resume a paused coworker", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The updated coworker", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/enable": { "post": { "operationId": "coworker-enable", "summary": "Enable a coworker", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The updated coworker", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/disable": { "post": { "operationId": "coworker-disable", "summary": "Disable a coworker", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The updated coworker", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/run": { "post": { "operationId": "coworker-run", "summary": "Run a coworker now", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The completed run", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/runs": { "get": { "operationId": "coworker-runs", "summary": "Get the run history for a coworker", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Maximum number of runs to return", "schema": { "type": "integer", "format": "int64", "default": 20 } } ], "responses": { "200": { "description": "List of runs, newest first", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "additionalProperties": { "type": "object" } } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/runs/{runId}": { "get": { "operationId": "coworker-run-detail", "summary": "Get one run of a coworker, with its per-item log", "description": "The run list's shape plus `log`: entries oldest first, at most the newest 500. `item` is the file or object an entry is about, as a path in the user's Files, or null.", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "runId", "in": "path", "description": "Run ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The run with its log", "content": { "application/json": { "schema": { "type": "object", "required": [ "id", "coworkerId", "userId", "status", "itemsTotal", "itemsProcessed", "summary", "error", "startedAt", "finishedAt", "pendingBatchId", "log" ], "properties": { "id": { "type": "integer", "format": "int64" }, "coworkerId": { "type": "integer", "format": "int64" }, "userId": { "type": "string" }, "status": { "type": "string" }, "itemsTotal": { "type": "integer", "format": "int64" }, "itemsProcessed": { "type": "integer", "format": "int64" }, "summary": { "type": [ "string", "null" ] }, "error": { "type": [ "string", "null" ] }, "startedAt": { "type": "integer", "format": "int64" }, "finishedAt": { "type": [ "integer", "null" ], "format": "int64" }, "pendingBatchId": { "type": [ "string", "null" ] }, "log": { "type": "array", "items": { "type": "object", "required": [ "ts", "level", "message", "item" ], "properties": { "ts": { "type": "integer", "format": "int64" }, "level": { "type": "string" }, "message": { "type": "string" }, "item": { "type": [ "string", "null" ] } } } } } } } } }, "404": { "description": "Coworker or run not found, or the run belongs to another coworker", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/stop": { "post": { "operationId": "coworker-stop", "summary": "Stop a coworker's run in flight", "description": "Cancels the run that is `running` or `pending` (a submitted batch). The run is closed as `cancelled` and keeps what it processed so far; a running one stops at its next item. The schedule is unchanged: pause or disable the coworker to stop future runs.", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The cancelled run", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Coworker not found, or it has no run in flight", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/trigger-url": { "post": { "operationId": "coworker-create-trigger-url", "summary": "Create a trigger URL for a coworker", "description": "Returns the URL and its secret. The secret is shown this once; only a hash of it is stored. Calling this again replaces the secret, so the old one stops working. Call the URL with `POST` and the secret as a bearer token: `Authorization: Bearer `.", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The trigger URL and its secret", "content": { "application/json": { "schema": { "type": "object", "required": [ "url", "token" ], "properties": { "url": { "type": "string" }, "token": { "type": "string" } } } } } }, "403": { "description": "Coworker triggers are not allowed for this account", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "delete": { "operationId": "coworker-delete-trigger-url", "summary": "Remove a coworker's trigger URL", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "The coworker, now without a trigger URL", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "object" } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/coworkers/{id}/trigger": { "post": { "operationId": "coworker_trigger-trigger", "summary": "Start a coworker through its trigger URL", "description": "Authenticate with `Authorization: Bearer `, the secret shown when the trigger URL was created. The run starts within a minute, as a background job; the response does not wait for it.", "tags": [ "coworker_trigger" ], "security": [ {}, { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "id", "in": "path", "description": "Coworker ID", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "authorization", "in": "header", "schema": { "type": "string" } } ], "responses": { "202": { "description": "A run is due", "content": { "application/json": { "schema": { "type": "object", "required": [ "coworkerId", "dueAt" ], "properties": { "coworkerId": { "type": "integer", "format": "int64" }, "dueAt": { "type": "integer", "format": "int64" } } } } } }, "401": { "description": "Missing or wrong secret", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "409": { "description": "The coworker cannot run now: it is paused or disabled, or triggers are not allowed for its account", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "429": { "description": "Too many triggered runs in the last hour", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/dashboard/coworker-output": { "get": { "operationId": "coworker-get-dashboard-coworker", "summary": "Get the coworker selected for the dashboard output widget", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "responses": { "200": { "description": "The selected coworker id (null when none chosen)", "content": { "application/json": { "schema": { "type": "object", "required": [ "coworkerId" ], "properties": { "coworkerId": { "type": [ "integer", "null" ], "format": "int64" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } }, "put": { "operationId": "coworker-set-dashboard-coworker", "summary": "Set the coworker shown by the dashboard output widget", "tags": [ "coworker" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "coworkerId": { "type": [ "integer", "null" ], "format": "int64", "default": null, "description": "Coworker to display, or null to clear" } } } } } }, "responses": { "200": { "description": "The stored selection", "content": { "application/json": { "schema": { "type": "object", "required": [ "coworkerId" ], "properties": { "coworkerId": { "type": [ "integer", "null" ], "format": "int64" } } } } } }, "404": { "description": "Coworker not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/files/info": { "get": { "operationId": "file-info", "summary": "Get metadata for a file or directory", "tags": [ "file" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "path", "in": "query", "description": "Path within the user's Nextcloud storage", "schema": { "type": "string", "default": "" } } ], "responses": { "200": { "description": "File or directory metadata", "content": { "application/json": { "schema": { "type": "object", "required": [ "name", "path", "size", "mimeType", "mtime", "etag", "permissions" ], "properties": { "name": { "type": "string" }, "path": { "type": "string" }, "size": { "type": "integer", "format": "int64" }, "mimeType": { "type": "string" }, "mtime": { "type": "integer", "format": "int64" }, "etag": { "type": "string" }, "permissions": { "type": "integer", "format": "int64" } } } } } }, "400": { "description": "No path provided", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "File or directory not found at the given path", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "Reading the file metadata failed", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/files/list": { "get": { "operationId": "file-list-dir", "summary": "List files and directories at the given path", "tags": [ "file" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "path", "in": "query", "description": "Directory path within the user's Nextcloud storage (default: root)", "schema": { "type": "string", "default": "/" } } ], "responses": { "200": { "description": "Directory listing", "content": { "application/json": { "schema": { "type": "object", "required": [ "files" ], "properties": { "files": { "type": "array", "items": { "type": "object", "required": [ "name", "path", "size", "mimeType", "mtime", "type" ], "properties": { "name": { "type": "string" }, "path": { "type": "string" }, "size": { "type": "integer", "format": "int64" }, "mimeType": { "type": "string" }, "mtime": { "type": "integer", "format": "int64" }, "type": { "type": "string" } } } } } } } } }, "400": { "description": "Path is not a directory or is otherwise invalid", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Directory not found at the given path", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "Reading the directory failed", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/files/content": { "get": { "operationId": "file-content", "summary": "Get the content of a file (base64-encoded for binary files)", "tags": [ "file" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "path", "in": "query", "description": "Path to the file within the user's Nextcloud storage", "schema": { "type": "string", "default": "" } } ], "responses": { "200": { "description": "File content with encoding and MIME type", "content": { "application/json": { "schema": { "type": "object", "required": [ "content", "mimeType", "name", "size", "encoding" ], "properties": { "content": { "type": "string" }, "mimeType": { "type": "string" }, "name": { "type": "string" }, "size": { "type": "integer", "format": "int64" }, "encoding": { "type": "string" } } } } } }, "400": { "description": "No path provided or path refers to a directory", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "File not found at the given path", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "413": { "description": "File exceeds the size limit", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "Reading the file failed", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/files/search": { "get": { "operationId": "file-search", "summary": "Search for files by name within the user's Nextcloud storage", "tags": [ "file" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "query", "in": "query", "description": "Search term", "schema": { "type": "string", "default": "" } }, { "name": "mime", "in": "query", "description": "Optional MIME type filter", "schema": { "type": [ "string", "null" ], "default": null } }, { "name": "path", "in": "query", "description": "Base directory to search within (default: root)", "schema": { "type": "string", "default": "/" } } ], "responses": { "200": { "description": "Search results", "content": { "application/json": { "schema": { "type": "object", "required": [ "results" ], "properties": { "results": { "type": "array", "items": { "type": "object", "required": [ "name", "path", "mimeType", "size" ], "properties": { "name": { "type": "string" }, "path": { "type": "string" }, "mimeType": { "type": "string" }, "size": { "type": "integer", "format": "int64" } } } } } } } } }, "400": { "description": "No search query provided or query is invalid", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Base path not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "The search failed", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/files/preview": { "get": { "operationId": "file-preview", "summary": "Get a base64-encoded preview image for a file", "tags": [ "file" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "path", "in": "query", "description": "Path to the file within the user's Nextcloud storage", "schema": { "type": "string", "default": "" } }, { "name": "width", "in": "query", "description": "Preview width in pixels (16-1024, default: 256)", "schema": { "type": "integer", "format": "int64", "default": 256 } }, { "name": "height", "in": "query", "description": "Preview height in pixels (16-1024, default: 256)", "schema": { "type": "integer", "format": "int64", "default": 256 } } ], "responses": { "200": { "description": "Base64-encoded preview image with MIME type", "content": { "application/json": { "schema": { "type": "object", "required": [ "preview", "mimeType" ], "properties": { "preview": { "type": "string" }, "mimeType": { "type": "string" } } } } } }, "400": { "description": "No path provided or preview cannot be generated", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "File not found at the given path", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "Generating the preview failed", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/files/zip": { "post": { "operationId": "file-compress", "summary": "Create a zip archive from one or more files/folders", "tags": [ "file" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "sources": { "type": "array", "default": [], "description": "Paths to include in the archive", "items": { "type": "string" } }, "destination": { "type": "string", "default": "", "description": "Path for the resulting .zip file" }, "overwrite": { "type": "boolean", "default": false, "description": "Whether to overwrite an existing destination" } } } } } }, "responses": { "200": { "description": "Archive created", "content": { "application/json": { "schema": { "type": "object", "required": [ "archive", "entries", "size" ], "properties": { "archive": { "type": "string" }, "entries": { "type": "integer", "format": "int64" }, "size": { "type": "integer", "format": "int64" } } } } } }, "400": { "description": "No sources provided or a path is invalid", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "A source path was not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "409": { "description": "Destination already exists and overwrite was not requested", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "413": { "description": "Archive exceeds the maximum size", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "Creating the archive failed", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/files/unzip": { "post": { "operationId": "file-extract", "summary": "Extract a zip archive into a destination folder", "tags": [ "file" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "archive": { "type": "string", "default": "", "description": "Path to the .zip file" }, "destination": { "type": "string", "default": "", "description": "Folder to extract into" }, "overwrite": { "type": "boolean", "default": false, "description": "Whether to overwrite existing entries" } } } } } }, "responses": { "200": { "description": "Archive extracted", "content": { "application/json": { "schema": { "type": "object", "required": [ "destination", "extracted" ], "properties": { "destination": { "type": "string" }, "extracted": { "type": "integer", "format": "int64" } } } } } }, "400": { "description": "Invalid path or unsafe archive entry", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Archive not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "409": { "description": "An entry already exists and overwrite was not requested", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "413": { "description": "Archive exceeds the maximum size", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "Extracting the archive failed", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } }, "/index.php/apps/aiquila/api/files/zip/list": { "get": { "operationId": "file-list-archive", "summary": "List the contents of a zip archive without extracting", "tags": [ "file" ], "security": [ { "bearer_auth": [] }, { "basic_auth": [] } ], "parameters": [ { "name": "archive", "in": "query", "description": "Path to the .zip file", "schema": { "type": "string", "default": "" } } ], "responses": { "200": { "description": "Archive entries", "content": { "application/json": { "schema": { "type": "object", "required": [ "archive", "count", "entries" ], "properties": { "archive": { "type": "string" }, "count": { "type": "integer", "format": "int64" }, "entries": { "type": "array", "items": { "type": "object", "required": [ "name", "size", "compressedSize", "isDirectory" ], "properties": { "name": { "type": "string" }, "size": { "type": "integer", "format": "int64" }, "compressedSize": { "type": "integer", "format": "int64" }, "isDirectory": { "type": "boolean" } } } } } } } } }, "400": { "description": "No path provided or path is not a file", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "404": { "description": "Archive not found", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "500": { "description": "Reading the archive failed", "content": { "application/json": { "schema": { "type": "object", "required": [ "error", "errorId" ], "properties": { "error": { "type": "string" }, "errorId": { "type": "string" } } } } } }, "401": { "description": "Current user is not logged in", "content": { "application/json": { "schema": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string" } } } } } } } } } }, "tags": [ { "name": "page", "description": "Page Controller for AIquila main interface" }, { "name": "stream_probe", "description": "A miniature Server-Sent Events endpoint whose only job is to be measured. The chat stream cannot double as a diagnostic: it needs a configured provider, a conversation and an LLM round trip, and it bills the account. This one emits a few empty ticks a fixed interval apart, so the StreamingNotBuffered setup check can tell whether something between PHP and the client is holding the response back — the failure that turns streaming chat into a long wait followed by the whole reply at once. It is a public page because the setup check requests it over the loopback without a session. It reveals nothing: the payload is a tick index and a server timestamp." }, { "name": "project_template", "description": "Project templates: the title, description, system prompt and path suggestions a new project is copied from. A project made from a template is a copy. Editing or deleting the template later leaves it alone. `/api/project-templates` holds the caller's own templates and lists the instance ones; `/api/admin/project-templates` is where admins publish instance templates." }, { "name": "prompt", "description": "The prompt library: reusable snippets a user inserts into a message or a project's system prompt. `/api/prompts` manages the caller's own prompts and lists the instance ones read-only. `/api/admin/prompts` is the admin side, for instance prompts only; the framework refuses those routes to non-admins." }, { "name": "instructions", "description": "Instance instructions: admin text placed in front of the system prompt for every user, on the surfaces the admin enables. Admin-only; the framework refuses both routes to other users." }, { "name": "provider_settings", "description": "Schema-driven read/write of provider configuration for the settings pages. Both the admin and the personal page render whatever LLMProviderInterface::getSettingsSchema() describes, so this controller never names a provider or a config key — adding a provider requires no change here. The admin/user split is enforced twice over: the admin routes carry no #[NoAdminRequired] (so Nextcloud requires an admin), and ProviderSettingsService::writeUser() additionally drops any field whose scope is not user-writable. That second check is what keeps endpoint URLs — which decide where the server sends outbound requests — out of reach of the personal page even if a route were ever mis-annotated. Provider *access* is enforced on top of that: index() only describes providers the current user is permitted to use, and update() refuses one they are not, so the personal page can neither see nor select a provider an admin blocked." }, { "name": "coworker", "description": "REST API for cowork tasks — persistent scheduled AI jobs. Consumed by the Cowork UI and by the MCP server (Basic Auth), hence NoCSRFRequired alongside NoAdminRequired." }, { "name": "coworker_trigger", "description": "The trigger URL of a coworker, for other systems: an orchestrator, a Webhook listeners webhook, a CI job. The caller has no Nextcloud session. It proves itself with the coworker's trigger secret as a bearer token (RFC 6750 §2.1, the header form only: a secret in the query string would end up in access logs). An unknown coworker and a wrong secret get the same 401, so the endpoint does not tell which coworker IDs exist, and both count as a brute-force attempt. The request body is not read. A trigger only says \"run now\"; what the run works on is the coworker's own input folder, so a caller cannot put text in front of the model or point the coworker at other files." } ] }