---
title: "Create a new thread for a user"
method: POST
path: "/v1/user/{userId}/threads/"
tags: ["/v1/user"]
---

# Create a new thread for a user

`POST /v1/user/{userId}/threads/`

## Request

- Base URL: `https://api.counselhealth.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.counselhealth.com/v1/user/{userId}/threads/`
- Auth: HTTP bearer

Creates a new thread for the specified user and returns the full thread object (same shape as GET by id). The thread_id field is included for backwards compatibility and can be passed to the signedAppUrl endpoint via the open_thread action.

Responds **201** when a thread was created and **200** when an existing unused thread was returned instead, so a repeated call does not accumulate empty threads. Reuse is enabled per organization and never happens when `initial_messages` are supplied.

## Path parameters

- `userId` string, required

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `module` string
  - `initial_messages` object[]
    - `body` string, required
    - `role` 'patient' | 'model'
  - `agent_context` object
  - `metadata` object: Custom key-value metadata for threads. Max 25 keys, each value ≤ 1800 characters. Keys must be alphanumeric with underscores/hyphens only.

## Response `200`

No thread was created — an existing unused thread matching this request (same module, smart pill, `metadata` and `agent_context`, with no messages from the user) was returned instead. Enabled per organization; requests that seed `initial_messages` always create.

- object: No thread was created — an existing unused thread matching this request (same module, smart pill, `metadata` and `agent_context`, with no messages from the user) was returned instead. Enabled per organization; requests that seed `initial_messages` always create.
  - `id` string, uuid, required
  - `patient_id` string, uuid, required
  - `mode` 'AI' | 'PHYSICIAN', required
  - `display_name` string, nullable, required
  - `module` 'get_advice' | 'order_lab' | 'refill_medication' | 'review_my_results' | 'get_care' | 'lifestyle_conditions' | 'get_care_quickly' | 'symptom_radar' | 'review_lab_results' | 'bp_signals' | 'cycle_insights' | 'cycle_insights_ttc' | 'optimize_lifestyle' | 'get_treatment', nullable, required: The chat module the thread is in. Nullable as chats started with a set of messages may have no module. May change over the life of the thread; a change emits `thread.updated`.
  - `status` 'unclaimed' | 'assigned' | 'active' | 'closed', required
  - `created_at` string, date-time, required
  - `last_activity_time` string, date-time, required
  - `expires_at` string, date-time, nullable, required
  - `updated_at` string, date-time, required
  - `terminated_at` string, date-time, nullable, required
  - `termination_reason` 'emergency' | 'malicious_action', nullable, required
  - `sla_start_at` string, date-time, nullable
  - `metadata` object, nullable: Custom key-value metadata for threads. Max 25 keys, each value ≤ 1800 characters. Keys must be alphanumeric with underscores/hyphens only.
  - `thread_id` string, uuid

## Other responses

- `201`: A new thread was created. Returned whenever the request seeds `initial_messages`, or the user has no matching unused thread.
- `400`: 400 error with a machine-readable `code` for client branching.
- `401`: Standard error body returned for non-2xx responses.
- `403`: Standard error body returned for non-2xx responses.
- `404`: Standard error body returned for non-2xx responses.
- `409`: Standard error body returned for non-2xx responses.
- `413`: Standard error body returned for non-2xx responses.
- `429`: Standard error body returned for non-2xx responses.
- `500`: Standard error body returned for non-2xx responses.
- `502`: Default Response
- `503`: Default Response
- `504`: Default Response

---

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