---
title: "Open a conversation"
method: POST
path: "/v1/projects/{project_id}/channels/{channel_id}/conversations"
tags: ["Channels"]
---

# Open a conversation

`POST /v1/projects/{project_id}/channels/{channel_id}/conversations`

## Request

- Base URL: `https://api.naturali.ai`
- URL: `https://api.naturali.ai/v1/projects/{project_id}/channels/{channel_id}/conversations`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.naturali.ai/authorize`, token URL `https://api.naturali.ai/token`, scopes: `mcp:access`)

The outbound-first path: open a conversation for an `identifier` ahead of any inbound message, which falls out of making the identifier the unit rather than the message. Resolves the same three-layer action an inbound would; a `409` when that does not land on an agent — there is nothing to open for a `message`/`silence` outcome.

## Request body

- object
  - `identifier` string, required: The address identifier, in this channel's kind (`whatsapp:dm:<phone>`, `discord:dm:<user_id>`); any other form is `400`.

## Response `201`

Conversation opened (or already existing).

- Conversation: An address's dialogue on a channel — naturali-native, keyed by (channel, address) so the same identifier never opens two conversations, and mapped 1:1 to the runtime session that carries the message history.
  - `id` string, required
  - `project_id` string, required
  - `channel_id` string, required
  - `address_id` string, required: The address the dialogue arrived at — the continuity key.
  - `route_id` string, required: The route this conversation's action came from — a real route id, or one of the two sentinels for "the address's own action" / "the channel default" (CHANNELS-ROUTING.md §3.8). A message resolving to a different action opens a new conversation rather than re-pointing this one.
  - `identifier` string, nullable, required: The prefixed, self-describing channel identifier (`whatsapp:dm:…`, `discord:dm:…`, `discord:thread:…`). Read through from the address above.
  - `actor_id` string, nullable, required: The runtime actor the address speaks as. Null when the address has not needed one yet.
  - `session_id` string, required: The runtime session this conversation maps 1:1 to.
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required

## Other responses

- `400`: The request was malformed or failed validation.
- `401`: Missing or invalid credentials.
- `403`: The credential is scoped to a different project, or the caller's role in the project does not carry this action.
- `404`: The resource does not exist (existence is not leaked).
- `409`: The request conflicts with the resource's current state.
- `502`: The upstream runtime, or Meta, could not complete the operation.

---

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