schemas/message
The Message object returned by message/get and prospect/messages_by_id.
| field | type | constraints | description |
|---|---|---|---|
| messageId | string | Unique identifier (SentID or ReplyID depending on type). | |
| createdAt | string | date-time | When the message was created or sent. |
| type | string | one of: Sent, Reply, SentManual | Message direction/origin. |
| campaignId | integer | int64 | Campaign this message belongs to, if applicable. |
| followupId | integer | int64 | Followup (FUID) this message belongs to, if applicable. |
| fromEmail | string | Sender email address. | |
| toEmail | string | Recipient email address. | |
| subject | string | Email subject line. | |
| body | string | Email body content (HTML; sanitize on the client side). In a list response, a body over 1,500 characters arrives as a plain-text preview unless you pass fullBodies: true — see schemas/pagination. |
|
| openCount | integer | Times this message was opened. Sent messages only. | |
| clickCount | integer | Times links in this message were clicked. Sent messages only. | |
| clickDetails | array | Per-link click details. Sent messages only. | |
| clickDetails[].url | string | URL that was clicked. |
Open/click tracking is counts only (
openCount,clickCount, per-link URLs inclickDetails). No device, email-client, geolocation, or user-agent data exists anywhere in the platform.
Bounces are not messages
Bounce state lives on the campaign (aggregate bounceCount) and on each prospect (sendingStatus: BounceHard | BounceSoft) — not in message records. No message row carries a bounce flag, and a bounce is never a Sent row that changed state. What does show up is the provider's delivery-failure notice arriving back as an ordinary Reply row like any other inbound mail — so counting Reply rows counts neither bounces nor human replies. confirmedStatus is a Reply-only query filter that classifies genuine reply emails; to enumerate bounced contacts, use the sendingStatus filter on prospect/get.