---
title: "Send a LinkedIn direct message to a 1st-degree lead, starting the conversation if none exists"
method: POST
path: "/api/v1/messages"
tags: ["Messages"]
---

# Send a LinkedIn direct message to a 1st-degree lead, starting the conversation if none exists

`POST /api/v1/messages`

## Request

- Base URL: `https://app.reachium.io`
- URL: `https://app.reachium.io/api/v1/messages`
- Auth: HTTP bearer

Single-call, idempotent. The lead must belong to this workspace and be a 1st-degree connection of the sending account (this route can never cold-DM). Looks up any existing chat with that lead before creating one, so it is also safe to call when a conversation already exists. Draws from the SAME per-account daily message budget the outreach worker and MCP sendMessage use. Emits message.sent with details.source = "api". Use POST /api/v1/replies instead once you already have a chat_id and are continuing that thread.

## Headers

- `Idempotency-Key` string, required

## Request body

- object
  - `lead_id` string, uuid: Exactly one of lead_id or linkedin_url.
  - `linkedin_url` string: A LinkedIn profile URL (https://www.linkedin.com/in/...). Exactly one of lead_id or linkedin_url.
  - `linkedin_account_id` string, uuid: Which of this workspace’s LinkedIn accounts sends. Required when more than one account could plausibly send (ambiguous_sender otherwise).
  - `text` string, required

## Response `201`

Sent.

- object
  - `data` object, required
    - `chat_id` string, required
    - `created_chat` boolean, required
    - `lead_id` string, uuid, required
    - `linkedin_account_id` string, uuid, required
    - `sent_at` string, date-time, required
  - `error` unknown, required

## Other responses

- `400`: Missing/blank text, text over 4000 characters, neither or both of lead_id/linkedin_url passed, or a malformed lead_id/linkedin_account_id/linkedin_url (code invalid_request), or a missing Idempotency-Key header (code idempotency_key_required), or a malformed key (code invalid_idempotency_key).
- `401`: Missing or invalid API key. Send `Authorization: Bearer rmcp_...` (code unauthorized).
- `402`: Workspace billing is blocked; mutating requests are refused (code billing_blocked).
- `403`: The key's granted scopes do not satisfy this endpoint's minimum required scope (code insufficient_scope).
- `404`: lead_id (or the lead resolved from linkedin_url) is not in this workspace (code not_found).
- `409`: not_connected (the lead is not a 1st-degree connection), no_sender_account (no LinkedIn account can send), ambiguous_sender (pass linkedin_account_id to disambiguate), or request_in_flight (another call with this exact Idempotency-Key has an unresolved in-flight or ambiguous outcome; reconcile before choosing a new key).
- `422`: This Idempotency-Key was already used with a DIFFERENT body (code idempotency_key_reuse).
- `429`: daily_message_cap_reached; the response includes resets_at.
- `500`: Unhandled server error (code internal_error).
- `502`: The LinkedIn send itself failed at Unipile (code send_failed).
- `503`: cap_check_failed: the daily-cap check errored transiently (a DB error, not the limit itself). Retry now.

---

[API](https://skmtc.dev/reachium/apis/reachium-api.md) · [All operations](https://skmtc.dev/reachium/apis/reachium-api/llms.txt) · [OpenAPI document](https://skmtc.dev/reachium/apis/reachium-api/revisions/11682826692b?raw)
