Skip to main content
GET
/
api
/
conversations
/
{id}
/
messages
List conversation messages
curl --request GET \
  --url https://app.puffle.ai/api/conversations/{id}/messages \
  --header 'Authorization: Bearer <token>'
{
  "messages": [
    {
      "id": "11111111-2222-3333-4444-555555555555",
      "user_id": "11111111-1111-1111-1111-111111111111",
      "conversation_id": "f11e8a2c-1234-4567-89ab-cdef01234567",
      "campaign_id": "8c2b2d4e-e29b-41d4-a716-446655440000",
      "direction": "outbound",
      "message_type": "message",
      "subject": null,
      "body_text": "Hi Jane — quick question about Acme's ops stack.",
      "body_html": null,
      "sender_name": "Sid",
      "sender_identifier": "unipile_user_sid",
      "external_id": "unipile_msg_1",
      "sent_at": "2026-04-20T15:02:00Z",
      "created_at": "2026-04-20T15:02:00Z"
    },
    {
      "id": "22222222-3333-4444-5555-666666666666",
      "user_id": "11111111-1111-1111-1111-111111111111",
      "conversation_id": "f11e8a2c-1234-4567-89ab-cdef01234567",
      "campaign_id": null,
      "direction": "inbound",
      "message_type": "message",
      "subject": null,
      "body_text": "Thanks for reaching out — happy to chat next week.",
      "body_html": null,
      "sender_name": "Jane Doe",
      "sender_identifier": "unipile_user_jane",
      "external_id": "unipile_msg_2",
      "sent_at": "2026-04-22T09:12:00Z",
      "created_at": "2026-04-22T09:12:05Z"
    }
  ],
  "total": 2,
  "page": 1,
  "limit": 50
}

Overview

Returns paginated messages for a conversation ordered sent_at ASC. Defaults to 50 per page, max 200. No side effects — unlike getConversation, this does not reset unread_count. Conversations and their messages are the inbox surface for campaign replies — they are created and kept in sync by inbound webhooks (Unipile message_received, AgentMail message.received).
This operation shares the URL path /api/conversations/{id}/messages with the send verb. See Send a conversation message to dispatch an outbound reply through Unipile (LinkedIn) or AgentMail (email).

AI agent notes

Safe to poll. GET is a pure DB read that does not mutate unread_count. If you want to mark messages as read, fetch getConversation instead.Pagination. Defaults to 50 per page, max 200. Use the returned hasMore flag plus offset to walk the full thread.Ordering. Messages are returned oldest-first (sent_at ASC), matching how they render in the inbox UI. The caller can reverse client-side if needed.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

id
string<uuid>
required

Conversation UUID. Must be owned by the authenticated user — other callers get 404.

Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$

Query Parameters

page
integer

1-indexed page number. Defaults to 1.

Required range: 0 < x <= 9007199254740991
limit
integer

Page size. Defaults to 50, max 200.

Required range: 0 < x <= 200

Response

Paginated messages for the conversation.

messages
object[]
required

Messages ordered sent_at ASC (oldest first). message_type includes "message" and provider-specific events like "connection_request" for LinkedIn.

total
integer
required

Total messages in the thread across all pages. Use for pagination UI.

Required range: 0 <= x <= 9007199254740991
page
integer
required
Required range: 0 < x <= 9007199254740991
limit
integer
required
Required range: 0 < x <= 9007199254740991