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

Reply to a contact

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
POST /inbox/contacts/{contactId}/reply

Sends a reply to a contact on a specific channel and appends it to the timeline. Each channel has its own requirements:

FieldTypeRequiredDescription
channel"email" \| "linkedin"YesChannel to send on.
bodystringYesMessage text, at least 1 character.
subjectstringEmail onlyRequired when channel is "email". A Re: prefix is added if missing.
sourceAccountIdstringYesID of the connected account to send from (email account or LinkedIn account, matching channel). Must belong to your workspace, otherwise 400 invalid_source_account.
bash
curl -X POST https://app.warmerly.com/api/v1/inbox/contacts/c3a1f6e2-9c4d-4e2a-8b5f-6a2c1d9e0f7b/reply \
  -H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "channel": "email",
        "subject": "Re: Quick question about your workflow",
        "body": "Great, does Tuesday at 3pm work for a quick call?",
        "sourceAccountId": "8f14e45f-ceea-4c6a-8c8d-6b1a5b5c9c1a"
      }'
json
{
  "message": {
    "id": "7f3a2cdb-9e1a-4f0c-8b6d-2e5f7a1c3b9d",
    "channel": "email",
    "direction": "outbound",
    "status": "sent",
    "contactId": "c3a1f6e2-9c4d-4e2a-8b5f-6a2c1d9e0f7b",
    "accountId": "8f14e45f-ceea-4c6a-8c8d-6b1a5b5c9c1a",
    "subject": "Re: Quick question about your workflow",
    "bodyText": "Great, does Tuesday at 3pm work for a quick call?",
    "toAddrs": ["jamie@northwindtraders.com"],
    "fromAddr": "you@yourcompany.com",
    "receivedAt": "2026-07-01T16:42:03.000Z"
  }
}

message is the stored message row, so it carries more fields than shown here. For email, the stored bodyText is the text you sent plus your mailbox signature and the quoted message you replied to.

Notes on behaviour by channel:

  • Email sends synchronously over SMTP; the contact must have an email on file and subject is required. If the contact already has an email thread in your workspace, the reply goes out from the mailbox that thread started on, even if sourceAccountId names another of your mailboxes. A send failure returns 500 with the SMTP error message, but the failed message is still recorded in the timeline with status: "failed".
  • LinkedIn sends synchronously through your connected LinkedIn account; the contact must have a linkedinProfileId on file. A send failure returns 500 and is recorded as failed, as for email. Some account types cannot send yet and return 400 (for example native_send_not_ready).

Missing channel-specific data returns 400 (contact_has_no_email, subject_required, contact_has_no_linkedin, contact_has_no_phone); a body that fails validation returns 400 invalid_body; and a contact that is not in your workspace returns 404. For example:

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