2026.20 Public API / SDK Changes
5 min read
Heads Up – New API Version Coming Soon
We want to inform you that a new version of the Public API is currently in development. No action is required on your end at this time - we will provide full documentation and a clear adoption timeline ahead of any changes.
What's changing?
Enforced role-based access control (RBAC)
Stricter request validation
Public API
New Endpoints
Analytics
Kong Plugin Upgrade Required
The analytics endpoints are only available for clients who have upgraded to the latest Kong plugin ( >1.3.0). This is already the case for Single-Tenant (ST) and Multi-Tenant (MT) deployments. For Customer-Managed-Tenant (CMT) deployments this must be verified — and it will only work if the CMT avoids hair-pinning. CMTs that use hair-pinning will not be able to use these endpoints, because the endpoints are now protected by roles retrieved from Zitadel.
Required Role: chat.feedback.read or chat.data.admin
Supported analytics types: ACTIVE_USER, CHAT_INTERACTION, CHAT_INTERACTION_DETAILED, REFERENCE_STAT, INGESTION_STAT, PRODUCT_METRICS, MODEL_USAGE, NPS, USER_CHAT_EXPORT
tech Create Order — create and start an analytics report order.
Body
type(AnalyticsType enum, required) — report type (see supported types above)start_date(string, required) — report start date in ISO 8601 format (e.g."2024-01-01")end_date(string, required) — report end date in ISO 8601 format (e.g."2024-12-31")assistant_id(string, optional) — filter the report to a specific assistant
Example
curl --location 'https://api.uat1.unique.app/public/analytics/orders' \
--header 'x-user-id: <user-id>' \
--header 'x-company-id: <company-id>' \
--header 'Authorization: Bearer <api-key>' \
--header 'x-app-id: <app-id>' \
--header 'x-api-version: 2026-03-01' \
--header 'Content-Type: application/json' \
--data '{
"type": "CHAT_INTERACTION",
"start_date": "2024-01-01",
"end_date": "2024-12-31"
}'tech List Orders — list all analytics orders for the company.
Query
skip(number, optional, default0) — number of orders to skiptake(number, optional, default20, max100) — number of orders to return
Example
curl --location 'https://api.uat1.unique.app/public/analytics/orders?skip=0&take=20' \
--header 'x-user-id: <user-id>' \
--header 'x-company-id: <company-id>' \
--header 'Authorization: Bearer <api-key>' \
--header 'x-app-id: <app-id>' \
--header 'x-api-version: 2026-03-01'tech Get Order — fetch a single order by ID; use this to poll for completion.
Example
curl --location 'https://api.uat1.unique.app/public/analytics/orders/<order-id>' \
--header 'x-user-id: <user-id>' \
--header 'x-company-id: <company-id>' \
--header 'Authorization: Bearer <api-key>' \
--header 'x-app-id: <app-id>' \
--header 'x-api-version: 2026-03-01'tech Download Results — download the completed analytics report as a CSV file. The order must be in DONE state. Returns 422 if the order is still processing.
Example
curl --location 'https://api.uat1.unique.app/public/analytics/orders/<order-id>/download' \
--header 'x-user-id: <user-id>' \
--header 'x-company-id: <company-id>' \
--header 'Authorization: Bearer <api-key>' \
--header 'x-app-id: <app-id>' \
--header 'x-api-version: 2026-03-01' \
--output analytics_report.csvtech Delete Order — delete an analytics order by ID
Example
curl --location --request DELETE 'https://api.uat1.unique.app/public/analytics/orders/<order-id>' \
--header 'x-user-id: <user-id>' \
--header 'x-company-id: <company-id>' \
--header 'Authorization: Bearer <api-key>' \
--header 'x-app-id: <app-id>' \
--header 'x-api-version: 2026-03-01'Briefings
Briefings let integration partners attach a markdown narrative and a set of suggested prompts to an assistant. When the FEATURE_FLAG_ENABLE_NARRATIVE_SUGGESTED_PROMPTS_UN_19396 flag is enabled, the chat web app renders the briefing on the chat welcome view of any assistant that has one attached.
Required Role: chat.admin (briefing READ, WRITE, DELETE, MANAGE). chat.user and space admins have READ only.
tech Upsert Briefing — create or update the briefing attached to an assistant. Sending a new prompts array fully replaces the previous one; the array order becomes the displayed order.
Path
assistantId(string, required, max 255 chars) — identifier of the assistant the briefing should be attached to. Used as the briefing's external id.
Body
title(string, optional, max 100 chars) — display title shown above the briefing in the chat UI. Omit to use the default copy ("Today's Briefing").text(string, required, max 4,000 chars) — markdown briefing body.generatedAt(string, required, ISO-8601) — timestamp when the briefing was generated by the integration partner.prompts(array, required, max 200 items) — full replacement set of suggested prompts. Each item has:title(string, required, max 100 chars)body(string, required, max 4,000 chars)
Example
curl --location --request DELETE 'https://api.uat1.unique.app/public/briefings/' \
--header 'x-user-id: <user-id>' \
--header 'x-company-id: <company-id>' \
--header 'Authorization: Bearer <api-key>' \
--header 'x-app-id: <app-id>' \
--header 'x-api-version: 2026-03-01'tech Get Briefing — fetch the briefing currently attached to an assistant. Returns 404 if no briefing is attached.
Path
assistantId(string, required) — identifier of the assistant whose briefing should be returned.
Example
curl --location 'https://api.uat1.unique.app/public/briefings/' \
--header 'x-user-id: <user-id>' \
--header 'x-company-id: <company-id>' \
--header 'Authorization: Bearer <api-key>' \
--header 'x-app-id: <app-id>' \
--header 'x-api-version: 2026-03-01'tech Detach Briefing — detach the briefing from the assistant. The underlying briefing record is preserved when other assistants in the same tenant still reference it; the response confirms the per-assistant detach. Returns 404 if no briefing is attached.
Path
assistantId(string, required) — identifier of the assistant whose briefing should be detached.
Example
curl --location --request DELETE 'https://api.uat1.unique.app/public/briefings/' \
--header 'x-user-id: <user-id>' \
--header 'x-company-id: <company-id>' \
--header 'Authorization: Bearer <api-key>' \
--header 'x-app-id: <app-id>' \
--header 'x-api-version: 2026-03-01'SDK
New Functions
Analytics
Kong Plugin Upgrade Required
The analytics endpoints are only available for clients who have upgraded to the latest Kong plugin ( >1.3.0). This is already the case for Single-Tenant (ST) and Multi-Tenant (MT) deployments. For Customer-Managed-Tenant (CMT) deployments this must be verified — and it will only work if the CMT avoids hair-pinning. CMTs that use hair-pinning will not be able to use these endpoints, because the endpoints are now protected by roles retrieved from Zitadel.
tech unique_sdk.AnalyticsOrder.create — create and start an analytics order (see supported types above in the beginning of the Public API section)
Example
order = unique_sdk.AnalyticsOrder.create(
user_id=user_id,
company_id=company_id,
type="CHAT_INTERACTION",
startDate="2024-01-01",
endDate="2024-12-31",
)tech unique_sdk.AnalyticsOrder.list — list analytics orders for the company, sorted by creation date descending
Example
orders = unique_sdk.AnalyticsOrder.list(
user_id=user_id,
company_id=company_id,
skip=0,
take=20,
)tech unique_sdk.AnalyticsOrder.retrieve — fetch a single order by ID; use this to poll for status changes.
Example
order = unique_sdk.AnalyticsOrder.retrieve(
user_id=user_id,
company_id=company_id,
order_id="ord_abc123",
)tech unique_sdk.AnalyticsOrder.delete — delete an analytics order by ID.
Example
deleted = unique_sdk.AnalyticsOrder.delete(
user_id=user_id,
company_id=company_id,
order_id="ord_abc123",
)tech unique_sdk.AnalyticsOrder.download — download the CSV content of a completed order; order must be in DONE state.
Example
csv_content = unique_sdk.AnalyticsOrder.download(
user_id=user_id,
company_id=company_id,
order_id="ord_abc123",
)tech Analytics Order Run Utility — run_analytics_order async helper handles the full create → poll → download workflow in one call
Example
import asyncio
from unique_sdk.utils.analytics_order_run import run_analytics_order
async def main():
result = await run_analytics_order(
user_id=user_id,
company_id=company_id,
type="CHAT_INTERACTION",
start_date="2024-01-01",
end_date="2024-12-31",
save_csv_to="./report.csv",
)
print(result["order"]["state"]) # "DONE"
print(result.get("csv_path")) # "./report.csv"
asyncio.run(main())