Summary of all REST API endpoints exposed by uxopian-ai. All endpoints are accessible via the gateway at the configured base path. An interactive API explorer (Swagger UI) is available at /swagger-ui/index.html.
Since 2026.0.0-ft4, every non-2xx response returns a structured JSON body instead of a plain-text message:
{ "code":"LLM_PROVIDER_NOT_FOUND", "message":"LLM provider 'xyz' not found.", "status":404 }
Field
Type
Description
code
string
Stable, machine-readable error code
message
string
Human-readable description
status
number
HTTP status code (also reflected in the response status line)
Common error codes and their HTTP status:
code
Status
Raised when
BAD_REQUEST
400
Malformed or invalid request
LLM_BAD_REQUEST
400
The LLM rejected the request
MISSING_TENANT
400
No tenant resolved from the request
MISSING_USER
400
No user resolved from the request
UNAUTHORIZED
401
Authentication/authorization failed (e.g. requesting an undeployed script)
NOT_FOUND / FILE_NOT_FOUND / RESOURCE_NOT_FOUND
404
Entity, file, or resource not found
LLM_PROVIDER_NOT_FOUND
404
Referenced LLM provider does not exist
MCP_SERVER_NOT_FOUND
404
Referenced MCP server does not exist
NOT_IMPLEMENTED
405
Operation not supported
CONFLICT
409
Duplicate entity (e.g. creating an LLM provider or script with an existing ID)
LLM_CAPABILITY_ERROR
422
The selected model lacks a required capability (multimodal, function calling)
TOOL_CYCLES_EXCEEDED
422
The tool-calling loop exceeded its maximum number of cycles
SCAN_CONFIGURATION_ERROR
422
The script security scan is not configured
OPENSEARCH_UNAVAILABLE
503
OpenSearch is unreachable
INTERNAL_ERROR
500
Unhandled server error
Migrating from a previous version
Clients that previously parsed the plain-text error body must now read the message field from the JSON object. Some statuses also changed — notably, creating a duplicate LLM provider now returns 409 Conflict (previously 400).
Download a temporary file by its key (files produced by a tool or an agent run).
There is no upload endpoint: files and images enter a conversation as base64 content items on a request ({ "type": "image", "value": "<base64>" }), not through a separate POST.
Since 2026.0.0-ft5, a prompt is one document holding a version history with an explicit draft → publish lifecycle — see Managing prompts for what that lifecycle means in the admin UI.
The prompt itself:
Method
Path
Description
GET
/api/v1/admin/prompts
List all prompts for the current tenant.
POST
/api/v1/admin/prompts
Create a new prompt with its initial version, v0 (201). 409 if a prompt with the same ID exists.
GET
/api/v1/admin/prompts/{id}
Get the prompt aggregate — {id, versions: [...]} — by ID.
GET
/api/v1/admin/prompts/{id}/render
Render the active version, or the one given by ?version=. Takes an optional JSON payload in the request body (Map<String, Object>).
GET
/api/v1/admin/prompts/{id}/statistics
Get usage statistics for a prompt, aggregated across all versions.
GET
/api/v1/admin/prompts/{id}/usage
Whether the prompt is deletable, and which Applications reference it.
GET
/api/v1/admin/prompts/categories
List distinct Quick Prompt categories currently in use.
DELETE
/api/v1/admin/prompts/{id}
Delete a prompt and all of its versions (204). 409 if it's a base prompt or referenced by an Application.
Versions — the draft → publish lifecycle:
A prompt has at most one draft at a time, and the draft is the only writable version: every published version is read-only, and any write targeting one is rejected with 409 Conflict.
Method
Path
Description
GET
/api/v1/admin/prompts/{id}/versions
List every version of the prompt, ordered by version number.
GET
/api/v1/admin/prompts/{id}/versions/{version}
Get one specific version.
POST
/api/v1/admin/prompts/{id}/versions
Create the draft — the next version (201). 409 if a draft already exists.
PUT
/api/v1/admin/prompts/{id}/versions/{version}
Edit the draft (draft:true in the body) or publish it (draft:false). 409 if the target isn't the draft.
DELETE
/api/v1/admin/prompts/{id}/versions/{version}
Discard the draft (204), keeping published versions intact. 409 if the target isn't the draft.
Publishing archives the previously-published version rather than deleting it, so restoring an older wording means re-publishing its content as a new version — there is no endpoint that reactivates an old version number in place. A draft can also be exercised by real callers before it goes live, by setting version on a type: prompt content item in a normal request (see Conversations and requests).