Less boo. More booked. Halloween offer: 30 days free on any paid plan. Claim 30 days freeEvery new account gets one free mailbox for warmup and replies. No domain to buy. See how it works

Skip to content

Get a contact's timeline

API referenceInbox

From the Inbox API reference. Requests use the base URL https://app.warmerly.com/api/v1 and an API key, see Authentication.

text
GET /inbox/contacts/{contactId}/timeline

Returns the full conversation with a contact across all channels, in chronological order (the most recent 200 messages), plus any autosaved email draft in progress for the latest inbound thread. Reading a timeline marks its unread messages as read, as opening the conversation in the dashboard does. Add ?preview=1 to read without marking anything read.

bash
curl https://app.warmerly.com/api/v1/inbox/contacts/c3a1f6e2-9c4d-4e2a-8b5f-6a2c1d9e0f7b/timeline \
  -H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
json
{
  "items": [
    {
      "id": "9d1e0b7a-5e7b-4f10-b2aa-1c8f0d3e6a4b",
      "channel": "email",
      "direction": "inbound",
      "status": "sent",
      "content": "Hi, thanks for the intro, happy to learn more.",
      "bodyHtml": "<p>Hi, thanks for the intro, happy to learn more.</p>",
      "subject": "Re: Quick question about your workflow",
      "sentAt": "2026-06-30T11:05:00.000Z",
      "fromAddr": "jamie@northwindtraders.com",
      "fromName": "Jamie Rivera",
      "toAddrs": ["you@yourcompany.com"],
      "externalId": null,
      "error": null,
      "hasAttachments": false,
      "attachmentsMeta": null,
      "isWarmup": false,
      "sentBy": null
    },
    {
      "id": "7f3a2cdb-9e1a-4f0c-8b6d-2e5f7a1c3b9d",
      "channel": "email",
      "direction": "outbound",
      "status": "sent",
      "content": "Great, does Tuesday at 3pm work for a quick call?",
      "bodyHtml": null,
      "subject": "Re: Quick question about your workflow",
      "sentAt": "2026-07-01T16:42:03.000Z",
      "fromAddr": "you@yourcompany.com",
      "fromName": "Your Name",
      "toAddrs": ["jamie@northwindtraders.com"],
      "externalId": null,
      "error": null,
      "hasAttachments": false,
      "attachmentsMeta": null,
      "isWarmup": false,
      "sentBy": null
    }
  ],
  "draft": null,
  "latestSubject": "Re: Quick question about your workflow",
  "replyAccountId": "8f14e45f-ceea-4c6a-8c8d-6b1a5b5c9c1a",
  "contact": {
    "id": "c3a1f6e2-9c4d-4e2a-8b5f-6a2c1d9e0f7b",
    "category": "lead",
    "categoryReason": "Replied positively and asked to schedule a call"
  }
}
FieldTypeDescription
items[].channel"email" \| "linkedin"Channel the message was sent/received on.
items[].direction"inbound" \| "outbound"Who sent it.
items[].status"queued" \| "sent" \| "failed"Delivery status.
items[].contentstringPlain-text body (falls back to snippet if the full body wasn't stored).
items[].hasAttachmentsbooleanWhether the message has attachments.
items[].attachmentsMetaarray \| nullAttachment details (filename, contentType, size, part), usable with the attachment download endpoint.
items[].isWarmupbooleanTrue for Warmerly warmup traffic.
items[].sentBy"autopilot" \| null"autopilot" when LinkedIn AI Autopilot sent the message.
draftobject \| nullAutosaved email draft for the latest inbound email thread, if one exists (subject, bodyText).
latestSubjectstring \| nullSubject of the most recent message that has one.
replyAccountIdstring \| nullThe mailbox the email thread started on, which replies are sent from.

If contactId doesn't exist, or has no message in your workspace, this returns 404:

json
{ "error": { "code": "not_found", "message": "not_found", "details": null } }
Was this page helpful?