|
|
@@ -1 +1,810 @@
|
|
|
-{ "openapi": "3.1.0", "info": { "title": "smartbotic-vectorapi", "version": "0.1.0" }, "paths": {} }
|
|
|
+{
|
|
|
+ "openapi": "3.1.0",
|
|
|
+ "info": {
|
|
|
+ "title": "smartbotic-vectorapi",
|
|
|
+ "version": "0.1.0",
|
|
|
+ "description": "General-purpose REST API fronting smartbotic-database. Supports multi-project namespacing and multi-key authorization with per-project grants."
|
|
|
+ },
|
|
|
+ "components": {
|
|
|
+ "securitySchemes": {
|
|
|
+ "bearerAuth": {
|
|
|
+ "type": "http",
|
|
|
+ "scheme": "bearer",
|
|
|
+ "description": "API key issued by the /api/v1/keys endpoint. Pass as Authorization: Bearer <KEY>."
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "schemas": {
|
|
|
+ "Error": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "error": { "type": "string" },
|
|
|
+ "message": { "type": "string" }
|
|
|
+ },
|
|
|
+ "required": ["error", "message"]
|
|
|
+ },
|
|
|
+ "CollectionMeta": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "name": { "type": "string" },
|
|
|
+ "kind": { "type": "string", "enum": ["json", "vector"] },
|
|
|
+ "vector_dimension": { "type": "integer", "minimum": 1 },
|
|
|
+ "embedding_model": { "type": "string" },
|
|
|
+ "created_at": { "type": "integer" }
|
|
|
+ },
|
|
|
+ "required": ["name", "kind"]
|
|
|
+ },
|
|
|
+ "ApiKeyPublic": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "key_prefix": { "type": "string" },
|
|
|
+ "label": { "type": "string" },
|
|
|
+ "projects": { "type": "array", "items": { "type": "string" } },
|
|
|
+ "admin": { "type": "boolean" },
|
|
|
+ "created_at": { "type": "integer" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "security": [{ "bearerAuth": [] }],
|
|
|
+ "paths": {
|
|
|
+ "/healthz": {
|
|
|
+ "get": {
|
|
|
+ "summary": "Liveness check — always 200 if the process is running",
|
|
|
+ "operationId": "healthz",
|
|
|
+ "security": [],
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "OK" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/readyz": {
|
|
|
+ "get": {
|
|
|
+ "summary": "Readiness check — 200 when the database is reachable",
|
|
|
+ "operationId": "readyz",
|
|
|
+ "security": [],
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "Ready" },
|
|
|
+ "503": { "description": "Database not reachable" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects": {
|
|
|
+ "get": {
|
|
|
+ "summary": "List projects the key may access (admin sees all)",
|
|
|
+ "operationId": "listProjects",
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Project list",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "projects": { "type": "array", "items": { "type": "string" } }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "post": {
|
|
|
+ "summary": "Create a new project (admin only)",
|
|
|
+ "operationId": "createProject",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "name": { "type": "string" }
|
|
|
+ },
|
|
|
+ "required": ["name"]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "201": { "description": "Project created" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden — admin required" },
|
|
|
+ "422": { "description": "Validation error" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects/{project}": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "project",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Project name"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "get": {
|
|
|
+ "summary": "Get project info (collection and document counts)",
|
|
|
+ "operationId": "getProject",
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Project info",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "name": { "type": "string" },
|
|
|
+ "collections": { "type": "integer" },
|
|
|
+ "documents": { "type": "integer" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Project not found" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "delete": {
|
|
|
+ "summary": "Drop a project (admin only; not 'default')",
|
|
|
+ "operationId": "deleteProject",
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "Project deleted" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden — admin required or cannot drop default" },
|
|
|
+ "404": { "description": "Project not found" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/keys": {
|
|
|
+ "get": {
|
|
|
+ "summary": "List API keys (admin only; secret masked, only key_prefix shown)",
|
|
|
+ "operationId": "listKeys",
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Key list",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "keys": {
|
|
|
+ "type": "array",
|
|
|
+ "items": { "$ref": "#/components/schemas/ApiKeyPublic" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden — admin required" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "post": {
|
|
|
+ "summary": "Generate a new API key (admin only); returns the secret key value once",
|
|
|
+ "operationId": "createKey",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "label": { "type": "string" },
|
|
|
+ "projects": {
|
|
|
+ "type": "array",
|
|
|
+ "items": { "type": "string" },
|
|
|
+ "description": "Project names the key may access; use [\"*\"] for all projects"
|
|
|
+ },
|
|
|
+ "admin": { "type": "boolean", "default": false }
|
|
|
+ },
|
|
|
+ "required": ["label", "projects"]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "201": {
|
|
|
+ "description": "Key created; contains the secret key value (shown once)",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "key": { "type": "string" },
|
|
|
+ "label": { "type": "string" },
|
|
|
+ "projects": { "type": "array", "items": { "type": "string" } },
|
|
|
+ "admin": { "type": "boolean" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden — admin required" },
|
|
|
+ "422": { "description": "Validation error" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/keys/{key}": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "key",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "API key value"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "patch": {
|
|
|
+ "summary": "Update key grants (admin only)",
|
|
|
+ "operationId": "updateKey",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "label": { "type": "string" },
|
|
|
+ "projects": { "type": "array", "items": { "type": "string" } },
|
|
|
+ "admin": { "type": "boolean" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "Key updated" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden — admin required" },
|
|
|
+ "404": { "description": "Key not found" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "delete": {
|
|
|
+ "summary": "Revoke an API key (admin only)",
|
|
|
+ "operationId": "deleteKey",
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "Key revoked" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden — admin required" },
|
|
|
+ "404": { "description": "Key not found" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects/{project}/collections": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "project",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Project name"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "get": {
|
|
|
+ "summary": "List collections in a project",
|
|
|
+ "operationId": "listCollections",
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Collection list",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "collections": {
|
|
|
+ "type": "array",
|
|
|
+ "items": { "$ref": "#/components/schemas/CollectionMeta" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "post": {
|
|
|
+ "summary": "Create a collection in a project",
|
|
|
+ "operationId": "createCollection",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "name": { "type": "string" },
|
|
|
+ "kind": { "type": "string", "enum": ["json", "vector"] },
|
|
|
+ "vector_dimension": {
|
|
|
+ "type": "integer",
|
|
|
+ "minimum": 1,
|
|
|
+ "description": "Required when kind=vector"
|
|
|
+ },
|
|
|
+ "embedding_model": {
|
|
|
+ "type": "string",
|
|
|
+ "description": "Optional; defaults to global default_embedding_model"
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "required": ["name", "kind"]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "201": { "description": "Collection created" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "422": { "description": "Validation error (e.g. missing vector_dimension for vector kind)" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects/{project}/collections/{name}": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "project",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Project name"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "name",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Collection name"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "get": {
|
|
|
+ "summary": "Get collection metadata",
|
|
|
+ "operationId": "getCollection",
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Collection metadata",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": { "$ref": "#/components/schemas/CollectionMeta" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Collection not found" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "delete": {
|
|
|
+ "summary": "Drop a collection and all its documents",
|
|
|
+ "operationId": "deleteCollection",
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "Collection deleted" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Collection not found" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects/{project}/collections/{name}/documents": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "project",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Project name"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "name",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Collection name"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "get": {
|
|
|
+ "summary": "Find documents with optional filter, pagination, and sort",
|
|
|
+ "operationId": "findDocuments",
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "filter",
|
|
|
+ "in": "query",
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Filter expression in field:op:value grammar (e.g. age:gte:30, name:eq:Alice). Multiple filters are ANDed."
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "limit",
|
|
|
+ "in": "query",
|
|
|
+ "schema": { "type": "integer", "default": 20 }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "offset",
|
|
|
+ "in": "query",
|
|
|
+ "schema": { "type": "integer", "default": 0 }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "sort",
|
|
|
+ "in": "query",
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Field to sort by"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "desc",
|
|
|
+ "in": "query",
|
|
|
+ "schema": { "type": "boolean", "default": false }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Document list",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "documents": { "type": "array", "items": { "type": "object" } },
|
|
|
+ "count": { "type": "integer" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Collection not found" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "post": {
|
|
|
+ "summary": "Insert a new JSON document",
|
|
|
+ "operationId": "insertDocument",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "data": {
|
|
|
+ "type": "object",
|
|
|
+ "description": "Arbitrary JSON document payload"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "201": {
|
|
|
+ "description": "Document inserted",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "id": { "type": "string" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Collection not found" },
|
|
|
+ "422": { "description": "Validation error" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects/{project}/collections/{name}/documents/{id}": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "project",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Project name"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "name",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Collection name"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "id",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Document ID"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "get": {
|
|
|
+ "summary": "Get a document by ID",
|
|
|
+ "operationId": "getDocument",
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Document",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": { "type": "object" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Document not found" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "put": {
|
|
|
+ "summary": "Replace a document (full upsert by ID)",
|
|
|
+ "operationId": "replaceDocument",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": { "type": "object" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "Document replaced" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Collection not found" },
|
|
|
+ "422": { "description": "Validation error" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "patch": {
|
|
|
+ "summary": "Partially update a document (merge fields)",
|
|
|
+ "operationId": "patchDocument",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": { "type": "object" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "Document updated" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Document not found" },
|
|
|
+ "422": { "description": "Validation error" }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "delete": {
|
|
|
+ "summary": "Delete a document by ID",
|
|
|
+ "operationId": "deleteDocument",
|
|
|
+ "responses": {
|
|
|
+ "200": { "description": "Document deleted" },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Document not found" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects/{project}/collections/{name}/vectors": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "project",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Project name"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "name",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Collection name (must be kind=vector)"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "post": {
|
|
|
+ "summary": "Store a vector; supply either text (auto-embedded) or an explicit vector array",
|
|
|
+ "operationId": "upsertVector",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "id": {
|
|
|
+ "type": "string",
|
|
|
+ "description": "Optional stable ID; auto-generated if omitted"
|
|
|
+ },
|
|
|
+ "text": {
|
|
|
+ "type": "string",
|
|
|
+ "description": "Source text; will be embedded using the collection's embedding_model"
|
|
|
+ },
|
|
|
+ "vector": {
|
|
|
+ "type": "array",
|
|
|
+ "items": { "type": "number" },
|
|
|
+ "description": "Pre-computed embedding; dimension must match the collection's vector_dimension"
|
|
|
+ },
|
|
|
+ "metadata": {
|
|
|
+ "type": "object",
|
|
|
+ "description": "Arbitrary JSON payload stored alongside the vector"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "201": {
|
|
|
+ "description": "Vector stored",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "id": { "type": "string" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Collection not found" },
|
|
|
+ "422": { "description": "Validation error (wrong dimension, not a vector collection, etc.)" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects/{project}/collections/{name}/search": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "project",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Project name"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "name",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Collection name (must be kind=vector)"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "post": {
|
|
|
+ "summary": "Cosine-similarity search; supply either query_text (auto-embedded) or query_vector",
|
|
|
+ "operationId": "searchVectors",
|
|
|
+ "requestBody": {
|
|
|
+ "required": true,
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "query_text": {
|
|
|
+ "type": "string",
|
|
|
+ "description": "Query text; embedded with the collection's model"
|
|
|
+ },
|
|
|
+ "query_vector": {
|
|
|
+ "type": "array",
|
|
|
+ "items": { "type": "number" },
|
|
|
+ "description": "Pre-computed query embedding"
|
|
|
+ },
|
|
|
+ "top_k": {
|
|
|
+ "type": "integer",
|
|
|
+ "minimum": 1,
|
|
|
+ "description": "Maximum number of results to return"
|
|
|
+ },
|
|
|
+ "min_score": {
|
|
|
+ "type": "number",
|
|
|
+ "description": "Minimum cosine similarity score (0–1)"
|
|
|
+ },
|
|
|
+ "filters": {
|
|
|
+ "type": "array",
|
|
|
+ "items": { "type": "string" },
|
|
|
+ "description": "Metadata filters in field:op:value grammar (e.g. src:eq:n8n)"
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "required": ["top_k"]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Search results",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "results": {
|
|
|
+ "type": "array",
|
|
|
+ "items": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "id": { "type": "string" },
|
|
|
+ "score": { "type": "number" },
|
|
|
+ "metadata": { "type": "object" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" },
|
|
|
+ "404": { "description": "Collection not found" },
|
|
|
+ "422": { "description": "Validation error" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/projects/{project}/stats": {
|
|
|
+ "parameters": [
|
|
|
+ {
|
|
|
+ "name": "project",
|
|
|
+ "in": "path",
|
|
|
+ "required": true,
|
|
|
+ "schema": { "type": "string" },
|
|
|
+ "description": "Project name"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "get": {
|
|
|
+ "summary": "Per-project stats (accessible by any key granted the project)",
|
|
|
+ "operationId": "projectStats",
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Project stats",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "project": { "type": "string" },
|
|
|
+ "collections": { "type": "integer" },
|
|
|
+ "documents": { "type": "integer" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "/api/v1/stats": {
|
|
|
+ "get": {
|
|
|
+ "summary": "Server-wide stats (admin only)",
|
|
|
+ "operationId": "globalStats",
|
|
|
+ "responses": {
|
|
|
+ "200": {
|
|
|
+ "description": "Global stats",
|
|
|
+ "content": {
|
|
|
+ "application/json": {
|
|
|
+ "schema": {
|
|
|
+ "type": "object",
|
|
|
+ "properties": {
|
|
|
+ "projects": { "type": "integer" },
|
|
|
+ "memory_pressure_level": { "type": "integer" },
|
|
|
+ "collections": { "type": "integer" },
|
|
|
+ "documents": { "type": "integer" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "401": { "description": "Unauthorized" },
|
|
|
+ "403": { "description": "Forbidden — admin required" }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|