---
title: "Generate LLM completion"
method: POST
path: "/completions"
tags: ["completions"]
---

# Generate LLM completion

`POST /completions`

Generates a completion based on the input messages and retrieval chunks. If the 'stream' parameter is set to true, the response is returned as a stream of plain text (text/plain).

Required roles: All, App

## Request body

- object
  - `messages` object[], required — The messages to generate completion for
    - `role` 'system' | 'user' | 'assistant', required — The role of the message sender
    - `content` string, required — The content of the message
  - `stream` boolean — Whether to stream the response. If true, the response is sent as a stream using the 'text/plain' content type.
  - `citation` boolean — Whether to include citations in the response
  - `grounding` boolean — Whether to enable Gemini's Google Search grounding during answer generation. Only effective when the completion model is a Gemini model and the `gemini_grounding` feature is enabled on the server; otherwise this flag is ignored.
  - `tags` string[] — target tag names to be obtained
  - `tag_ids` string[] — target tag IDs to be obtained
  - `tag_filter_logic` 'AND' | 'OR' — Logical operator for combining filter conditions
  - `source_types` SourceType[]
  - `file_types` FileType[]
  - `date_from` integer — Start date for content search (Unix timestamp in seconds)
  - `date_to` integer — End date for content search (Unix timestamp in seconds)
  - `domains` string[] — Array of domains to search within (supports partial matching)
  - `metadata` MetadataFilterGroup — (reserved for future use) Filter group with nested structure. Supports combining filters with AND/OR logic.
    - `logic` 'AND' | 'OR' — Logical operator for combining filter conditions
    - `filters` MetadataFilter[] — Filters within this group (combined using the logic operator)
      - `key` string, required — Metadata key
      - `val` unknown
      - `type` 'string' | 'integer' | 'float' | 'date' | 'datetime', required — Data type of the metadata value
      - `operator` 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'between', required — Comparison operator
      - `min` unknown
      - `max` unknown
    - `groups` MetadataFilterGroup[] — Nested subgroups
  - `source_metadata` MetadataFilterGroup — (reserved for future use) Filter group with nested structure. Supports combining filters with AND/OR logic.
    - `logic` 'AND' | 'OR' — Logical operator for combining filter conditions
    - `filters` MetadataFilter[] — Filters within this group (combined using the logic operator)
      - `key` string, required — Metadata key
      - `val` unknown
      - `type` 'string' | 'integer' | 'float' | 'date' | 'datetime', required — Data type of the metadata value
      - `operator` 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'between', required — Comparison operator
      - `min` unknown
      - `max` unknown
    - `groups` MetadataFilterGroup[] — Nested subgroups
  - `chunk_metadata` MetadataFilterGroup — (reserved for future use) Filter group with nested structure. Supports combining filters with AND/OR logic.
    - `logic` 'AND' | 'OR' — Logical operator for combining filter conditions
    - `filters` MetadataFilter[] — Filters within this group (combined using the logic operator)
      - `key` string, required — Metadata key
      - `val` unknown
      - `type` 'string' | 'integer' | 'float' | 'date' | 'datetime', required — Data type of the metadata value
      - `operator` 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'between', required — Comparison operator
      - `min` unknown
      - `max` unknown
    - `groups` MetadataFilterGroup[] — Nested subgroups
  - `metadata_filter` MetadataFilterGroup — (reserved for future use) Filter group with nested structure. Supports combining filters with AND/OR logic.
    - `logic` 'AND' | 'OR' — Logical operator for combining filter conditions
    - `filters` MetadataFilter[] — Filters within this group (combined using the logic operator)
      - `key` string, required — Metadata key
      - `val` unknown
      - `type` 'string' | 'integer' | 'float' | 'date' | 'datetime', required — Data type of the metadata value
      - `operator` 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'between', required — Comparison operator
      - `min` unknown
      - `max` unknown
    - `groups` MetadataFilterGroup[] — Nested subgroups
  - `use_postfilter` boolean — Whether to bypass LanceDB prefilter and apply WHERE after the vector search (IVF_PQ) returns top-K. Significantly faster for broad filters that cover most of the table, but may return fewer than `limit` results when the hit rate is low.
  - `limit` integer — Maximum number of chunks to retrieve as context for completion
  - `authz_policy` string — (reserved for future use) Name of the registered authz policy to evaluate when retrieving context. Defaults to the reserved "default" policy when omitted. Ignored when authz is disabled.
  - `principal_id` string — Identifier of the end-user (principal) on whose behalf this request is made. Used to look up the principal's authz subject attributes for policy evaluation. When omitted, subject attributes are empty (most restrictive). Ignored when authz is disabled.
  - `conversation_id` string — Conversation to append this turn to. When omitted, a new conversation is created server-side and its id is returned (response body for JSON, the X-Conversation-Id header for streaming). Pass it back on subsequent turns so the answer is persisted into the same conversation history tree. When set, the past conversation is rebuilt server-side from the stored tree, so only the latest user message in `messages` is used as the new input (earlier `messages` entries are ignored). Retrieval uses that latest question.
  - `parent_message_id` string — Id of the message node to branch this turn from (the parent of the new user message). When omitted, the turn continues from the conversation's current active leaf. Set it to fork a branch (e.g. editing an earlier question). Must belong to conversation_id.
  - `regenerate` boolean — When true, the latest user message is NOT persisted again; instead a new assistant answer is created as a sibling under parent_message_id (which must reference an existing user message). Used to regenerate an answer.
  - `truncation` 'auto' | 'disabled' — How to handle a reconstructed conversation that exceeds the model's context budget (only relevant when conversation_id is set, i.e. history is rebuilt server-side). "auto": drop the oldest turns until it fits (the latest question is always kept). "disabled": return 400 if it does not fit.

