Ir al contenido

Send Message

Ver como Markdown
POST
/public/v1/conversations/{conversation_id}/messages
curl --request POST \
--url https://api.nuntius.chat/public/v1/conversations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/messages \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <X-API-Key>' \
--data '{ "content": "example" }'

Send a free-text message into an existing conversation (SPEC_API_PUBLICA.md §2.3).

Foreign/unknown conversationId -> 404, zero persistence. For a whatsapp conversation, the contact’s 24h session window is checked FIRST, via the SAME SessionWindowStore every other proactive-send path in this codebase already consults – closed (or no linked channel identity to check at all, fail-closed) -> 409 WHATSAPP_SESSION_WINDOW_CLOSED, with NOTHING written and NO attempt to resolve a channel adapter or reach the provider (closes the gap the internal POST /conversations/{id}/ messages leaves open, this module’s own docstring). Every other channel kind (web, telegram, messenger, instagram_dm) has no such window, so a message is always attempted; a real delivery FAILURE past that point (bad/missing provider credentials, a rejected send) still persists the message with deliveryStatus='failed' and returns 201 – same best-effort treatment KAP-95 already gives the internal endpoint, never silently dropped nor mistaken for the window gate above.

Idempotency-Key (API-3, D-API-4) is optional: a repeat with the SAME header and SAME body replays the original response without sending a second message; the SAME header with a DIFFERENT body -> 422 IDEMPOTENCY_KEY_REUSE_MISMATCH. NOT cached: the 409 window- closed rejection itself (a retry re-checks the window fresh, never trapped behind a stale cached rejection).


Permiso necesario: tenant:conversations.manage

conversation_id
required
Conversation Id
string format: uuid
Media typeapplication/json
PublicSendMessageRequest

POST /public/v1/conversations/{id}/messages body – free-form text only (no attachments, no authorName override – see PublicMessageOut’s own docstring).

object
content
required
Content
string
>= 1 characters

Examplegenerated

{
"content": "example"
}

Successful Response

Media typeapplication/json
PublicMessageOut

A single message, curated subset of the internal InboxMessageOut.

role is the RAW Message.role domain value ('user'/'assistant'/'operator'/ 'system') – never the internal _map_role UI relabeling ('user' -> 'customer'): same reasoning as PublicConversationOut.status above. Drops authorName (an operator’s display name, Platform-only presentation) and attachments (ADJ-4/ADJ-13, out of scope for this endpoint – SPEC_API_PUBLICA.md §2.3 names no attachment capability for the public surface; a real caller can still read attachment-bearing message text/metadata via content).

object
id
required
Id
string
conversationId
required
Conversationid
string
role
required
Role
string
content
required
Content
string
deliveryStatus
Any of:
string
createdAt
required
Createdat
string

Examplegenerated

{
"id": "example",
"conversationId": "example",
"role": "example",
"content": "example",
"deliveryStatus": "example",
"createdAt": "example"
}

Validation Error

Media typeapplication/json
HTTPValidationError
object
detail
Detail
Array<object>
ValidationError
object
loc
required
Location
Array
msg
required
Message
string
type
required
Error Type
string
input
Input
ctx
Context
object

Examplegenerated

{
"detail": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example",
"input": "example",
"ctx": {}
}
]
}