dotAI REST API Resources
The dotAI feature offers a wealth of API tools to undertake OpenAI operations headlessly. Similar to the viewtool, the endpoints include those that focus on generation, searching, embeddings, and completions.
The various endpoints exist as child paths of /api/v1/ai, outlined below by category and path.
Generative Endpoints#
| Path | Method |
|---|---|
/api/v1/ai/text/generate | GET |
/api/v1/ai/text/generate | POST |
/api/v1/ai/image/test | GET |
/api/v1/ai/image/generate | GET |
/api/v1/ai/image/generate | POST |
Generate Text (GET)#
Calling the GET text-generation endpoint requires only a prompt.
Endpoint: GET /v1/ai/text/generate
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
prompt | Yes | Text generation prompt |
Response Type: application/json
Example:
curl -X 'GET' \ 'http://localhost:8082/api/v1/ai/text/generate?prompt=test' \ -H 'accept: application/json'
The response object resembles that of the dotAI viewtool's $ai.completions.raw() method:
{ "id": "chatcmpl-CZJuecFUiWcPKTk9MYqJ6Qu5mBTpI", "object": "chat.completion", "created": 1762534060, "model": "gpt-4.1-2025-04-14", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Hello! 👋 It looks like you're testing the bot. How can I assist you today with your content management needs? If you want to generate, rewrite, or review content, just let me know!", "refusal": null, "annotations": [] }, "logprobs": null, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 35, "completion_tokens": 41, "total_tokens": 76, "prompt_tokens_details": { "cached_tokens": 0, "audio_tokens": 0 }, "completion_tokens_details": { "reasoning_tokens": 0, "audio_tokens": 0, "accepted_prediction_tokens": 0, "rejected_prediction_tokens": 0 } }, "service_tier": "default", "system_fingerprint": "fp_d38c7f4fa7" }
Generate Text (POST)#
When called with POST, a data payload is instead required, of the type described under the section on completions forms, providing a greater range of configurability. However, the actual submissions can be as simple as only including a prompt property, as follows:
Generates text with advanced configuration options.
Endpoint: POST /v1/ai/text/generate
Request Body: CompletionsForm (application/json)
Response Type: application/json
Example Request:
curl -X 'POST' \ 'http://localhost:8082/api/v1/ai/text/generate' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "prompt": "tell me about costa rica!" "model": "gpt-4", "temperature": 0.7, "responseLengthTokens": 256 }'
The success response object will be the same as for the corresponding GET endpoint.
For the full set of properties, see the completions form.
Generate Image (GET) (Test)#
Simple test endpoint to verify image service availability.
Endpoint: GET /v1/ai/image/test
Response Type: application/json
Success Response (200):
{ "type": "image" }
Generate Image (GET)#
Generates an AI image from a text prompt using query parameters.
Endpoint: GET /v1/ai/image/generate
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
prompt | Yes | Text description of image to generate |
Response Type: application/json
Error Responses:
400- Missing or invalid prompt401- User not authenticated500- App config missing or internal error
Example Request:
When called with GET, only a prompt path parameter is required:
curl -X 'GET' \ 'http://localhost:8082/api/v1/ai/image/generate?prompt=a%20pig%20wearing%20a%20hat' \ -H 'accept: application/json'
The result is as follows:
{ "revised_prompt": "A playful farm scene showcasing a pink pig. This pig is unique, it is wearing a hat possibly a sunhat for the bright sunny day. The hat is delicately perched on the pig's big head. Attention is drawn to the pig's gleeful expressions, and the curious sparkle in its eyes. Different shades of pink colour are reflected on its body indicating a healthy pig with a tinge of fun and eccentricity with the presence of the hat. The whole ambiance of the farm is of warmth and vitality. A light breeze may be rustling through making the image lively.", "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-qZnNeZvyp7uFUh2EX8AJA6gw/user-2MAFKcfsfuJ7ILKoM3ZYWUcs/img-sLsWAgFW0B7U5cLaRblzmQeF.png?st=2024-02-12T13%3A29%3A31Z&se=2024-02-12T15%3A29%3A31Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-02-12T14%3A27%3A13Z&ske=2024-02-13T14%3A27%3A13Z&sks=b&skv=2021-08-06&sig=qwmBl4uETTfn14v4jQhUUUeH1HihtKm2m4udyxlmm%2BE%3D", "originalPrompt": "a pig wearing a hat", "tempFileName": "pig_20240212_022931.png", "response": "temp_298431dce8", "tempFile": "/data/shared/assets/tmp_upload/temp_298431dce8/pig_20240212_022931.png" }
Generate Image (POST)#
Generates an AI image with advanced configuration options.
Endpoint: POST /v1/ai/image/generate
Request Body: AIImageRequestDTO (application/json)
Response Type: application/json
Example Request:
{ "prompt": "A serene mountain landscape with a lake", "numberOfImages": 1, "size": "1024x1024", "quality": "hd", "style": "vivid" }
See further details on the image request form data members below.
Responses are as documented under the corresponding GET method.
Search Endpoints#
| Path | Method |
|---|---|
/api/v1/ai/search/test | GET |
/api/v1/ai/search | GET |
/api/v1/ai/search | POST |
/api/v1/ai/search/related | GET |
/api/v1/ai/search/related | POST |
Test Endpoint#
Simple test endpoint to verify search service availability.
Endpoint: GET /v1/ai/search/test
Response Type: application/json
Success Response (200):
{ "type": "search" }
Semantic Search (GET)#
Performs AI-powered semantic search using vector similarity. This endpoint accepts query parameters for basic search operations.
Endpoint: GET /v1/ai/search
Query Parameters:
When performing a GET call to ai/search, a list of query parameters are accepted that parallel the properties of the completions form used in many other functions.
| Parameter | Required | Default | Description |
|---|---|---|---|
query | Yes | - | Search query text |
searchLimit | No | 1000 | Maximum results (1-1000) |
searchOffset | No | 0 | Result offset for pagination |
site | No | - | Filter by site |
contentType | No | - | Filter by content type |
indexName | No | "default" | Index to search |
threshold | No | 0.5 | Similarity threshold (0-1) |
stream | No | false | Enable streaming response |
responseLength | No | 1024 | Max response length in tokens |
operator | No | "<=>" | Distance operator (<=>, <->, <#>) |
language | No | - | Filter by language |
Response Types:
application/json- Complete search resultsapplication/octet-stream- Streaming response (whenstream=true)
Success Response (200):
{ "results": [ { "identifier": "abc123", "title": "Matching Content Title", "contentType": "Blog", "score": 0.89, "content": "Relevant content excerpt..." } ], "totalResults": 15, "query": "artificial intelligence", "threshold": 0.5 }
Error Responses:
401- User not authenticated500- Internal server error
Example Request:
Specifying a query and index should suffice as a bare minimum to yield results:
curl -X 'GET' \ 'http://localhost:8082/api/v1/ai/search?query=snow&indexName=blogIndex' \ -H 'accept: application/json'
For more refined searches with additional filtering:
curl -X 'GET' \ 'http://localhost:8082/api/v1/ai/search?query=machine%20learning&searchLimit=20&contentType=Blog&threshold=0.7' \ -H 'accept: application/json'
The returned object will have the same schema as that returned by a viewtool search function.
Semantic Search (POST)#
Performs AI-powered semantic search with form data, providing the same functionality as the GET endpoint but accepting parameters in the request body.
Endpoint: POST /v1/ai/search
Request Body: CompletionsForm (application/json)
Response Type: application/json
Example Request:
{ "prompt": "cloud computing best practices", "searchLimit": 50, "searchOffset": 0, "contentType": "Blog,NewsArticle", "site": "demo.dotcms.com", "threshold": 0.6, "indexName": "default", "operator": "cosine" }
Success Response (200):
{ "results": [ { "identifier": "xyz789", "title": "Cloud Computing Guide", "contentType": "Blog", "score": 0.92, "content": "Best practices for cloud..." } ], "totalResults": 23 }
Find Related Content (GET)#
Finds content semantically related to a specific piece of content using query parameters that point to the source content.
Endpoint: GET /v1/ai/search/related
Query Parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
identifier | Optional* | - | Content identifier |
inode | Optional* | - | Content inode |
language | No | - | Language ID |
indexName | No | "default" | Index to search |
fieldVar | No | - | Specific field to use for similarity |
Note: Either identifier or inode must be provided.
Response Type: application/json
Success Response (200):
{ "results": [ { "identifier": "related123", "title": "Similar Article", "contentType": "Blog", "score": 0.85, "content": "Related content..." } ], "sourceIdentifier": "abc123", "totalResults": 10 }
Error Responses:
401- User not authenticated404- Content not found500- Internal server error
Example Request:
The five key parameters point to a piece of content (language, identifier, inode), an index (indexName), and a specific field within the contentlet (fieldVar):
curl -X 'GET' \ 'http://localhost:8082/api/v1/ai/search/related?language=0&identifier=3d6fa2a4-2b48-4421-a2f5-b6518a7c0830&inode=ae49b86b-6bd2-47d4-924e-c8e747d9bf0a&indexName=blogIndex&fieldVar=blogContent' \ -H 'accept: application/json'
Find Related Content (POST)#
Finds related content using JSON request body, providing the same functionality as the GET endpoint but with parameters submitted as payload data.
Endpoint: POST /v1/ai/search/related
Request Body:
{ "identifier": "abc123", "language": 1, "indexName": "default", "fieldVar": "body" }
Response Type: application/json
Success Response (200):
{ "results": [ { "identifier": "related456", "title": "Related Content", "contentType": "NewsArticle", "score": 0.78, "content": "Content excerpt..." } ], "totalResults": 8 }
Example Request:
curl -X 'POST' \ 'http://localhost:8082/api/v1/ai/search/related' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "language":0, "identifier":"3d6fa2a4-2b48-4421-a2f5-b6518a7c0830", "inode":"ae49b86b-6bd2-47d4-924e-c8e747d9bf0a", "indexName":"blogIndex", "fieldVar":"blogContent" }'
Embeddings Endpoints#
| Path | Method |
|---|---|
/api/v1/ai/embeddings/test | GET |
/api/v1/ai/embeddings | POST |
/api/v1/ai/embeddings | DELETE |
/api/v1/ai/embeddings/count | GET |
/api/v1/ai/embeddings/count | POST |
/api/v1/ai/embeddings/indexCount | GET |
/api/v1/ai/embeddings/db | DELETE |
Test Endpoint#
Simple test endpoint to verify embeddings service availability.
Endpoint: GET /v1/ai/embeddings/test
Response Type: application/json
Success Response (200):
{ "type": "embeddings" }
Create Embeddings#
Creates vector embeddings for content matching the provided query. Processes content in batches and adds them to the specified index.
Endpoint: POST /v1/ai/embeddings
Request Body: EmbeddingsForm (application/json)
Response Type: application/json
Success Response (200):
{ "timeToEmbeddings": "5432ms", "totalToEmbed": 150, "indexName": "default" }
Error Responses:
401- User not authenticated500- Internal server error with error details
Example Request:
curl -X 'POST' \ 'http://localhost:8082/api/v1/ai/embeddings' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "query": "+contentType:blogIndex +variant:default +live:true", "limit": 1000, "offset": 0, "indexName": "blogIndex", "model": "text-embedding-ada-002", "fields":"blogContent" }'
Notes:
- Processes up to 10,000 iterations
- Automatically adds
+live:trueto query - Results sorted by modification date
- Batch processes based on limit parameter
Delete Embeddings#
Deletes embeddings matching specific criteria or by query. Can delete individual contentlets, entire content types, or arbitrary query results.
Endpoint: DELETE /v1/ai/embeddings
Request Body (Option 1 - Query-based deletion):
{ "deleteQuery": "+contentType:Blog +site:demo.dotcms.com", "indexName": "default" }
Request Body (Option 2 - Specific deletion):
{ "indexName": "default", "identifier": "abc123", "language": 1, "inode": "def456", "contentType": "Blog", "site": "demo.dotcms.com" }
Response Type: application/json
Success Response (200):
{ "deleted": 42 }
Error Responses:
401- User not authenticated500- Internal server error
Example Request:
curl -X 'DELETE' \ 'http://localhost:8082/api/v1/ai/embeddings' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "indexName": "blogIndex", "contentType": "Blog" }'
Count Embeddings (GET)#
Counts embeddings matching filter criteria using query parameters.
Endpoint: GET /v1/ai/embeddings/count
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
site | No | Filter by site/host |
contentType | No | Filter by content type |
indexName | No | Filter by index name |
language | No | Filter by language |
identifier | No | Filter by content identifier |
inode | No | Filter by content inode |
fieldVar | No | Filter by field variable |
Response Type: application/json
Success Response (200):
{ "embeddingsCount": 1543 }
Example Request:
curl -X 'GET' \ 'http://localhost:8082/api/v1/ai/embeddings/count?contentType=Blog&site=demo.dotcms.com&indexName=default' \ -H 'accept: application/json'
Count Embeddings (POST)#
Counts embeddings matching filter criteria using form data.
Endpoint: POST /v1/ai/embeddings/count
Request Body: CompletionsForm (application/json)
Response Type: application/json
Success Response (200):
{ "embeddingsCount": 892 }
Example Request:
{ "contentType": "Blog", "site": "demo.dotcms.com", "indexName": "default", "language": "1", "prompt": "NOT USED" }
Count Embeddings by Index#
Returns count of embeddings grouped by index name with detailed statistics. Requires CMS Administrator role.
Endpoint: GET /v1/ai/embeddings/indexCount
Required Role: CMS_ADMINISTRATOR_ROLE
Response Type: application/json
Success Response (200):
{ "indexCount": { "blogIndex": { "contentTypes": "Activity,Blog,calendarEvent,Image,webPageContent", "contents": 42, "fragments": 91, "tokenTotal": 26797, "tokensPerChunk": 294 }, "products": { "contentTypes": "Product", "contents": 892, "fragments": 1523, "tokenTotal": 45231, "tokensPerChunk": 312 }, "cache": { "contentTypes": "cache", "contents": 1, "fragments": 80, "tokenTotal": 21579, "tokensPerChunk": 269 } } }
Error Responses:
401- User not authenticated403- Insufficient permissions500- Internal server error
Example Request:
curl -X 'GET' \ 'http://localhost:8082/api/v1/ai/embeddings/indexCount' \ -H 'accept: application/json'
Drop and Recreate Embeddings Table#
⚠️ DESTRUCTIVE OPERATION - Drops and recreates the entire embeddings table. Requires CMS Administrator role. Use with extreme care.
Endpoint: DELETE /v1/ai/embeddings/db
Required Role: CMS_ADMINISTRATOR_ROLE
Request Body: {} (empty JSON object)
Response Type: application/json
Success Response (200):
{ "created": true }
Error Responses:
401- User not authenticated403- Insufficient permissions (not CMS Administrator)500- Internal server error
Example Request:
curl -X 'DELETE' \ 'http://localhost:8082/api/v1/ai/embeddings/db' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{}'
Completions Endpoints#
| Path | Method |
|---|---|
/api/v1/ai/completions | POST |
/api/v1/ai/completions/rawPrompt | POST |
/api/v1/ai/completions/config | GET |
Generate AI Completions from Content#
Generates AI-powered summaries and completions based on provided prompts with content preprocessing. This endpoint searches for relevant content and uses it to generate contextually-aware responses.
Endpoint: POST /v1/ai/completions
Request Body: CompletionsForm (application/json)
Response Types:
application/json- Complete response with all metadataapplication/octet-stream- Streaming response (whenstream: true)
Success Response (200 - JSON):
{ "response": "Generated completion text...", "model": "gpt-4", "tokens": 150, "totalTime": "1250ms" }
Success Response (200 - Streaming):
When application/octet-stream is used (typically when stream: true), the response is delivered as a line-by-line text stream. Each chunk of generated text is sent immediately as it becomes available, rather than waiting for the complete response.
Error Responses:
400- Missing or invalid prompt401- User not authenticated500- Internal server error
Example Request:
curl -X 'POST' \ 'http://localhost:8082/api/v1/ai/completions' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "prompt": "where do i vacation?", "threshold": ".2", "searchLimit": 50, "stream": false, "indexName": "blogIndex" }'
The endpoint returns detailed completion data containing the prompt response along with the relevant content matches:
{ "timeToEmbeddings": "860ms", "total": 5, "query": "What's the best place to vacation?", "threshold": 0.25, "dotCMSResults": [ { "identifier": "abc123", "matches": [ { "distance": 0.21085739135742188, "extractedText": "<text excerpt>..." } ] } ], "operator": "<=>", "offset": 0, "limit": 50, "count": 3, "openAiResponse": { "id": "chatcmpl-8rUy56hdxj210olTgFbNfVpxKVQla", "object": "chat.completion", "created": 1707761117, "model": "gpt-3.5-turbo-16k-0613", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Based on the information provided, Fiji would be an excellent destination for a vacation. Fiji is located in the heart of the South Pacific and is blessed with 333 tropical islands. The islands are known for their luxurious..." }, "logprobs": null, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 325, "completion_tokens": 139, "total_tokens": 464 }, "system_fingerprint": null }, "totalTime": "2475ms" }
Get AI Configuration#
Retrieves current AI service configuration including available models, settings, and prompts. This endpoint returns the configuration values visible in the Config Values tab in the dotAI Tool.
Endpoint: GET /v1/ai/completions/config
Response Type: application/json
Success Response (200):
{ "configHost": "demo.dotcms.com (falls back to system host)", "apiUrl": "https://api.openai.com/v1", "apiKey": "*****", "model": "gpt-4", "embeddingsModel": "text-embedding-ada-002", "rolePrompt": "You are a helpful assistant...", "availableModels": [ { "name": "gpt-4", "type": "chat", "maxTokens": 8192 }, { "name": "gpt-3.5-turbo", "type": "chat", "maxTokens": 4096 } ] }
Error Responses:
401- User not authenticated500- Internal server error
Example Request:
curl -X 'GET' \ 'http://localhost:8082/api/v1/ai/completions/config' \ -H 'accept: application/json'
A typical returned object will resemble this:
{ "apiImageUrl": "https://api.openai.com/v1/images/generations", "apiKey": "*****", "apiUrl": "https://api.openai.com/v1/chat/completions", "availableModels": [ "gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4", "gpt-4-1106-preview" ], "com.dotcms.ai.completion.default.temperature": "1", "com.dotcms.ai.completion.model": "gpt-3.5-turbo-16k", "com.dotcms.ai.completion.role.prompt": "You are a helpful assistant with a descriptive writing style.", "com.dotcms.ai.completion.text.prompt": "Answer this question\\n\\\"$!{prompt}?\\\"\\n\\nby using only the information in the following text:\\n\"\"\"\\n$!{supportingContent} \\n\"\"\"\\n", "com.dotcms.ai.debug.logging": "false", "com.dotcms.ai.embeddings.build.for.file.extensions": "pdf,doc,docx,txt,html", "com.dotcms.ai.embeddings.cache.size": "1000", "com.dotcms.ai.embeddings.cache.ttl.seconds": "600", "com.dotcms.ai.embeddings.delete.old.on.update": "true", "com.dotcms.ai.embeddings.minimum.file.size": "1024", "com.dotcms.ai.embeddings.minimum.text.length": "64", "com.dotcms.ai.embeddings.model": "text-embedding-ada-002", "com.dotcms.ai.embeddings.search.default.threshold": ".25", "com.dotcms.ai.embeddings.split.at.tokens": "512", "com.dotcms.ai.embeddings.threads": "3", "com.dotcms.ai.embeddings.threads.max": "6", "com.dotcms.ai.embeddings.threads.queue": "10000", "configHost": "demo.dotcms.com (falls back to system host)", "imageModel": "dall-e-3", "imagePrompt": "Use 3:4 aspect ratio.", "imageSize": "1792x1024", "listenerIndexer": "{\n \"blogIndex\":\"Blog.blogContent\"\n}", "model": "gpt-3.5-turbo-16k", "rolePrompt": "You are dotCMSbot, and AI assistant to help content creators generate and rewrite content in their content management system.", "textPrompt": "Use Descriptive writing style." }
Common Data Models#
CompletionsForm#
Used for completions, search, and text generation requests.
Fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
prompt | string | Yes | - | Query or prompt text (1-4096 chars) |
searchLimit | integer | No | 50 | Max results (1-1000) |
searchOffset | integer | No | 0 | Pagination offset |
responseLengthTokens | integer | No | 0 | Max response length in tokens (min: 128) |
language | long/string | No | default | Language ID or code |
stream | boolean | No | false | Enable streaming response |
fieldVar | string | No | - | Specific field to search/analyze |
indexName | string | No | "default" | Embeddings index name |
contentType | string | No | - | Content type filter (comma-separated) |
threshold | float | No | 0.25 | Similarity threshold (0-1). Higher value results in stricter matching. |
temperature | float | No | config | AI temperature (0-2). Values greater than 2 are clamped to 2. |
model | string | No | config | AI model name |
operator | string | No | "cosine" | Distance operator (distance/cosine/innerProduct) |
site | string | No | - | Site/host filter |
responseFormat | object | No | - | Response format configuration |
Example:
{ "prompt": "Analyze customer feedback trends", "searchLimit": 100, "contentType": "Review,Comment", "temperature": 0.5, "model": "gpt-4", "threshold": 0.7, "stream": false, "responseLengthTokens": 512 }
EmbeddingsForm#
Used for creating and managing embeddings.
Fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | Yes | - | Content query (1-4096 chars) |
limit | integer | No | 1000 | Max items per batch (1-1000) |
offset | integer | No | 0 | Starting offset |
indexName | string | No | "default" | Index name |
model | string | No | config | Embeddings model |
velocityTemplate | string | No | - | Velocity template for content extraction |
fields | string | No | - | Comma-separated field names. Converted to lowercase. |
Example:
{ "query": "+contentType:Blog +live:true", "limit": 500, "offset": 0, "indexName": "default", "model": "text-embedding-ada-002", "fields": "title,body,tags" }
AIImageRequestDTO#
Used for image generation requests.
Fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
prompt | string | Yes | - | Image description |
numberOfImages | integer | No | 1 | Number of images to generate |
size | string | No | "1024x1024" | Image dimensions |
quality | string | No | "standard" | Image quality (standard/hd) |
style | string | No | "natural" | Image style (natural/vivid) |
Example:
{ "prompt": "A peaceful garden with cherry blossoms", "numberOfImages": 1, "size": "1024x1024", "quality": "hd", "style": "vivid" }