---
title: "Open Dm Thread"
method: POST
path: "/api/threads/open-dm"
tags: ["threads", "threads"]
---

# Open Dm Thread

`POST /api/threads/open-dm`

## Request

- Base URL: `https://api.dialogbrain.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.dialogbrain.com/api/threads/open-dm`
- Auth: none declared

Open the DM with one participant of a group, on ANY channel.

Clicking a sender's name in a group must land the operator in a chat they
can type into. Three steps, in order:

1. The thread already exists → return it. (Every channel.)
2. The channel can fetch an existing remote dialog → do that, so the
   operator also gets the history. (Telegram only, see above.)
3. Otherwise create an EMPTY local DM thread.

Step 3 is the point of this endpoint. Before it existed the handler bailed
out with `if channel != "telegram": return {"thread": None}`, and the UI
told the operator "No conversation history with this contact" — true, but
useless: they wanted to START the conversation, not read it.

A locally-created thread is not a phantom: it carries the real
(channel_account_id, channel_ref) pair, so the first inbound message from
that contact lands in this very row rather than spawning a second one.
Whether the FIRST OUTBOUND send is permitted is the channel's business
(Zalo may refuse a non-friend, Facebook enforces its 24h window) — the send
then fails loudly with the channel's own reason, which is far more useful
than refusing to open the chat at all.

## Request body

- OpenDmRequest
  - `channel_ref` string, required
  - `channel_account_id` string, required
  - `title` string, nullable

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/dialogbrain/apis/dialogbrain-v2-api-gateway.md) · [All operations](https://skmtc.dev/dialogbrain/apis/dialogbrain-v2-api-gateway/llms.txt) · [OpenAPI document](https://skmtc.dev/dialogbrain/apis/dialogbrain-v2-api-gateway/revisions/77bef09a9209?raw)
