> For the complete documentation index, see [llms.txt](https://docs.usepylon.com/pylon-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.usepylon.com/pylon-docs/developer/api/api-reference/messages.md).

# Messages

## Get messages on an issue

> Returns messages for the specified issue, including replies and internal notes, ordered from oldest to newest.\
> \
> Use these messages when posting a reply or internal note:\
> \
> \* To post a reply, choose a customer-visible message where is\_private is false and pass its top-level id as message\_id to POST /issues/{id}/reply.\
> \
> \* To post an internal note to an existing internal thread, choose an internal note where is\_private is true. Pass its thread\_id as thread\_id, or its top-level id as message\_id, to POST /issues/{id}/note.\
> \
> \* Do not use email\_info.message\_id for either operation. It is the email's RFC 5322 Message-ID header, not the Pylon message ID.\
> \
> Pagination:\
> \
> \* Omit both limit and cursor to return all messages for backward compatibility.\
> \
> \* Set limit from 1 to 1000 to paginate the results.\
> \
> \* If cursor is provided without limit, the page size defaults to 100.\
> \
> \* While pagination.has\_next\_page is true, pass pagination.cursor as cursor in the next request.\
> \
> \*\*Rate limit:\*\* 20 requests per minute

```json
{"openapi":"3.0.3","info":{"title":"Pylon API.","version":"1.0.0"},"servers":[{"url":"https://api.usepylon.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"description":"Authorization: Bearer <token>","scheme":"bearer","type":"http"}},"responses":{"GetIssueMessagesResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetIssueMessagesResponseBody"}}},"description":""},"BadRequestApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The request was invalid or could not be completed."},"ErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":""},"InternalServerErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"An unexpected internal error occurred."}},"schemas":{"GetIssueMessagesResponseBody":{"properties":{"data":{"description":"The data payload of the response.","items":{"$ref":"#/components/schemas/Message"},"type":"array"},"pagination":{"$ref":"#/components/schemas/Pagination"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"},"Message":{"properties":{"author":{"$ref":"#/components/schemas/MessageAuthor"},"email_info":{"$ref":"#/components/schemas/EmailMessageInfo"},"file_urls":{"description":"The URLs of the files in the message, if any.","items":{"type":"string"},"type":"array"},"id":{"description":"The top-level Pylon message ID. Use this value as message_id when replying or when targeting an internal note's thread.","type":"string"},"is_private":{"description":"Whether the message is an internal note. If true, the message is not visible to the requester; if false, it is customer-visible.","type":"boolean"},"message_html":{"description":"The HTML body of the message.","type":"string"},"source":{"description":"The source of the message.","type":"string"},"thread_id":{"description":"The Pylon internal thread ID. This is set only for internal notes and can be passed as thread_id when creating an internal note.","type":"string"},"timestamp":{"description":"The time at which the message was created.","type":"string"}},"type":"object"},"MessageAuthor":{"properties":{"avatar_url":{"type":"string"},"contact":{"$ref":"#/components/schemas/MiniContact"},"name":{"type":"string"},"user":{"$ref":"#/components/schemas/MiniUser"}},"type":"object"},"MiniContact":{"properties":{"email":{"description":"The email of the contact.","type":"string"},"id":{"description":"The ID of the contact.","type":"string"}},"type":"object"},"MiniUser":{"properties":{"email":{"description":"The email of the user.","type":"string"},"id":{"description":"The ID of the user.","type":"string"}},"type":"object"},"EmailMessageInfo":{"properties":{"bcc_emails":{"description":"The email addresses of the BCC recipients of the message.","items":{"type":"string"},"type":"array"},"cc_emails":{"description":"The email addresses of the CC recipients of the message.","items":{"type":"string"},"type":"array"},"from_email":{"description":"The email address of the sender of the message.","type":"string"},"message_id":{"description":"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.","type":"string"},"to_emails":{"description":"The email addresses of the recipients of the message.","items":{"type":"string"},"type":"array"}},"type":"object"},"Pagination":{"properties":{"cursor":{"description":"The cursor for the next page of results.","type":"string"},"has_next_page":{"description":"Indicates if there is a next page of results.","type":"boolean"}},"required":["cursor","has_next_page"],"type":"object"},"ErrorApiResponseBody":{"properties":{"errors":{"description":"The list of errors.","items":{"type":"string"},"type":"array"},"exists_id":{"description":"The ID of the object that already exists if this is a duplicate object error.","type":"string"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"}}},"paths":{"/issues/{id}/messages":{"get":{"description":"Returns messages for the specified issue, including replies and internal notes, ordered from oldest to newest.\n\nUse these messages when posting a reply or internal note:\n\n* To post a reply, choose a customer-visible message where is_private is false and pass its top-level id as message_id to POST /issues/{id}/reply.\n\n* To post an internal note to an existing internal thread, choose an internal note where is_private is true. Pass its thread_id as thread_id, or its top-level id as message_id, to POST /issues/{id}/note.\n\n* Do not use email_info.message_id for either operation. It is the email's RFC 5322 Message-ID header, not the Pylon message ID.\n\nPagination:\n\n* Omit both limit and cursor to return all messages for backward compatibility.\n\n* Set limit from 1 to 1000 to paginate the results.\n\n* If cursor is provided without limit, the page size defaults to 100.\n\n* While pagination.has_next_page is true, pass pagination.cursor as cursor in the next request.\n\n**Rate limit:** 20 requests per minute","operationId":"GetIssueMessages","parameters":[{"description":"The ID of the issue to fetch messages for.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"The cursor to use for pagination.","in":"query","name":"cursor","schema":{"type":"string"}},{"description":"The number of messages to fetch. Must be greater than 0 and at most 1000. If omitted, all messages are returned for backward compatibility.","in":"query","name":"limit","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"$ref":"#/components/responses/GetIssueMessagesResponse"},"400":{"$ref":"#/components/responses/BadRequestApiResponse"},"404":{"$ref":"#/components/responses/ErrorApiResponse"},"500":{"$ref":"#/components/responses/InternalServerErrorApiResponse"}},"summary":"Get messages on an issue","tags":["messages"]}}}}
```

## Get all threads on an issue

> Returns all threads for the specified issue.\
> \
> \*\*Rate limit:\*\* 20 requests per minute

```json
{"openapi":"3.0.3","info":{"title":"Pylon API.","version":"1.0.0"},"servers":[{"url":"https://api.usepylon.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"description":"Authorization: Bearer <token>","scheme":"bearer","type":"http"}},"responses":{"GetIssueThreadsResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetIssueThreadsResponseBody"}}},"description":""},"BadRequestApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The request was invalid or could not be completed."},"ErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":""},"InternalServerErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"An unexpected internal error occurred."}},"schemas":{"GetIssueThreadsResponseBody":{"properties":{"data":{"description":"The data payload of the response.","items":{"$ref":"#/components/schemas/IssueThread"},"type":"array"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"},"IssueThread":{"description":"A thread of notes on an issue, for internal discussions not visible to the customer.\n\nThreads can be created manually through the UI or from triggers.\n\nIf a channel ID is set, this thread is being synced with a chat platform.","properties":{"channel_id":{"description":"The ID of the channel that the thread belongs to, if the thread is being synced with a chat platform.","type":"string"},"id":{"description":"The ID of the thread.","type":"string"},"issue_id":{"description":"The issue ID that the thread belongs to.","type":"string"},"name":{"description":"The name of the thread.","type":"string"},"source":{"description":"The source of the thread.","type":"string"},"thread_id":{"description":"The ID of the thread that the thread belongs to, if the thread is being synced with a chat platform. A thread ID for Slack would be the thread timestamp.","type":"string"}},"title":"IssueThread","type":"object"},"ErrorApiResponseBody":{"properties":{"errors":{"description":"The list of errors.","items":{"type":"string"},"type":"array"},"exists_id":{"description":"The ID of the object that already exists if this is a duplicate object error.","type":"string"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"}}},"paths":{"/issues/{id}/threads":{"get":{"description":"Returns all threads for the specified issue.\n\n**Rate limit:** 20 requests per minute","operationId":"GetIssueThreads","parameters":[{"description":"The ID of the issue to fetch threads for.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"$ref":"#/components/responses/GetIssueThreadsResponse"},"400":{"$ref":"#/components/responses/BadRequestApiResponse"},"404":{"$ref":"#/components/responses/ErrorApiResponse"},"500":{"$ref":"#/components/responses/InternalServerErrorApiResponse"}},"summary":"Get all threads on an issue","tags":["messages"]}}}}
```

## Create a thread on an issue

> Creates a new internal thread on an issue.\
> \
> \*\*Rate limit:\*\* 20 requests per minute

```json
{"openapi":"3.0.3","info":{"title":"Pylon API.","version":"1.0.0"},"servers":[{"url":"https://api.usepylon.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"description":"Authorization: Bearer <token>","scheme":"bearer","type":"http"}},"schemas":{"CreateIssueThreadRequestBody":{"properties":{"name":{"description":"The name of the thread.","type":"string"}},"type":"object"},"CreateIssueThreadResponseBody":{"properties":{"data":{"$ref":"#/components/schemas/IssueThread"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"},"IssueThread":{"description":"A thread of notes on an issue, for internal discussions not visible to the customer.\n\nThreads can be created manually through the UI or from triggers.\n\nIf a channel ID is set, this thread is being synced with a chat platform.","properties":{"channel_id":{"description":"The ID of the channel that the thread belongs to, if the thread is being synced with a chat platform.","type":"string"},"id":{"description":"The ID of the thread.","type":"string"},"issue_id":{"description":"The issue ID that the thread belongs to.","type":"string"},"name":{"description":"The name of the thread.","type":"string"},"source":{"description":"The source of the thread.","type":"string"},"thread_id":{"description":"The ID of the thread that the thread belongs to, if the thread is being synced with a chat platform. A thread ID for Slack would be the thread timestamp.","type":"string"}},"title":"IssueThread","type":"object"},"ErrorApiResponseBody":{"properties":{"errors":{"description":"The list of errors.","items":{"type":"string"},"type":"array"},"exists_id":{"description":"The ID of the object that already exists if this is a duplicate object error.","type":"string"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"}},"responses":{"CreateIssueThreadResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueThreadResponseBody"}}},"description":""},"BadRequestApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The request was invalid or could not be completed."},"ErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":""},"InternalServerErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"An unexpected internal error occurred."}}},"paths":{"/issues/{id}/threads":{"post":{"description":"Creates a new internal thread on an issue.\n\n**Rate limit:** 20 requests per minute","operationId":"CreateIssueThread","parameters":[{"description":"The ID of the issue to create a thread for.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueThreadRequestBody"}}}},"responses":{"200":{"$ref":"#/components/responses/CreateIssueThreadResponse"},"400":{"$ref":"#/components/responses/BadRequestApiResponse"},"404":{"$ref":"#/components/responses/ErrorApiResponse"},"500":{"$ref":"#/components/responses/InternalServerErrorApiResponse"}},"summary":"Create a thread on an issue","tags":["messages"]}}}}
```

## Reply to an issue

> Sends a customer-facing reply on an issue, visible to the requester.\
> \
> message\_id is required to identify which existing customer-visible conversation or thread to continue. Use the top-level message id returned by GET /issues/{id}/messages; do not use an external provider's message ID or the nested email\_info.message\_id value.\
> \
> For an email conversation, email\_info must contain at least one recipient across to\_emails, cc\_emails, and bcc\_emails. The referenced message controls email threading, but its recipients are not copied automatically.\
> \
> \*\*Rate limit:\*\* 10 requests per minute

```json
{"openapi":"3.0.3","info":{"title":"Pylon API.","version":"1.0.0"},"servers":[{"url":"https://api.usepylon.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"description":"Authorization: Bearer <token>","scheme":"bearer","type":"http"}},"schemas":{"CreateIssueReplyRequestBody":{"properties":{"attachment_urls":{"description":"URLs of files to attach to this reply.","items":{"type":"string"},"type":"array"},"body_html":{"description":"The body of the message in HTML.","type":"string"},"contact_id":{"description":"Optional contact ID to post the message as. Only one of user_id or contact_id can be provided.","type":"string"},"custom_source":{"$ref":"#/components/schemas/CustomSourceInfo"},"email_info":{"$ref":"#/components/schemas/CreateIssueReplyEmailInfo"},"message_id":{"description":"The top-level Pylon message ID to reply to, from the `id` field returned by GET /issues/{id}/messages. The message must belong to the issue in the request path and must be customer-visible, not an internal note. This selects the external conversation or thread where the reply is delivered. For email, it also sets the In-Reply-To and References chain. Do not use a provider-specific message ID or email_info.message_id.","type":"string"},"user_id":{"description":"Optional user ID to post the message as. Only one of user_id or contact_id can be provided.","type":"string"}},"required":["body_html","message_id"],"type":"object"},"CustomSourceInfo":{"properties":{"created_at":{"description":"The timestamp of when the message was created in the external system. (RFC3339)","type":"string"},"external_id":{"description":"The external ID of this message in the custom system.","type":"string"},"metadata":{"additionalProperties":{},"description":"Arbitrary metadata to store with the message.","type":"object"}},"required":["external_id"],"title":"CustomSourceInfo contains metadata for messages on custom source issues.","type":"object"},"CreateIssueReplyEmailInfo":{"description":"Recipient information for replies to email conversations.\n\nProvide at least one address across to_emails, cc_emails, and bcc_emails.\n\nRecipients are not inferred from the referenced message.","properties":{"bcc_emails":{"description":"The blind-carbon-copy recipients of the email reply.","items":{"type":"string"},"type":"array"},"cc_emails":{"description":"The carbon-copy recipients of the email reply.","items":{"type":"string"},"type":"array"},"to_emails":{"description":"The primary recipients of the email reply.","items":{"type":"string"},"type":"array"}},"title":"CreateIssueReplyEmailInfo","type":"object"},"CreateIssueReplyResponseBody":{"properties":{"data":{"$ref":"#/components/schemas/CreateIssueReplyResponseData"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"},"CreateIssueReplyResponseData":{"properties":{"id":{"description":"The ID of the message.","type":"string"},"issue_id":{"description":"The ID of the issue.","type":"string"}},"type":"object"},"ErrorApiResponseBody":{"properties":{"errors":{"description":"The list of errors.","items":{"type":"string"},"type":"array"},"exists_id":{"description":"The ID of the object that already exists if this is a duplicate object error.","type":"string"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"}},"responses":{"CreateIssueReplyResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueReplyResponseBody"}}},"description":""},"BadRequestApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The request was invalid or could not be completed."},"ForbiddenApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The authenticated caller or organization is not allowed to access this endpoint or operation."},"ErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":""},"InternalServerErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"An unexpected internal error occurred."}}},"paths":{"/issues/{id}/reply":{"post":{"description":"Sends a customer-facing reply on an issue, visible to the requester.\n\nmessage_id is required to identify which existing customer-visible conversation or thread to continue. Use the top-level message id returned by GET /issues/{id}/messages; do not use an external provider's message ID or the nested email_info.message_id value.\n\nFor an email conversation, email_info must contain at least one recipient across to_emails, cc_emails, and bcc_emails. The referenced message controls email threading, but its recipients are not copied automatically.\n\n**Rate limit:** 10 requests per minute","operationId":"CreateIssueReply","parameters":[{"description":"The ID of the issue.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueReplyRequestBody"}}}},"responses":{"200":{"$ref":"#/components/responses/CreateIssueReplyResponse"},"400":{"$ref":"#/components/responses/BadRequestApiResponse"},"403":{"$ref":"#/components/responses/ForbiddenApiResponse"},"404":{"$ref":"#/components/responses/ErrorApiResponse"},"500":{"$ref":"#/components/responses/InternalServerErrorApiResponse"}},"summary":"Reply to an issue","tags":["messages"]}}}}
```

## Create an internal note on an issue

> Posts an internal note on an issue thread. Not visible to the requester.\
> \
> Thread selection:\
> \
> \* If thread\_id is provided, posts to that internal thread.\
> \
> \* If message\_id is provided, posts to the thread containing that internal note.\
> \
> \* Providing both thread\_id and message\_id returns a 400 response.\
> \
> \* If neither is provided, posts to the most recently created Slack-backed internal thread. If none exists, creates a Pylon-only internal thread.\
> \
> \* thread\_name names that newly created Pylon-only thread and is otherwise ignored.\
> \
> Empty thread\_id, message\_id, and thread\_name values are treated as omitted.\
> \
> \*\*Rate limit:\*\* 10 requests per minute

```json
{"openapi":"3.0.3","info":{"title":"Pylon API.","version":"1.0.0"},"servers":[{"url":"https://api.usepylon.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"description":"Authorization: Bearer <token>","scheme":"bearer","type":"http"}},"schemas":{"CreateIssueNoteRequestBody":{"properties":{"attachment_urls":{"description":"URLs of files to attach to this internal note.","items":{"type":"string"},"type":"array"},"body_html":{"description":"The body of the message in HTML.","type":"string"},"message_id":{"description":"The ID of an internal note whose thread should receive the new note. Use the top-level `id` from GET /issues/{id}/messages. Cannot be combined with thread_id.","type":"string"},"thread_id":{"description":"The ID of the internal thread to post the note to. Use the `id` field (not `thread_id`) from GET /issues/{id}/threads. Cannot be combined with message_id.","type":"string"},"thread_name":{"description":"Optional name for a new Pylon-only internal thread. Used only when neither thread_id nor message_id is provided and no Slack-backed internal thread exists.","type":"string"},"user_id":{"description":"Optional user ID to post the message as. If not provided, the API token user will be used.","type":"string"}},"required":["body_html"],"type":"object"},"CreateIssueNoteResponseBody":{"properties":{"data":{"$ref":"#/components/schemas/CreateIssueNoteResponseData"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"},"CreateIssueNoteResponseData":{"properties":{"id":{"description":"The ID of the message.","type":"string"},"issue_id":{"description":"The ID of the issue.","type":"string"}},"type":"object"},"ErrorApiResponseBody":{"properties":{"errors":{"description":"The list of errors.","items":{"type":"string"},"type":"array"},"exists_id":{"description":"The ID of the object that already exists if this is a duplicate object error.","type":"string"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"}},"responses":{"CreateIssueNoteResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueNoteResponseBody"}}},"description":""},"BadRequestApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The request was invalid or could not be completed."},"ForbiddenApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The authenticated caller or organization is not allowed to access this endpoint or operation."},"ErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":""},"InternalServerErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"An unexpected internal error occurred."}}},"paths":{"/issues/{id}/note":{"post":{"description":"Posts an internal note on an issue thread. Not visible to the requester.\n\nThread selection:\n\n* If thread_id is provided, posts to that internal thread.\n\n* If message_id is provided, posts to the thread containing that internal note.\n\n* Providing both thread_id and message_id returns a 400 response.\n\n* If neither is provided, posts to the most recently created Slack-backed internal thread. If none exists, creates a Pylon-only internal thread.\n\n* thread_name names that newly created Pylon-only thread and is otherwise ignored.\n\nEmpty thread_id, message_id, and thread_name values are treated as omitted.\n\n**Rate limit:** 10 requests per minute","operationId":"CreateIssueNote","parameters":[{"description":"The ID of the issue.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueNoteRequestBody"}}}},"responses":{"200":{"$ref":"#/components/responses/CreateIssueNoteResponse"},"400":{"$ref":"#/components/responses/BadRequestApiResponse"},"403":{"$ref":"#/components/responses/ForbiddenApiResponse"},"404":{"$ref":"#/components/responses/ErrorApiResponse"},"500":{"$ref":"#/components/responses/InternalServerErrorApiResponse"}},"summary":"Create an internal note on an issue","tags":["messages"]}}}}
```

## Redact a message

> Permanently redacts a message's content. This action cannot be undone.\
> \
> \*\*Rate limit:\*\* 20 requests per minute

```json
{"openapi":"3.0.3","info":{"title":"Pylon API.","version":"1.0.0"},"servers":[{"url":"https://api.usepylon.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"description":"Authorization: Bearer <token>","scheme":"bearer","type":"http"}},"responses":{"RedactMessageResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactMessageResponseBody"}}},"description":""},"BadRequestApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The request was invalid or could not be completed."},"ErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":""},"InternalServerErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"An unexpected internal error occurred."}},"schemas":{"RedactMessageResponseBody":{"properties":{"data":{"$ref":"#/components/schemas/Message"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"},"Message":{"properties":{"author":{"$ref":"#/components/schemas/MessageAuthor"},"email_info":{"$ref":"#/components/schemas/EmailMessageInfo"},"file_urls":{"description":"The URLs of the files in the message, if any.","items":{"type":"string"},"type":"array"},"id":{"description":"The top-level Pylon message ID. Use this value as message_id when replying or when targeting an internal note's thread.","type":"string"},"is_private":{"description":"Whether the message is an internal note. If true, the message is not visible to the requester; if false, it is customer-visible.","type":"boolean"},"message_html":{"description":"The HTML body of the message.","type":"string"},"source":{"description":"The source of the message.","type":"string"},"thread_id":{"description":"The Pylon internal thread ID. This is set only for internal notes and can be passed as thread_id when creating an internal note.","type":"string"},"timestamp":{"description":"The time at which the message was created.","type":"string"}},"type":"object"},"MessageAuthor":{"properties":{"avatar_url":{"type":"string"},"contact":{"$ref":"#/components/schemas/MiniContact"},"name":{"type":"string"},"user":{"$ref":"#/components/schemas/MiniUser"}},"type":"object"},"MiniContact":{"properties":{"email":{"description":"The email of the contact.","type":"string"},"id":{"description":"The ID of the contact.","type":"string"}},"type":"object"},"MiniUser":{"properties":{"email":{"description":"The email of the user.","type":"string"},"id":{"description":"The ID of the user.","type":"string"}},"type":"object"},"EmailMessageInfo":{"properties":{"bcc_emails":{"description":"The email addresses of the BCC recipients of the message.","items":{"type":"string"},"type":"array"},"cc_emails":{"description":"The email addresses of the CC recipients of the message.","items":{"type":"string"},"type":"array"},"from_email":{"description":"The email address of the sender of the message.","type":"string"},"message_id":{"description":"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.","type":"string"},"to_emails":{"description":"The email addresses of the recipients of the message.","items":{"type":"string"},"type":"array"}},"type":"object"},"ErrorApiResponseBody":{"properties":{"errors":{"description":"The list of errors.","items":{"type":"string"},"type":"array"},"exists_id":{"description":"The ID of the object that already exists if this is a duplicate object error.","type":"string"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"}}},"paths":{"/issues/{id}/messages/{message_id}/redact":{"post":{"description":"Permanently redacts a message's content. This action cannot be undone.\n\n**Rate limit:** 20 requests per minute","operationId":"RedactMessage","parameters":[{"description":"The ID of the issue that the message belongs to.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"The ID of the message to redact.","in":"path","name":"message_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"$ref":"#/components/responses/RedactMessageResponse"},"400":{"$ref":"#/components/responses/BadRequestApiResponse"},"404":{"$ref":"#/components/responses/ErrorApiResponse"},"500":{"$ref":"#/components/responses/InternalServerErrorApiResponse"}},"summary":"Redact a message","tags":["messages"]}}}}
```

## Delete a message

> Permanently deletes a message from an issue and its connected external system.\
> \
> \*\*Rate limit:\*\* 10 requests per minute

```json
{"openapi":"3.0.3","info":{"title":"Pylon API.","version":"1.0.0"},"servers":[{"url":"https://api.usepylon.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"description":"Authorization: Bearer <token>","scheme":"bearer","type":"http"}},"responses":{"DeleteMessageResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteMessageResponseBody"}}},"description":""},"BadRequestApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"The request was invalid or could not be completed."},"ErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":""},"InternalServerErrorApiResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorApiResponseBody"}}},"description":"An unexpected internal error occurred."}},"schemas":{"DeleteMessageResponseBody":{"properties":{"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"},"ErrorApiResponseBody":{"properties":{"errors":{"description":"The list of errors.","items":{"type":"string"},"type":"array"},"exists_id":{"description":"The ID of the object that already exists if this is a duplicate object error.","type":"string"},"request_id":{"description":"The request ID for tracking.","type":"string"}},"type":"object"}}},"paths":{"/issues/{id}/messages/{message_id}":{"delete":{"description":"Permanently deletes a message from an issue and its connected external system.\n\n**Rate limit:** 10 requests per minute","operationId":"DeleteMessage","parameters":[{"description":"The ID of the issue that the message belongs to.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"The ID of the message to delete.","in":"path","name":"message_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"$ref":"#/components/responses/DeleteMessageResponse"},"400":{"$ref":"#/components/responses/BadRequestApiResponse"},"404":{"$ref":"#/components/responses/ErrorApiResponse"},"500":{"$ref":"#/components/responses/InternalServerErrorApiResponse"}},"summary":"Delete a message","tags":["messages"]}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.usepylon.com/pylon-docs/developer/api/api-reference/messages.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
