Inbox

Replace lead

Replaces the thread lead with a new contact and optionally queues a forward job.

Two modes, reported in the response mode field:

  • created — the address is new to this campaign. A lead is inserted, the conversation moves to them, and the original lead is archived.
  • attached — the address is already a live lead in this campaign. That existing contact is reused (their profile and sequence stay as they are), the conversation moves to them, the original lead is retired as stopped/replaced, and any duplicate rows for the same address have their sequences stopped (retired_sibling_count). On attach, new_lead_id and target_lead_id are that pre-existing contact.

Attach happens automatically when the address matches; there is no opt-in flag. The call fails with 409 target_missing_enrollment when the existing contact has no live enrollment (nothing to send against). Prefer calling previewThreadLeadReplacement first to inspect mode, allowed, block-list status, and disallowed_reason before writing.

POST/v1/threads/{id}/replace-lead

Authorization

bearerAuth
AuthorizationBearer <token>

Use an account API key in the Authorization header: Authorization: Bearer f_....

In: header

Path Parameters

idstring

Inbox thread id.

Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

new_emailstring
Formatemail
new_name?string
new_first_name?string
new_last_name?string
new_phone_number?string
new_mobile_phone_number?string
reason?string

Defaults to manual_referral when omitted.

Value in

  • "auto_reply_forward"
  • "manual_referral"
  • "wrong_contact"
  • "role_change"
  • "other"
reason_note?string
source_message_id?string
Formatuuid
forward_message_id?string
Formatuuid
curl -X POST "https://example.com/v1/threads/497f6eca-6276-4993-bfeb-53cbbbba6f08/replace-lead" \  -H "Content-Type: application/json" \  -d '{    "new_email": "referral@example.com",    "new_name": "Jane Doe"  }'
{  "data": {    "replacement_id": "8076ac29-0aa5-4b57-99a2-25a4517a9861",    "new_lead_id": "1a442062-8ce7-4e61-9b03-98697a478ee6",    "enrollment_id": "cd8e6b59-f5cf-4894-8850-4dc2dc1aaf8e",    "mode": "created",    "target_lead_id": "00970d14-f6dd-4dfb-98c8-c9a407078b5a",    "retired_sibling_count": 0,    "forward_job_id": "8325dffb-5cdb-4839-81bd-e3e01b2574de"  }}
{  "error": {    "type": "invalid_request_error",    "code": "invalid_flow",    "message": "Flow validation failed"  },  "details": [    {      "path": "nodes[1].data.variants[0].id",      "code": "invalid_variant_id",      "message": "Email variants must have a stable UUID id."    }  ]}
{  "error": {    "type": "authentication_error",    "code": "invalid_api_key",    "message": "A valid Furnace API key is required"  }}
{  "error": {    "type": "permission_error",    "code": "smartlead_read_only",    "message": "Smartlead campaigns are read-only via the API"  }}
{  "error": {    "type": "invalid_request_error",    "code": "campaign_not_found",    "message": "Campaign not found"  }}
{  "error": {    "type": "invalid_request_error",    "code": "target_missing_enrollment",    "message": "The existing contact for this address has no active enrollment in this campaign; launch the campaign or re-add the contact before replacing. Call GET /v1/threads/{id}/replace-lead/preview to inspect the match first."  }}
{  "error": {    "type": "rate_limit_error",    "code": "rate_limit_exceeded",    "message": "Rate limit exceeded for this account"  }}
{  "error": {    "type": "api_error",    "code": "internal_error",    "message": "Internal server error"  }}