{"openapi":"3.1.0","info":{"title":"AI Backends","version":"v1.0.0","description":"Making common AI use cases easily accessible and customizable. Skip the heavy lifting of understanding OpenAI or other providers with our open source stack.","contact":{"name":"AI Backends Support","url":"https://github.com/donvito/ai-backend"}},"servers":[{"url":"https://ai.backend.gquizmaker.com","description":"Production server"}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"HealthcheckResponse":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"message":{"type":"string","example":"Service is healthy"}},"required":["status","message"]}},"parameters":{}},"paths":{"/api/jsoneditor":{"get":{"tags":["Tools"],"responses":{"200":{"description":"Returns the AI Backend JSON editor interface for testing API payloads.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/shared/safedom.js":{"get":{"tags":["Static"],"responses":{"200":{"description":"Returns the safedom.js utility file.","content":{"application/javascript":{"schema":{"type":"string"}}}}}}},"/api/v1/pdf-summarizer":{"post":{"security":[{"BearerAuth":[]}],"summary":"Summarize PDF document","description":"This endpoint receives a PDF URL and uses an LLM to summarize the document's content.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"maxLength":{"type":"number","minimum":0,"description":"Maximum length of the summary in characters"}},"required":["url"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the summarized PDF content.","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"string"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"pdfMetadata":{"type":"object","properties":{"title":{"type":"string"},"author":{"type":"string"},"pages":{"type":"number"},"extractedTextLength":{"type":"number","description":"Number of characters extracted from the PDF"}},"required":["extractedTextLength"]},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["summary","usage"]}}}},"400":{"description":"Bad request - Invalid URL or PDF cannot be processed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/rewrite":{"post":{"security":[{"BearerAuth":[]}],"summary":"Rewrite text","description":"This endpoint accepts text and an optional instruction, then uses an LLM to rewrite the text accordingly.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1,"description":"Text to rewrite"},"instruction":{"type":"string","description":"Predefined rewrite instruction (case-insensitive)"},"tone":{"type":"string","description":"Required only when instruction = rewrite_with_tone (case-insensitive)"},"maxLength":{"type":"number","minimum":0}},"required":["text","instruction"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the rewritten text.","content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["text","usage"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/pdf-translate":{"post":{"security":[{"BearerAuth":[]}],"summary":"Translate PDF document","description":"This endpoint receives a PDF URL and uses an LLM to translate the document's content to the target language.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"targetLanguage":{"type":"string","description":"Target language e.g. \"english\", \"tagalog\", \"japanese\", \"korean\", \"chinese\", \"french\", \"spanish\""}},"required":["url","targetLanguage"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the translated PDF content.","content":{"application/json":{"schema":{"type":"object","properties":{"translation":{"type":"string"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"pdfMetadata":{"type":"object","properties":{"title":{"type":"string"},"author":{"type":"string"},"pages":{"type":"number"},"extractedTextLength":{"type":"number","description":"Number of characters extracted from the PDF"}},"required":["extractedTextLength"]},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["translation","usage"]}}}},"400":{"description":"Bad request - Invalid URL or PDF cannot be processed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/compose-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Compose demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/web-search-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the WebSearch demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/ocr-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the OCR demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/email-reply-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Email Reply demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/meeting-notes-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Meeting Notes demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/pdf-keywords-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the PDF Keywords demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/rewrite-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Rewrite demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/project-planner-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Project Planner demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/keywords-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Keywords demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/pdf-translate-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the PDF Translation demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/synthetic-data-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Synthetic Data Generation demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/vision-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Vision demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/sentiment-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Sentiment Analysis demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/pdf-summarizer-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the PDF Summarization demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/translate-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Translate demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/highlighter-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Highlighter demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/demos":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the demos index page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/summarize-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the Summarization demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/asktext-demo":{"get":{"tags":["Demos"],"responses":{"200":{"description":"Returns the AskText demo page.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/v1/hello":{"get":{"tags":["Health"],"responses":{"200":{"description":"Returns the health status of the service.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthcheckResponse"}}}}}}},"/api/v1/keywords":{"post":{"summary":"Extract keywords from text","description":"This endpoint receives a text and uses an LLM to extract keywords from the text.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1},"maxKeywords":{"type":"integer","minimum":0,"exclusiveMinimum":true},"temperature":{"type":"number","minimum":0,"maximum":1}},"required":["text"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the extracted keywords.","content":{"application/json":{"schema":{"type":"object","properties":{"keywords":{"type":"array","items":{"type":"string"}},"provider":{"type":"string","description":"The AI service that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["keywords","usage"]}}}}}}},"/api/v1/project-planner":{"post":{"security":[{"BearerAuth":[]}],"summary":"Generate structured plans for tasks","description":"This endpoint receives a task description and generates a detailed, structured plan with steps, dependencies, time estimates, and success criteria.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"task":{"type":"string","description":"The task or goal to create a plan for"},"context":{"type":"string","description":"Additional context or constraints for the plan"},"maxSteps":{"type":"number","default":10,"description":"Maximum number of steps to include"},"detailLevel":{"type":"string","enum":["basic","detailed","comprehensive"],"default":"detailed","description":"Level of detail for the plan"},"includeTimeEstimates":{"type":"boolean","default":true,"description":"Whether to include time estimates"},"includeRisks":{"type":"boolean","default":true,"description":"Whether to identify potential risks"},"domain":{"type":"string","description":"Domain or field of the task (e.g., \"software development\", \"project management\")"}},"required":["task"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns a structured plan to accomplish the given task.","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","description":"The generated plan as formatted text"},"metadata":{"type":"object","properties":{"generatedAt":{"type":"string","description":"ISO timestamp of when the plan was generated"},"provider":{"type":"string","description":"AI provider used"},"model":{"type":"string","description":"Model used for generation"},"processingTime":{"type":"number","description":"Time taken to generate plan in milliseconds"}},"required":["generatedAt","provider","model"]},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]},"apiVersion":{"type":"string"}},"required":["plan","metadata"]}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/ocr":{"post":{"security":[{"BearerAuth":[]}],"summary":"Extract structured data from image using OCR","description":"This endpoint receives an image URL and extraction instructions, then uses ZAI GLM-4.6V vision models to extract structured data. Optionally provide a JSON schema to format the output.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"imageUrl":{"type":"string","format":"uri","description":"URL of the image to extract data from"},"prompt":{"type":"string","default":"Extract all information from this image.","description":"Instructions for what data to extract"},"jsonSchema":{"type":"object","additionalProperties":{"nullable":true},"description":"Optional JSON schema to structure the output"}},"required":["imageUrl"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the extracted data from the image.","content":{"application/json":{"schema":{"type":"object","properties":{"rawText":{"type":"string","description":"Raw text response from the model"},"extractedData":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Parsed JSON data if extraction was successful"},"parseError":{"type":"string","description":"Error message if JSON parsing failed"},"model":{"type":"string","description":"The model used"},"provider":{"type":"string","description":"The provider used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"],"description":"Token usage information"}},"required":["rawText","extractedData","model","provider"]}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"details":{"type":"string","description":"Additional error details"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Server error - Failed to extract data","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"details":{"type":"string","description":"Additional error details"}},"required":["error"]}}}}}}},"/api/v1/meeting-notes":{"post":{"summary":"Extract meeting notes from text","description":"This endpoint receives a text and uses an LLM to extract meeting notes from the text.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1}},"required":["text"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns structured meeting notes (date, attendees, tasks, decisions, updates, summary).","content":{"application/json":{"schema":{"type":"object","properties":{"decisions":{"type":"array","items":{"type":"string"},"description":"Decisions made during the meeting"},"tasks":{"type":"array","items":{"type":"object","properties":{"task":{"type":"string"},"owner":{"type":"string"},"estimate":{"type":"string","description":"Estimated completion time or effort (e.g., \"2 weeks\", \"3 days\", \"high priority\")"}},"required":["task"]},"description":"Action items identified during the meeting"},"attendees":{"type":"array","items":{"type":"string"},"description":"List of attendees if mentioned"},"meeting_date":{"type":"string","description":"Meeting date/time in ISO 8601 (e.g., YYYY-MM-DD or YYYY-MM-DDTHH:mm) if mentioned"},"updates":{"type":"array","items":{"type":"string"},"description":"Status updates or progress mentioned during the meeting"},"summary":{"type":"string","description":"Short summary (1–2 sentences) of the meeting"},"provider":{"type":"string","description":"The AI service that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["decisions","tasks","attendees","updates","summary","usage"]}}}}}}},"/api/v1/sentiment":{"post":{"security":[{"BearerAuth":[]}],"summary":"Analyze sentiment of text","description":"This endpoint receives a text and uses an LLM to analyze the sentiment of the text.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":10000},"categories":{"type":"array","items":{"type":"string"}}},"required":["text"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns sentiment analysis results.","content":{"application/json":{"schema":{"type":"object","properties":{"sentiment":{"type":"string"},"confidence":{"type":"number","minimum":0,"maximum":1},"emotions":{"type":"array","items":{"type":"object","properties":{"emotion":{"type":"string"},"score":{"type":"number"}},"required":["emotion","score"]}},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["sentiment","confidence","emotions","provider","model","usage"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/summarize":{"post":{"security":[{"BearerAuth":[]}],"summary":"Summarize text","description":"This endpoint receives a text and uses an LLM to summarize the text.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1},"maxLength":{"type":"number","minimum":0}},"required":["text"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the summarized text.","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"string"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["summary","usage"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/highlighter":{"post":{"security":[{"BearerAuth":[]}],"summary":"Highlight key parts of text","description":"This endpoint receives a text and uses an LLM to generate highlight spans with labels and descriptions for key parts of the text.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1},"maxHighlights":{"type":"integer","minimum":0,"exclusiveMinimum":true},"temperature":{"type":"number","minimum":0,"maximum":1}},"required":["text"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns highlight spans with labels and descriptions for key parts of the text.","content":{"application/json":{"schema":{"type":"object","properties":{"highlights":{"type":"array","items":{"type":"object","properties":{"char_start_position":{"type":"integer","minimum":0},"char_end_position":{"type":"integer","minimum":0,"description":"Exclusive end index"},"label":{"type":"string","minLength":1,"maxLength":80,"description":"Short label identifying the highlight"},"description":{"type":"string"}},"required":["char_start_position","char_end_position","label","description"]}},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["highlights","usage"]}}}}}}},"/api/v1/translate":{"post":{"summary":"Translate text","description":"This endpoint receives a text and uses an LLM to translate the text to the target language.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","description":"Text to translate"},"targetLanguage":{"type":"string","description":"Target language e.g.  \"english\", \"tagalog\", \"japanese\", \"korean\", \"chinese\", \"french\", \"spanish\""}},"required":["text","targetLanguage"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the translated text.","content":{"application/json":{"schema":{"type":"object","properties":{"translation":{"type":"string"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["translation","usage"]}}}}}}},"/api/v1/compose":{"post":{"security":[{"BearerAuth":[]}],"summary":"Compose text","description":"This endpoint receives a topic and uses an LLM to compose text about it.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"topic":{"type":"string","minLength":1},"maxLength":{"type":"number","minimum":0}},"required":["topic"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns composed text for the provided topic.","content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["text","usage"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/outline":{"post":{"security":[{"BearerAuth":[]}],"summary":"Create outline from text","description":"This endpoint receives a text and uses an LLM to create a structured outline.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1},"maxDepth":{"type":"number","minimum":1,"maximum":5,"description":"Maximum depth of outline levels (default: 3)"},"style":{"type":"string","enum":["numbered","bulleted","mixed"],"description":"Outline style (default: numbered)"},"includeIntro":{"type":"boolean","description":"Include an introduction paragraph (default: false)"},"includeConclusion":{"type":"boolean","description":"Include a conclusion paragraph (default: false)"}},"required":["text"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the generated outline.","content":{"application/json":{"schema":{"type":"object","properties":{"outline":{"type":"string","description":"The generated outline in markdown format"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["outline","usage"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/ask-text":{"post":{"security":[{"BearerAuth":[]}],"summary":"Answer questions based on provided text","description":"This endpoint receives a text and a question, then uses an LLM to generate an answer based solely on the provided text context.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1,"description":"The text context to base the answer on"},"question":{"type":"string","minLength":1,"description":"The question to answer based on the text"}},"required":["text","question"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns an answer to the question based on the provided text.","content":{"application/json":{"schema":{"type":"object","properties":{"answer":{"type":"string","description":"The answer to the question based on the provided text"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"],"description":"Token usage information"}},"required":["answer","usage"]}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/services/status":{"get":{"responses":{"200":{"description":"Returns status of all AI services","content":{"application/json":{"schema":{"type":"object","properties":{"services":{"type":"object","properties":{"openai":{"type":"object","properties":{"enabled":{"type":"boolean"},"available":{"type":"boolean"},"config":{"type":"object","properties":{"model":{"type":"string"},"hasApiKey":{"type":"boolean"}},"required":["model","hasApiKey"]}},"required":["enabled","available","config"]},"ollama":{"type":"object","properties":{"enabled":{"type":"boolean"},"available":{"type":"boolean"},"config":{"type":"object","properties":{"baseURL":{"type":"string"},"model":{"type":"string"},"chatModel":{"type":"string"}},"required":["baseURL","model","chatModel"]}},"required":["enabled","available","config"]},"openrouter":{"type":"object","properties":{"enabled":{"type":"boolean"},"available":{"type":"boolean"},"config":{"type":"object","properties":{"model":{"type":"string"},"hasApiKey":{"type":"boolean"},"baseURL":{"type":"string","nullable":true}},"required":["model","hasApiKey"]}},"required":["enabled","available","config"]},"anthropic":{"type":"object","properties":{"enabled":{"type":"boolean"},"available":{"type":"boolean"},"config":{"type":"object","properties":{"model":{"type":"string"},"hasApiKey":{"type":"boolean"}},"required":["model","hasApiKey"]}},"required":["enabled","available","config"]},"lmstudio":{"type":"object","properties":{"enabled":{"type":"boolean"},"available":{"type":"boolean"},"config":{"type":"object","properties":{"baseURL":{"type":"string"},"model":{"type":"string"},"chatModel":{"type":"string"}},"required":["baseURL","model","chatModel"]}},"required":["enabled","available","config"]},"google":{"type":"object","properties":{"enabled":{"type":"boolean"},"available":{"type":"boolean"},"config":{"type":"object","properties":{"model":{"type":"string"},"hasApiKey":{"type":"boolean"}},"required":["model","hasApiKey"]}},"required":["enabled","available","config"]}},"required":["openai","ollama","openrouter","anthropic","lmstudio","google"]},"primary":{"type":"string","nullable":true},"anyAvailable":{"type":"boolean"}},"required":["services","primary","anyAvailable"]}}}}}}},"/api/v1/services/models":{"get":{"parameters":[{"schema":{"type":"string","description":"Service to get models for (openai, ollama, openrouter, anthropic, lmstudio, or auto for all)","example":"auto"},"required":false,"name":"service","in":"query"},{"schema":{"type":"string","enum":["live","config"],"description":"Data source: live fetch from providers, or config-guidance from models.json","example":"config"},"required":false,"name":"source","in":"query"},{"schema":{"type":"string","enum":["capability","provider","both"],"description":"When source=config, return models grouped by capability (default), by provider, or both","example":"both"},"required":false,"name":"view","in":"query"}],"responses":{"200":{"description":"Returns available models for the specified service(s)","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"service":{"type":"string"},"models":{"type":"array","items":{"type":"string"}},"available":{"type":"boolean"}},"required":["service","models","available"]},{"type":"object","properties":{"openai":{"type":"object","properties":{"service":{"type":"string"},"models":{"type":"array","items":{"type":"string"}},"available":{"type":"boolean"}},"required":["service","models","available"]},"ollama":{"type":"object","properties":{"service":{"type":"string"},"models":{"type":"array","items":{"type":"string"}},"available":{"type":"boolean"}},"required":["service","models","available"]},"openrouter":{"type":"object","properties":{"service":{"type":"string"},"models":{"type":"array","items":{"type":"string"}},"available":{"type":"boolean"}},"required":["service","models","available"]},"anthropic":{"type":"object","properties":{"service":{"type":"string"},"models":{"type":"array","items":{"type":"string"}},"available":{"type":"boolean"}},"required":["service","models","available"]},"lmstudio":{"type":"object","properties":{"service":{"type":"string"},"models":{"type":"array","items":{"type":"string"}},"available":{"type":"boolean"}},"required":["service","models","available"]},"google":{"type":"object","properties":{"service":{"type":"string"},"models":{"type":"array","items":{"type":"string"}},"available":{"type":"boolean"}},"required":["service","models","available"]}},"required":["openai","ollama","openrouter","anthropic","lmstudio","google"]},{"type":"object","properties":{"source":{"type":"string","enum":["config"]},"byCapability":{"type":"object","properties":{"summarize":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"web-search":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"pdf-summarizer":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"pdf-translate":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"rewrite":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"compose":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"keywords":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"sentiment":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"emailReply":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"planning":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"vision":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"askText":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"translate":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"meetingNotes":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"outline":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["summarize","web-search","pdf-summarizer","pdf-translate","rewrite","compose","keywords","sentiment","emailReply","planning","vision","askText","translate","meetingNotes","outline"]},"byProvider":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"capabilities":{"type":"array","items":{"type":"string","enum":["summarize","web-search","pdf-summarizer","pdf-translate","rewrite","compose","keywords","sentiment","emailReply","vision","askText","translate","meetingNotes","planning","outline"]}},"notes":{"type":"string"}},"required":["name","capabilities"]}}}},"required":["source"]}]}}}}}}},"/api/v1/services/health/{service}":{"get":{"parameters":[{"schema":{"type":"string","description":"Service to check health for","example":"ollama"},"required":true,"name":"service","in":"path"}],"responses":{"200":{"description":"Returns health status of the specified service","content":{"application/json":{"schema":{"type":"object","properties":{"service":{"type":"string"},"available":{"type":"boolean"},"timestamp":{"type":"string"}},"required":["service","available","timestamp"]}}}}}}},"/api/v1/describe-image":{"post":{"security":[{"BearerAuth":[]}],"summary":"Describe an image","description":"This endpoint receives an image and uses an LLM to generate a description of the image.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"service":{"type":"string","enum":["ollama"],"description":"The AI service to use for image description (currently only ollama is supported, auto will select ollama)"},"model":{"type":"string","description":"The model to use for image description"},"temperature":{"type":"number","default":0,"description":"The temperature of the response"},"stream":{"type":"boolean","default":false,"description":"Whether to stream the response"},"images":{"type":"array","items":{"type":"string"},"description":"Array of base64 encoded images"}},"required":["service","model","images"]}}}},"responses":{"200":{"description":"Returns the image description.","content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"The model used for image description"},"created_at":{"type":"string","description":"ISO timestamp of when the response was created"},"message":{"type":"object","properties":{"role":{"type":"string","description":"The role of the response"},"content":{"type":"string","description":"The description of the image"}},"required":["role","content"]},"done_reason":{"type":"string","description":"Reason why generation stopped"},"done":{"type":"boolean","description":"Whether the generation is complete"},"total_duration":{"type":"number","description":"Total duration in nanoseconds"},"load_duration":{"type":"number","description":"Model load duration in nanoseconds"},"prompt_eval_count":{"type":"number","description":"Number of tokens in the prompt"},"prompt_eval_duration":{"type":"number","description":"Prompt evaluation duration in nanoseconds"},"eval_count":{"type":"number","description":"Number of tokens in the response"},"eval_duration":{"type":"number","description":"Response generation duration in nanoseconds"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"],"description":"Token usage information"},"service":{"type":"string","description":"The AI service that was actually used"}},"required":["model","created_at","message","done_reason","done"]}}}},"400":{"description":"Bad Request - Invalid input, missing images, unsupported service, or unsupported model","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"supportedModels":{"type":"object","properties":{"ollama":{"type":"array","items":{"type":"string"},"description":"Available Ollama vision models"}},"required":["ollama"],"description":"List of supported models by service"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/email-reply":{"post":{"summary":"Generate an email reply","description":"This endpoint receives an email text and uses an LLM to generate a reply to the email.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"text":{"type":"string","minLength":1,"description":"The email content to reply to"},"customInstruction":{"type":"string","description":"Optional combined guidance/style instruction, e.g., \"positive, professional in Tagalog\""},"senderName":{"type":"string","description":"Optional sender name to address in the reply without greeting words"},"recipientName":{"type":"string","description":"Optional name of the person writing the reply (the recipient of the original email)"}},"required":["text"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns an email reply to the provided email text.","content":{"application/json":{"schema":{"type":"object","properties":{"reply":{"type":"string"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["reply","usage"]}}}}}}},"/api/v1/web-search":{"post":{"security":[{"BearerAuth":[]}],"summary":"Perform web search and summarize results","description":"This endpoint performs a web search using the Firecrawl API and converts the results into a natural language summary using an LLM.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"query":{"type":"string","minLength":1,"description":"The search query"},"limit":{"type":"number","minimum":1,"maximum":20,"default":10,"description":"Maximum number of results to return (1-20)"},"sources":{"type":"array","items":{"type":"string"},"default":["web"],"description":"The sources to search from"}},"required":["query"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns a natural language summary of web search results.","content":{"application/json":{"schema":{"type":"object","properties":{"searchResult":{"type":"string","description":"A natural language summary of the search results"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"],"description":"Token usage information"}},"required":["searchResult","usage"]}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/synthetic-data":{"post":{"security":[{"BearerAuth":[]}],"summary":"Generate synthetic data based on user prompt","description":"This endpoint generates synthetic data based on a user-provided prompt. Users must provide a JSON schema that defines the structure of the generated data.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"description":"Description of the synthetic data to generate"},"schema":{"type":"object","additionalProperties":{"nullable":true},"description":"JSON schema that defines the structure of the generated data"},"count":{"type":"number","minimum":1,"maximum":100,"default":1,"description":"Number of synthetic data records to generate (1-100)"}},"required":["prompt","schema"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns generated synthetic data in the requested format.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"nullable":true,"description":"The generated synthetic data following the provided JSON schema"},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"],"description":"Token usage information"},"metadata":{"type":"object","properties":{"count":{"type":"number","description":"Number of records generated"},"validation_passed":{"type":"boolean","description":"Whether the generated data passed schema validation"}},"required":["count","validation_passed"],"description":"Generation metadata"}},"required":["usage","metadata"]}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v1/vision":{"post":{"security":[{"BearerAuth":[]}],"summary":"Analyze an image with vision AI","description":"This endpoint receives an image URL and a prompt, then uses ZAI GLM-4.6V vision models to answer questions about the image, detect objects, and provide coordinates.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"imageUrl":{"type":"string","format":"uri","description":"URL of the image to analyze"},"prompt":{"type":"string","description":"Question or prompt about the image"},"thinking":{"type":"boolean","default":false,"description":"Enable thinking mode for more detailed analysis"}},"required":["imageUrl","prompt"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the vision analysis result.","content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Response from the vision model"},"thinking":{"type":"string","description":"Model thinking process if enabled"},"model":{"type":"string","description":"The model used"},"provider":{"type":"string","description":"The provider used"},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"],"description":"Token usage information"}},"required":["text","model","provider"]}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"details":{"type":"string","description":"Additional error details"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Server error - Failed to analyze image","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"details":{"type":"string","description":"Additional error details"}},"required":["error"]}}}}}}},"/api/v1/pdf-keywords":{"post":{"security":[{"BearerAuth":[]}],"summary":"Extract keywords from PDF document","description":"This endpoint receives a PDF URL and uses an LLM to extract keywords from the document's content.","tags":["API"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"maxKeywords":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["url"]},"config":{"type":"object","properties":{"provider":{"type":"string","enum":["ollama","openai","anthropic","openrouter","lmstudio","aigateway","llamacpp","google","baseten","llmgateway","zai"],"description":"AI service to use"},"model":{"type":"string","description":"Specific model to use"},"temperature":{"type":"number","default":0},"stream":{"type":"boolean","default":false,"description":"Enable streaming response"}},"required":["provider","model"]}},"required":["payload","config"]}}}},"responses":{"200":{"description":"Returns the extracted keywords from the PDF.","content":{"application/json":{"schema":{"type":"object","properties":{"keywords":{"type":"array","items":{"type":"string"}},"provider":{"type":"string","description":"The AI service that was actually used"},"model":{"type":"string","description":"The model that was actually used"},"pdfMetadata":{"type":"object","properties":{"title":{"type":"string"},"author":{"type":"string"},"pages":{"type":"number"},"extractedTextLength":{"type":"number","description":"Number of characters extracted from the PDF"}},"required":["extractedTextLength"]},"usage":{"type":"object","properties":{"input_tokens":{"type":"number"},"output_tokens":{"type":"number"},"total_tokens":{"type":"number"}},"required":["input_tokens","output_tokens","total_tokens"]}},"required":["keywords","usage"]}}}},"400":{"description":"Bad request - Invalid URL or PDF cannot be processed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Unauthorized - Bearer token required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/v2/hello":{"get":{"tags":["Health"],"responses":{"200":{"description":"Returns the health status of the service.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthcheckResponse"}}}}}}}}}