Messages
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
Authorization: Bearer
The ID of the issue that the message belongs to.
The ID of the message to edit.
The new message body in HTML. Replaces the existing body.
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
PATCH /issues/{id}/messages/{message_id} HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 20
{
"body_html": "text"
}{
"data": {
"author": {
"avatar_url": "text",
"contact": {
"email": "text",
"id": "text"
},
"name": "text",
"user": {
"email": "text",
"id": "text"
}
},
"author_unverified": true,
"email_info": {
"bcc_emails": [
"text"
],
"cc_emails": [
"text"
],
"from_email": "text",
"message_id": "text",
"opens": [
{
"email": "text",
"time": "2026-09-30T16:33:54Z"
}
],
"sender_authentication_status": "pass",
"to_emails": [
"text"
]
},
"file_urls": [
"text"
],
"id": "text",
"is_private": true,
"message_html": "text",
"slack_info": {
"channel_id": "text",
"message_ts": "text",
"permalink": "text",
"thread_ts": "text"
},
"source": "text",
"thread_id": "text",
"timestamp": "2026-01-01T00:00:00.000Z"
},
"request_id": "text"
}Returns messages for the specified issue, including replies and internal notes, ordered from oldest to newest.
To post a reply, use the message's top-level id—not thread_id or email_info.message_id. To post an internal note, use an internal thread's thread_id or an internal note's top-level id. Omit both limit and cursor to return all messages; when cursor is provided without limit, the page size defaults to 100.
Rate limit: 120 requests per minute
Authorization: Bearer
The ID of the issue to fetch messages for.
The cursor to use for pagination.
The number of messages to fetch. Must be greater than 0 and at most 1000. If omitted, all messages are returned for backward compatibility.
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
GET /issues/{id}/messages HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"data": [
{
"author": {
"avatar_url": "text",
"contact": {
"email": "text",
"id": "text"
},
"name": "text",
"user": {
"email": "text",
"id": "text"
}
},
"author_unverified": true,
"email_info": {
"bcc_emails": [
"text"
],
"cc_emails": [
"text"
],
"from_email": "text",
"message_id": "text",
"opens": [
{
"email": "text",
"time": "2026-09-30T16:33:54Z"
}
],
"sender_authentication_status": "pass",
"to_emails": [
"text"
]
},
"file_urls": [
"text"
],
"id": "text",
"is_private": true,
"message_html": "text",
"slack_info": {
"channel_id": "text",
"message_ts": "text",
"permalink": "text",
"thread_ts": "text"
},
"source": "text",
"thread_id": "text",
"timestamp": "2026-01-01T00:00:00.000Z"
}
],
"pagination": {
"cursor": "text",
"has_next_page": true
},
"request_id": "text"
}Returns all threads for the specified issue.
Rate limit: 120 requests per minute
Authorization: Bearer
The ID of the issue to fetch threads for.
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
GET /issues/{id}/threads HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"data": [
{
"channel_id": "text",
"id": "text",
"issue_id": "text",
"name": "text",
"source": "text",
"thread_id": "text"
}
],
"request_id": "text"
}Creates a new internal thread on an issue.
Rate limit: 120 requests per minute
Authorization: Bearer
The ID of the issue to create a thread for.
The name of the thread.
The Slack channel ID to sync the thread to. When slack_thread_ts is also provided, links that existing Slack thread. Otherwise, creates a new Slack-backed thread. Linking an existing Slack thread imports its message history and enables ongoing synchronization. Creating or linking a Slack-backed thread requires an API token configured to act as a human Pylon user whose verified Slack identity is a member of the channel. Pylon bot users and standalone API identities are not supported because they do not have Slack-verifiable channel membership.
The root message timestamp of an existing Slack thread to link. Requires slack_channel_id.
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
POST /issues/{id}/threads HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 66
{
"name": "text",
"slack_channel_id": "text",
"slack_thread_ts": "text"
}{
"data": {
"channel_id": "text",
"id": "text",
"issue_id": "text",
"name": "text",
"source": "text",
"thread_id": "text"
},
"request_id": "text"
}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: 30 requests per minute
Authorization: Bearer
The ID of the issue.
URLs of files to attach to this reply.
The body of the message in HTML.
Optional contact ID to post the message as. Only one of user_id or contact_id can be provided.
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.
Optional user ID to post the message as. Only one of user_id or contact_id can be provided.
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
POST /issues/{id}/reply HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 322
{
"attachment_urls": [
"text"
],
"body_html": "text",
"contact_id": "text",
"custom_source": {
"created_at": "2026-01-01T00:00:00.000Z",
"external_id": "text",
"metadata": {
"conversation_id": "conv_123",
"source": "wechat"
}
},
"email_info": {
"bcc_emails": [
"text"
],
"cc_emails": [
"text"
],
"to_emails": [
"text"
]
},
"message_id": "text",
"user_id": "text"
}{
"data": {
"id": "text",
"issue_id": "text"
},
"request_id": "text"
}Creates a private customer-reply draft without sending it. The draft is visible only to its owner and may require a normal issue refetch before appearing in the app. For unlinked or service API tokens, user_id is required. This endpoint updates only untouched drafts that it previously created; every other existing draft returns a conflict.
Rate limit: 30 requests per minute
Authorization: Bearer
The ID of the issue.
The draft's BCC recipients. See to_emails.
The draft body in HTML.
The draft's CC recipients. See to_emails.
The draft's To recipients. If any of to_emails, cc_emails, or bcc_emails is provided, the draft uses exactly those lists and an omitted list is saved empty; omit all three to use the composer's default recipients.
The active Pylon user who should own and see the draft. Defaults to the API-token user when it is a human Pylon user; required for unlinked or service API tokens.
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
POST /issues/{id}/draft-reply HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 101
{
"bcc_emails": [
"text"
],
"body_html": "text",
"cc_emails": [
"text"
],
"to_emails": [
"text"
],
"user_id": "text"
}{
"data": {
"id": "text",
"issue_id": "text",
"status": "text",
"updated_at": "2026-01-01T00:00:00.000Z",
"user_id": "text"
},
"request_id": "text"
}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: 30 requests per minute
Authorization: Bearer
The ID of the issue.
URLs of files to attach to this internal note.
The body of the message in HTML.
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.
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.
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.
Optional user ID to post the message as. If not provided, the API token user will be used.
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
POST /issues/{id}/note HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 124
{
"attachment_urls": [
"text"
],
"body_html": "text",
"message_id": "text",
"thread_id": "text",
"thread_name": "text",
"user_id": "text"
}{
"data": {
"id": "text",
"issue_id": "text"
},
"request_id": "text"
}Permanently replaces a message's stored content with redacted_body_message and optionally deletes its attachments. This action cannot be undone. When omitted, redacted_body_message defaults to "This message has been redacted." and redact_attachments defaults to true.
Rate limit: 120 requests per minute
Authorization: Bearer
The ID of the issue that the message belongs to.
The ID of the message to redact.
Whether to permanently delete the message's attachments. Defaults to true.
Replacement message body in HTML. The caller is responsible for replacing any sensitive portions. Defaults to "This message has been redacted."
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
POST /issues/{id}/messages/{message_id}/redact HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 58
{
"redact_attachments": true,
"redacted_body_message": "text"
}{
"data": {
"author": {
"avatar_url": "text",
"contact": {
"email": "text",
"id": "text"
},
"name": "text",
"user": {
"email": "text",
"id": "text"
}
},
"author_unverified": true,
"email_info": {
"bcc_emails": [
"text"
],
"cc_emails": [
"text"
],
"from_email": "text",
"message_id": "text",
"opens": [
{
"email": "text",
"time": "2026-09-30T16:33:54Z"
}
],
"sender_authentication_status": "pass",
"to_emails": [
"text"
]
},
"file_urls": [
"text"
],
"id": "text",
"is_private": true,
"message_html": "text",
"slack_info": {
"channel_id": "text",
"message_ts": "text",
"permalink": "text",
"thread_ts": "text"
},
"source": "text",
"thread_id": "text",
"timestamp": "2026-01-01T00:00:00.000Z"
},
"request_id": "text"
}Permanently deletes a message from an issue and its connected external system.
Rate limit: 30 requests per minute
Authorization: Bearer
The ID of the issue that the message belongs to.
The ID of the message to delete.
The request ID for tracking.
The request was invalid or could not be completed.
The request could not be authenticated for this API.
The authenticated caller or organization is not allowed to access this endpoint or operation.
The request exceeded the applicable rate limit.
An unexpected internal error occurred.
DELETE /issues/{id}/messages/{message_id} HTTP/1.1
Host: api.usepylon.com
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"request_id": "text"
}Last updated
Was this helpful?

