Skip to content

Forward a message

POST
/v1/conversations/{id}/forward
curl --request POST \
--url https://app.mondochat.io/v1/conversations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/forward \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "client_msg_id": "0199d6a0-3000-7000-8000-000000000099", "message_id": "0199d6a0-3000-7000-8000-000000000001" }'

Posts a copy of a text, photo, video or voice message into the conversation in the path, as the caller. Takes a session token. Answers 201, or 200 with the stored message when the caller already used that client_msg_id there. The copy has forwarded true and no quote, and media is copied in storage. Answers 404 when the source is not visible to the caller, is not sent, is redacted or deleted, or its media is not ready, and 403 policy_denied with reason forward for view-once, card and system messages. The gates of a send or an upload also apply. See https://docs.mondochat.io/guides/media/.

id
required
Id
string format: uuid
Media typeapplication/json
ForwardMessage

The message to copy into a conversation.

object
client_msg_id
required
Client Msg Id

An id you choose; a repeat returns the stored copy with 200.

string format: uuid
message_id
required
Message Id

The message to forward.

string format: uuid

Already exists

Media typeapplication/json
Message

A message in a conversation, as the viewer sees it.

object
auto
Auto

True for an away reply the server sent for its sender.

boolean
caption
Any of:
string
card
Any of:
Card

A structured message such as an offer, a purchase or a call event.

object
data
Data

The card’s content; its shape depends on type.

object
key
additional properties
any
type
required
Type

What the card is.

string
Allowed values: call_invite call_ended call_missed purchase offer system signup_invite
client_msg_id
required
Any of:
string
conversation_id
required
Conversation Id

The conversation it belongs to.

string format: uuid
created_at
required
Created At

When it was sent.

string format: date-time
deleted
Deleted

True when the sender deleted it for everyone. It has no text, caption, photo, card or quote.

boolean
delivered_to_peer
Delivered To Peer

True for the viewer’s own message once the peer received or read it, never for a silently dropped one.

boolean
duration_ms
Any of:
integer
edited_at
Any of:
string format: date-time
forwarded
Forwarded

True when the sender marked it forwarded, or it came from the forward route.

boolean
height
Any of:
integer
id
required
Id

The message’s id.

string format: uuid
kind
required
Kind

text, photo, video, voice, system or card.

string
Allowed values: text photo video voice system card
once
Once

True for view-once media: it carries no links and no caption for anyone, and its recipient opens it through the open route.

boolean
opened_at
Any of:
string format: date-time
photo
Any of:
Photo

A photo, video, voice note or avatar and the links to read it.

object
full_url
required
Any of:
string
height
required
Any of:
integer
id
required
Id

The media’s id.

string format: uuid
kind
required
Kind

What the media is.

string
Allowed values: photo video voice avatar
status
required
Status

pending until the upload is completed, held while it waits for the receiver’s consent or for moderation, rejected or deleted once it is gone.

string
Allowed values: pending ready held rejected deleted
thumb_url
required
Any of:
string
uploader_id
required
Uploader Id

The id of the user who uploaded it.

string format: uuid
width
required
Any of:
integer
reactions
Reactions

One entry per emoji in the order they were set; none on a deleted or redacted message.

Array<object>
default:
Reaction

One emoji on a message and how many users set it.

object
count
required
Count

How many users reacted with it.

integer
emoji
required
Emoji

The emoji.

string
mine
required
Mine

True when the viewer’s own reaction is this emoji.

boolean
read_by_peer
required
Read By Peer

True for the viewer’s own message once the peer read it; false while either participant has read_receipts off.

boolean
redacted
required
Redacted

True when a moderator removed the content.

boolean
reply_to
Any of:
ReplyTo

The message a message quotes.

object
id
required
Id

The quoted message’s id.

string format: uuid
kind
required
Kind

The quoted message’s kind.

string
Allowed values: text photo video voice system card
preview
required
Preview

The quoted text or caption, up to 140 characters; empty for a view-once message or a card.

string
sender_id
required
Any of:
string format: uuid
sender_id
required
Any of:
string format: uuid
seq
required
Seq

The message’s place in its conversation’s sync order. Keep the copy with the higher seq.

integer
status
required
Status

held and rejected come from moderation or photo consent, and undelivered is a message dropped silently because the peer blocked the sender.

string
Allowed values: sent held rejected undelivered
text
Any of:
string
wave
Any of:
string
width
Any of:
integer

Example

{
"client_msg_id": "c1f0a5e2-7d2b-4d57-9a53-0a6f5b6f1d10",
"conversation_id": "0199d6a0-2000-7000-8000-000000000001",
"created_at": "2026-11-01T09:30:00Z",
"delivered_to_peer": true,
"id": "0199d6a0-3000-7000-8000-000000000001",
"kind": "text",
"reactions": [
{
"count": 1,
"emoji": "👍",
"mine": false
}
],
"read_by_peer": false,
"redacted": false,
"sender_id": "0199d6a0-1000-7000-8000-000000000001",
"seq": 12,
"status": "sent",
"text": "Hi Bob"
}

