---
title: "Edit a message"
method: PATCH
path: "/issues/{id}/messages/{message_id}"
tags: ["messages"]
---

# Edit a message

`PATCH /issues/{id}/messages/{message_id}`

## Request

- Base URL: `https://api.usepylon.com`
- URL: `https://api.usepylon.com/issues/{id}/messages/{message_id}`
- Auth: HTTP bearer

Replaces the body of a message and syncs the edit to its connected channel (Slack, Microsoft Teams, Discord, Google Chat, Telegram, or the chat widget).
Only messages authored by the API token's user can be edited. Emails, customer messages, and redacted messages cannot be edited.
Callers without issue write access can edit only their own internal notes.

**Rate limit:** 30 requests per minute

## Path parameters

- `id` string, required
- `message_id` string, required

## Request body

- UpdateMessageRequestBody
  - `body_html` string, required: The new message body in HTML. Replaces the existing body.

## Response `200`

- UpdateMessageResponseBody
  - `data` Message, required
    - `author` MessageAuthor
      - `avatar_url` string
      - `contact` MiniContact
        - `email` string: The email of the contact.
        - `id` string, required: The ID of the contact.
      - `name` string, required
      - `user` MiniUser
        - `email` string: The email of the user.
        - `id` string, required: The ID of the user.
    - `author_unverified` boolean, required: Whether this message's author identity has NOT been verified. True for public form submissions, unverified chat widget visitors, and emails that failed sender authentication. For emails, read email_info.sender_authentication_status to tell an authentication failure apart from the other cases.
    - `email_info` EmailMessageInfo
      - `bcc_emails` string[], nullable: The email addresses of the BCC recipients of the message.
      - `cc_emails` string[], nullable: The email addresses of the CC recipients of the message.
      - `from_email` string, required: The email address of the sender of the message.
      - `message_id` string, required: The RFC 5322 Message-ID header value for this email. This is a provider-specific identifier, not the top-level Pylon message ID, and cannot be used as message_id when posting a reply or internal note.
      - `opens` EmailEvent[], nullable: When each recipient first opened an email Pylon sent, at most one entry per recipient. Always empty for inbound mail and for mail sent through a connected personal email account. Open tracking is approximate: clients that prefetch images (such as Apple Mail Privacy Protection) can report opens that never happened, and clients that block images report none.
        - `email` string, required: The email address of the recipient the event applies to.
        - `time` string, required: When the event happened, in RFC 3339 format.
      - `sender_authentication_status` string, required: The SPF/DKIM sender authentication result recorded by Pylon's inbound mail provider. One of "pass", "fail", or "unknown". "fail" means SPF failed outright, or the message carried a DKIM signature that did not validate. "pass" means SPF passed, or a DKIM signature validated. "unknown" means nothing vouched for the sender and must not be read as a pass. It covers mail Pylon sent, mail synced from a personal email integration, submissions stored as email messages, and senders whose domain published no SPF or DKIM records to check against.
      - `to_emails` string[], nullable: The email addresses of the recipients of the message.
    - `file_urls` string[]: The URLs of the files in the message, if any. Signed download URLs. Fetch with a plain GET, no Authorization header.
    - `id` string, required: The top-level Pylon message ID. Use this value as message_id when replying or when targeting an internal note's thread.
    - `is_private` boolean, required: Whether the message is an internal note. If true, the message is not visible to the requester; if false, it is customer-visible.
    - `message_html` string, required: The HTML body of the message.
    - `reactions` MessageReaction[], nullable: The emoji reactions currently on the message, grouped by emoji.
      - `count` integer, required: The number of people who reacted with this emoji.
      - `name` string, required: The emoji's Slack-style shortcode name without colons, such as thumbsup.
    - `slack_info` SlackMessageInfo
      - `channel_id` string, required: The Slack channel ID the message was posted in.
      - `message_ts` string, required: The Slack timestamp of this message, which is its Slack message ID.
      - `permalink` string: A link that opens this specific message in Slack. Omitted when the workspace's Slack domain is unknown.
      - `thread_ts` string, required: The timestamp of the thread's root message. Equal to message_ts for the root message itself.
    - `source` string, required: The source of the message.
    - `thread_id` string: The Pylon internal thread ID. This is set only for internal notes and can be passed as thread_id when creating an internal note.
    - `timestamp` string, date-time, required: The time at which the message was created.
  - `request_id` string, required: The request ID for tracking.

## Other responses

- `400`: The request was invalid or could not be completed.
- `401`: The request could not be authenticated for this API.
- `403`: The authenticated caller or organization is not allowed to access this endpoint or operation.
- `404`
- `429`: The request exceeded the applicable rate limit.
- `500`: An unexpected internal error occurred.

## Changes

- **2026-10-27** `69a0bee18b33`: 1 info
  - added the optional property `data/reactions` to the response with the `200` status
- **2026-10-13** `5734a02bb845`: 1 info
  - added the optional property `data/slack_info` to the response with the `200` status
- **2026-10-12** `40bf3229d58f`: 1 breaking, 12 info
  - the `data` response's property type changed from no type to `object` for status `200`
  - added the optional property `data/author` to the response with the `200` status
  - added the optional property `data/email_info` to the response with the `200` status
  - added the optional property `data/file_urls` to the response with the `200` status
  - …9 more
- **2026-10-11** `dfb481067e5a`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/usepylon/apis/pylon-api/changes/issues/:id/messages/:message_id/patch.md)

---

[API](https://skmtc.dev/usepylon/apis/pylon-api.md) - [All operations](https://skmtc.dev/usepylon/apis/pylon-api/llms.txt) - [OpenAPI document](https://skmtc.dev/usepylon/apis/pylon-api/revisions/7d018a2a6265?raw)
