Update a chat
Patch an Extract chat title or workflow.
workflow_type. A non-extract-* workflow is 400 — the thread cannot leave Extract. Empty body is a no-op.Authorizations
Organisation API key from Settings → API / /api/keys/. The secret is
shown once. Send Authorization: Bearer sk-abacus-…. One active key
per organisation. Ingest (/api/v2/ingest/*) refuses API keys — that
surface is Auth0-only with ingest:read / ingest:write scopes.
Path Parameters
Body
Body for PATCH /api/v2/chats/<thread_id>/.
Both fields optional — a PATCH may update the title, the workflow type, or both. An empty body is a no-op that returns the unchanged chat.
Fields:
title: New chat title (1-255 chars).
workflow_type: New Extract workflow slug. Validated against the Extract
whitelist in the view — a non-Extract value (e.g. flipping the chat
to document-intelligence) is rejected with 400 so the chat can
never escape the Extract surface, matching the Phase 2
set_chat_workflow guard.
Response
Response shape for a single chat (list item AND detail).
A plain Serializer (not ModelSerializer) because the
*_count fields are queryset annotations, not model fields — the
view layers them on via
:func:deckmonkey.api_v2.chats.views._annotated_chat_qs (one query,
no per-row N+1). DRF reads each field as an attribute off the model
instance, so the annotations surface transparently alongside the
real columns.
Fields:
id / thread_id / title / workflow_type / created_at / updated_at /
is_active: straight off the Chat row.
message_count: ChatMessage rows in the thread.
batch_count: attached batches (ChatBatchAttachment join rows).
attachment_count: documents uploaded directly into this chat
(ChatAttachment rows whose chat is this chat).
linked_count: documents linked in from another chat
(ChatAttachmentLink rows) — Decision 8 LINK semantics.

