Developer Portal
How-to guides

How to Access a Forwarded Message

When a user forwards an existing message into a conversation, the incoming webhook contains a share_link_id field. Use that ID to fetch the original message content — transcript, audio, and attachments — via the share link endpoint.

Detecting a Forwarded Message

A forwarded message arrives as a normal message.posted.to.channel webhook event. Check for a non-null share_link_id in the payload to identify it:

{
  "event": "message.posted.to.channel",
  "data": {
    "id": "new-message-uuid",
    "conversation_id": "channel-uuid",
    "share_link_id": "share-link-uuid",
    "transcript_txt": "Check this out",
    "creator_id": "user-who-forwarded-uuid"
  }
}

share_link_id being non-null is the only signal you need — transcript_txt may also be present if the sender added accompanying text, but the original forwarded content lives behind the share link.

Fetch the Original Message Content

GET /v6/message-sharelinks/{share_link_id}
Authorization: Bearer <your-pat>

Response — key fields:

FieldDescription
share_type"forward" for forwarded messages, "link" for public share links
created_byUser who performed the forward
end_access_atExpiration timestamp (null if no expiry)
revoked_atSet if access has been revoked
has_channel_accessWhether the authenticated user has access to the original message's conversation
shared_messageThe original message, in the same MessageV6 shape the /v6/messages endpoints return (see below)

shared_message fields:

FieldDescription
idID of the original message
creator_idWho originally sent the message
conversation_idThe conversation the original message belongs to
workspace_idThe workspace the original message belongs to
content.transcriptThe transcript of the original message as plain text
content.ai_summaryAI summary of the original message, when one exists
content.time_codesWord-level time codes, when available
content.urlPlayback URL of the original audio
content.duration_msDuration of the original voice message
attachmentsAttachments from the original message. For type: "file", url already points at GET /message-sharelinks/{share_link_id}/attachments/signedurl/{id}, which returns the download URL
created_atWhen the original message was sent

To get the original message ID, read shared_message.id directly.

Access Attachments and Audio

Play the original audio from shared_message.content.url.

File attachments are stored privately and are not directly downloadable. The url of each type: "file" entry in shared_message.attachments is the share-link-scoped signed URL endpoint, which validates share-link access rather than requiring conversation membership:

GET /message-sharelinks/{share_link_id}/attachments/signedurl/{attachment_id}
Authorization: Bearer <your-pat>

The response is a signed URL you can use to download the file. Do not use GET /v5/attachments/download/signedurl/{attachment_id} here — that endpoint checks access to the original message's conversation and will 403 when has_channel_access is false.

Full Example — Webhook Handler

async function handleWebhook(webhook) {
  const { share_link_id, conversation_id, id } = webhook.data;

  if (!share_link_id) return; // not a forwarded message

  const res = await fetch(
    `https://api.carbonvoice.app/v6/message-sharelinks/${share_link_id}`,
    {
      headers: {
        Authorization: `Bearer ${process.env.CV_PAT}`,
      },
    },
  );
  const shareLink = await res.json();

  if (shareLink.revoked_at) return; // access revoked

  const { shared_message } = shareLink;
  const originalMessageId = shared_message.id;
  const transcript = shared_message.content?.transcript ?? '';

  // reply with a summary or acknowledgement
  await fetch('https://api.carbonvoice.app/v6/messages/text', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.CV_PAT}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      conversation_id,
      transcript: `Got the forwarded message: "${transcript}"`,
      reply_to_message_id: id,
    }),
  });
}

Related

How to Access a Forwarded Message | Carbon Voice Developer Portal