## Response `200`

Successful completion. If the 'stream' parameter is false, the response is returned as application/json. If the 'stream' parameter is true, the response is returned as a stream of plain text (text/plain).

- object
  - `created` integer, required — The Unix timestamp (in seconds) of when the completion was created
  - `conversation_id` string, nullable — Target conversation id. For an existing conversation (conversation_id was supplied) it is always returned, even if this turn's answer was not persisted. For a new conversation it is null when nothing was persisted (e.g. no answer generated, or the history write failed).
  - `user_message_id` string, nullable — Id of the persisted user message node for this turn. Null when the turn was not persisted.
  - `assistant_message_id` string, nullable — Id of the persisted assistant message node (the new active leaf). Null when no assistant node was persisted.
  - `choices` object[], required — The completion choices generated by the model
    - `index` integer, required — The index of this completion choice
    - `message` object, required
      - `role` 'assistant', required — The role of the message sender
      - `content` string, required — The content of the message
    - `finish_reason` string, required — The reason why the model stopped generating tokens
    - `citations` Content[] — Array of search results
      - `id` string, required — Content ID
      - `text` string, required — Content chunk from the source
      - `url` string, required — Source URL of the content
      - `title` string, required — Title of the content or document
      - `timestamp` integer, required — Unix timestamp when the content was indexed
      - `file_type` 'html' | 'pdf' | 'ppt' | 'pptx' | 'pptm' | 'doc' | 'docx' | 'docm' | 'xls' | 'xlsx' | 'xlsm' | 'md' | 'txt' | 'jsonl' | 'png' | 'jpg' | 'webp' | 'heic' | 'heif' | 'wav' | 'mp3' | 'aiff' | 'aac' | 'm4a' | 'ogg' | 'flac' | 'mp4' | 'mpg' | 'mov' | 'avi' | 'flv' | 'webm' | 'wmv' | '3gp' | 'notion_page', required — The type of the source file
      - `page_number` integer, required — Page number for paginated documents like PDFs. Set to 0 for sources without page numbers
      - `source_type` 'crawl' | 'local_file' | 'google_drive' | 'github' | 'notion', required — The type of the source
      - `source_id` string — Optional source ID for the original source. For crawl content, use this value with GET /sources/{source_id}/raw to download the stored crawl file content. For local_file content, use GET /sources/{source_id} for source details.
      - `keywords` string[]
    - `web_citations` WebCitation[] — Web sources from Gemini's Google Search grounding, returned separately from `citations`. Present only when grounding was enabled and the model used web results.
      - `url` string, required — URL of the grounded web source
      - `title` string, required — Title of the grounded web source
    - `search_suggestion` string — Google Search Suggestions HTML (searchEntryPoint.renderedContent) from Gemini grounding. Per Google's "Grounding with Google Search" terms, clients MUST display this content as provided whenever it is present. Present only when grounding produced search suggestions.
    - `web_search_queries` string[] — The Google Search queries Gemini issued for grounding. Present only when grounding was used.

## Other responses

- `400` — Bad Request - The request was malformed or invalid
- `401` — Unauthorized - Authentication failed
- `403` — Forbidden - Insufficient permissions
- `429` — Too Many Requests - Rate limit exceeded
- `500` — Internal Server Error

---

[API](https://skmtc.net/qlonolink/apis/qaip-apis.md) · [All operations](https://skmtc.net/qlonolink/apis/qaip-apis/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/qlonolink/qaip-apis/versions/f5f5994dfe05/schema)