Successful Response

Media typeapplication/json
Message

A message in a conversation, as the viewer sees it.

object
auto
Auto

True for an away reply the server sent for its sender.

boolean
caption
Any of:
string
card
Any of:
Card

A structured message such as an offer, a purchase or a call event.

object
data
Data

The card’s content; its shape depends on type.

object
key
additional properties
any
type
required
Type

What the card is.

string
Allowed values: call_invite call_ended call_missed purchase offer system signup_invite
client_msg_id
required
Any of:
string
conversation_id
required
Conversation Id

The conversation it belongs to.

string format: uuid
created_at
required
Created At

When it was sent.

string format: date-time
deleted
Deleted

True when the sender deleted it for everyone. It has no text, caption, photo, card or quote.

boolean
delivered_to_peer
Delivered To Peer

True for the viewer’s own message once the peer received or read it, never for a silently dropped one.

boolean
duration_ms
Any of:
integer
edited_at
Any of:
string format: date-time
forwarded
Forwarded

True when the sender marked it forwarded, or it came from the forward route.

boolean
height
Any of:
integer
id
required
Id

The message’s id.

string format: uuid
kind
required
Kind

text, photo, video, voice, system or card.

string
Allowed values: text photo video voice system card
once
Once

True for view-once media: it carries no links and no caption for anyone, and its recipient opens it through the open route.

boolean
opened_at
Any of:
string format: date-time
photo
Any of:
Photo

A photo, video, voice note or avatar and the links to read it.

object
full_url
required
Any of:
string
height
required
Any of:
integer
id
required
Id

The media’s id.

string format: uuid
kind
required
Kind

What the media is.

string
Allowed values: photo video voice avatar
status
required
Status

pending until the upload is completed, held while it waits for the receiver’s consent or for moderation, rejected or deleted once it is gone.

string
Allowed values: pending ready held rejected deleted
thumb_url
required
Any of:
string
uploader_id
required
Uploader Id

The id of the user who uploaded it.

string format: uuid
width
required
Any of:
integer
reactions
Reactions

One entry per emoji in the order they were set; none on a deleted or redacted message.

Array<object>
default:
Reaction

One emoji on a message and how many users set it.

object
count
required
Count

How many users reacted with it.

integer
emoji
required
Emoji

The emoji.

string
mine
required
Mine

True when the viewer’s own reaction is this emoji.

boolean
read_by_peer
required
Read By Peer

True for the viewer’s own message once the peer read it; false while either participant has read_receipts off.

boolean
redacted
required
Redacted

True when a moderator removed the content.

boolean
reply_to
Any of:
ReplyTo

The message a message quotes.

object
id
required
Id

The quoted message’s id.

string format: uuid
kind
required
Kind

The quoted message’s kind.

string
Allowed values: text photo video voice system card
preview
required
Preview

The quoted text or caption, up to 140 characters; empty for a view-once message or a card.

string
sender_id
required
Any of:
string format: uuid
sender_id
required
Any of:
string format: uuid
seq
required
Seq

The message’s place in its conversation’s sync order. Keep the copy with the higher seq.

integer
status
required
Status

held and rejected come from moderation or photo consent, and undelivered is a message dropped silently because the peer blocked the sender.

string
Allowed values: sent held rejected undelivered
text
Any of:
string
wave
Any of:
string
width
Any of:
integer

Example

{
"client_msg_id": "c1f0a5e2-7d2b-4d57-9a53-0a6f5b6f1d10",
"conversation_id": "0199d6a0-2000-7000-8000-000000000001",
"created_at": "2026-11-01T09:30:00Z",
"delivered_to_peer": true,
"id": "0199d6a0-3000-7000-8000-000000000001",
"kind": "text",
"reactions": [
{
"count": 1,
"emoji": "👍",
"mine": false
}
],
"read_by_peer": false,
"redacted": false,
"sender_id": "0199d6a0-1000-7000-8000-000000000001",
"seq": 12,
"status": "sent",
"text": "Hi Bob"
}

Problem

Media typeapplication/problem+json

An RFC 9457 problem: the body of every error answer.

object
code
required

The stable error code to branch on, such as policy_denied.

string
detail

What went wrong this time, when there is more to say.

string | null
errors

For validation, one entry per invalid field.

Array<object>

One invalid field.

object
loc

The path to the field.

array
msg

What is wrong with it.

string
instance

The path of the request.

string
reason

For policy_denied and limit_reached, the rule or limit that refused the request; for forbidden, a short cause such as you_blocked; for banned, temporary when the ban expires.

string
status
required

The HTTP status code.

integer
title
required

A short summary of the problem.

string
type
required

A URL that names the problem, https://app.mondochat.io/problems/<code>.

string

Example

{
"code": "policy_denied",
"detail": null,
"instance": "/v1/conversations/0199d6a0-2000-7000-8000-000000000001",
"reason": "pins",
"status": 403,
"title": "Policy denied",
"type": "https://app.mondochat.io/problems/policy_denied"
}