---
title: "Create a VetsGPT chat"
method: POST
path: "/workspaces/{workspaceId}/vetsgpt/chats"
tags: ["vetsgpt"]
---

# Create a VetsGPT chat

`POST /workspaces/{workspaceId}/vetsgpt/chats`

## Request

- Base URL: `https://vetnio.com/api/v2`
- URL: `https://vetnio.com/api/v2/workspaces/{workspaceId}/vetsgpt/chats`
- Auth: HTTP bearer

Creates an empty VetsGPT chat owned by the calling user, optionally with consultation and patient context. Create a chat first when the first message carries file attachments, because upload URLs are issued per chat. Not idempotent: each call creates a new chat.

## Path parameters

- `workspaceId` string, required: Identifier of the workspace (clinic). The caller must be a member, and VetsGPT must be enabled for them in this workspace.

## Request body

- object
  - `title` string: Initial title. Defaults to `New Chat <date>`. VetsGPT replaces it with a generated title after the first message on a topic unless you set it later with the update endpoint.
  - `consultationIds` string[]: Consultations to attach as context (up to 50). Each must be readable by the caller, otherwise `404` (the chat is still created).
  - `patientId` string: Patient to attach as context. Used only while no consultations are attached. Not validated; an unknown id gives no context.

## Response `200`

The created VetsGPT chat.

- object
  - `chat_id` string, required: Chat id (UUID). Use it as `chatId` in the other VetsGPT endpoints.
  - `user_id` string, required: Id of the Vetnio user who owns the chat, i.e. the caller.
  - `workspace_id` string, required: Workspace the chat belongs to.
  - `title` string, required: Chat title. Without a supplied title the server stores `New Chat <date>` (date in the server's locale format). Either way, a short generated title replaces it in the background after the first message on a topic, unless the title is set with the update endpoint first.
  - `created_at` string, required: When the chat was created (ISO-8601 UTC).
  - `last_updated_at` string, required: When the chat last changed (ISO-8601 UTC).
  - `messages` object[], required: Messages in the chat, oldest first. Always empty for a newly created chat.
    - `message_id` string, required: Message id, unique within the chat. Use it with the feedback endpoint.
    - `timestamp` string, required: When the message was stored (ISO-8601 UTC).
    - `type` 'user_message' | 'bot_message', required: Who wrote the message: - `user_message` — the vet. - `bot_message` — VetsGPT.
    - `content` object, required: Text and attachments of a stored VetsGPT message.
      - `text` string, required: Message text. Assistant answers are Markdown with inline source citations (see the ask endpoint).
      - `attachments` string[]: Files attached to a user message. The messages endpoint returns each file inline as a base64 data URI (`data:<mime>;name=<url-encoded file name>;base64,<bytes>`), which can make responses large; files that can no longer be read are left out. Absent when the message has no attachments.
    - `feedback` 'positive' | 'negative' | 'none', required: The vet's rating of the message: - `positive` — rated helpful (thumbs up). - `negative` — rated unhelpful (thumbs down). - `none` — not rated, or the rating was cleared.
    - `isAttachmentAnalysis` boolean: Internal marker for hidden messages that hold VetsGPT's analysis of uploaded files. Such messages are filtered out of the messages endpoint, so REST clients do not normally see this field.
    - `copilotProposals` object[]: Edits to a consultation's clinical note or client communication that VetsGPT proposed while the vet chatted from the consultation page in the web app. Absent for chats that never used the consultation editor. Informational for REST clients; proposals can only be applied in the web app.
      - `proposalId` string, required: Id of the proposal, unique within the message.
      - `tool` 'edit_clinical_note' | 'edit_communication', required: The editing tool VetsGPT used: - `edit_clinical_note` — edits the consultation's clinical note. - `edit_communication` — edits the consultation's client communication.
      - `target` 'clinical_note' | 'communication', required: Which document the edit applies to: - `clinical_note` — the clinical note. - `communication` — the client communication.
      - `summary` string, required: Short description of the change shown to the vet (up to 300 characters).
      - `operation` union, required: The edit itself, discriminated by `kind`: `patch` carries `edits` (1 to 20 `{find, replace}` pairs of lines in the document's HTML); `replace_all` carries `html`, the complete new document.
        - object
          - `kind` 'patch', required
          - `edits` object[], required
            - `find` string, required: The line, or the consecutive lines, being replaced — their text exactly as it reads in the current content, one per <br />.
            - `replace` string, required: What those lines become. Empty removes them.
        - object
          - `kind` 'replace_all', required
          - `html` string, required
      - `source` 'consultation' | 'vetsgpt_knowledge': Where the content of the edit came from: - `consultation` — this consultation's data. - `vetsgpt_knowledge` — VetsGPT's own veterinary knowledge, flagged to the vet for review. Absent on older proposals, which count as `consultation`.
      - `mode` 'auto' | 'manual', required: How the vet had VetsGPT apply edits when the proposal was made: - `auto` — applied immediately ("Write it"). - `manual` — waits for the vet to accept ("Ask first").
      - `baseHash` string, required: Fingerprint of the document version the edit was written against. Used to detect that the document changed since.
      - `status` 'pending' | 'applied' | 'accepted' | 'rejected' | 'undone' | 'stale', required: Review state of the proposal: - `pending` — waiting for the vet. - `applied` — applied automatically. - `accepted` — accepted by the vet and applied. - `rejected` — declined by the vet. - `undone` — applied, then reverted. - `stale` — could not be applied because the document changed (shown as Outdated).
  - `searchable_content` string: Plain-text log of message text (questions, extracted file text and most answers) that the list endpoint's search matches against. Not intended for display. Absent on a new chat.
  - `sharing` object, required: Owner and effective sharing summary; underlying clinical source access is not granted by chat sharing.
    - `permission` 'owner' | 'view' | 'contribute', required: The current actor's effective permission for this chat.
    - `owner` object, required: The chat's owner identity.
      - `id` string, required: User ID of the chat owner; grants do not transfer ownership.
      - `name` string, nullable, required: Owner display name, or null when unavailable.
    - `isShared` boolean, required: Whether at least one current workspace member has an explicit grant.
    - `recipientCount` number, required: Number of current explicitly granted recipients, excluding the owner.
    - `firstRecipientName` string, nullable, required: First recipient display name for a compact sharing summary, or null.

## Other responses

- `400`: Invalid input data
- `401`: Authorization not provided
- `403`: Insufficient access
- `500`: Internal server error

---

[API](https://skmtc.dev/vetnio/apis/vetnio-api.md) - [All operations](https://skmtc.dev/vetnio/apis/vetnio-api/llms.txt) - [OpenAPI document](https://skmtc.dev/vetnio/apis/vetnio-api/revisions/d004afd5617d?raw)
