Send message
Queue a new LinkedIn DM to a 1st-degree connection (rate-safe).
Tool: send_message
Fails with active_campaign_conflict if the person has an active sequence enrollment - the error's recommended_next carries a prefilled stop_sequence_and_send to stop it and send in one call. DMs only deliver to people connected with the sending seat: fails with not_connected otherwise - use send_connection_request for a first touch (the note can carry the message), or check_linkedin_connection to verify and record an existing connection.
Parameters
| Param | Type | Required | Description |
|---|---|---|---|
person_id | string (slug or UUID) | no | Recipient. One of person_id / linkedin_url is required. |
linkedin_url | string | no | OR message by LinkedIn profile URL - matches the existing person; someone not yet imported is created, enriched (best-effort), and filed into today's misc lead group. A URL pasted into person_id is treated the same way. Alias: profile_url. |
body | string | yes | Message text. Alias: text. |
connected_account_id | string (slug or UUID) | no | Sender seat. Alias: account_id. Default: the only connected seat. |
Template variables ({{first_name}}, {{custom.<key>}}, ...) render at queue time: unknown names →
validation_error; names the person has no value for →missing_variables- empty text is never sent.Queued, not instant - sends respect rate limits and working hours (see
schedules.md).Blocked with
active_campaign_conflictwhen the person has an active enrollment - the error'srecommended_nextcarries a prefilledstop_sequence_and_send.DMs only deliver to 1st-degree connections of the sending seat: fails with
not_connectedunless the person is a confirmed connection or has an existing message thread. First touch for anyone else →send_connection_request; already connected but unrecorded →check_linkedin_connectionverifies and unblocks.
Sample request
{
"person_id": "marco-rossi-0004",
"body": "Hi Marco — saw your post on PLG onboarding, would love to compare notes."
}