Drafts

Create a draft

Draft a message, InMail or connection request for a lead. Nothing is sent until a member approves it in the Needle inbox, where they can also edit or discard it. A conversation (account and lead) has one draft waiting at a time: creating another replaces a waiting draft created through the API, which is discarded as `superseded`. A draft a campaign step holds is never replaced; creating one then fails until it is reviewed.

POST

/api/v1/drafts

Request bodyrequired

connectedAccountIdrequired

string · uuid

The account that sends it. Its channel must match `action`.

leadIdrequired

string · uuid

The lead it goes to.

actionrequired

"linkedin_message" | "linkedin_inmail" | "linkedin_invitation" | "instagram_message"

`linkedin_invitation` sends a connection request with `text` as its note.

textrequired

string

Sent exactly as written, so {{variables}} are not allowed. Up to 300 characters for a connection note and 1900 for an InMail.

subjectoptional

string

Required for `linkedin_inmail`, not allowed otherwise.

Response

201Draft created and waiting for review.

draft

object

id

string · uuid

status

"awaiting_review" | "sent" | "failed" | "discarded"

`awaiting_review` until a member approves or discards it in the Needle inbox. Approving sends it right away: it becomes `sent`, or stays `awaiting_review` with `lastError` when the send fails. `failed` means it could not be sent and cannot be approved again; `discarded` means it will not be sent.

channel

"linkedin" | "instagram"

action

"linkedin_message" | "linkedin_inmail" | "linkedin_invitation" | "instagram_message"

text

string

What will be sent, or was sent. A member may edit it before approving.

subject

string | null

The InMail subject.

lead

object

id

string · uuid

name

string | null

connectedAccountId

string · uuid

campaignId

string · uuid | null

Set when a campaign step drafted the message.

taskId

string · uuid | null

The campaign task the draft holds. Null for API drafts.

discardReason

"rejected" | "superseded" | "withdrawn" | "enrollment_stopped" | "campaign_archived" | "task_cancelled" | null

lastError

string | null

Why the last attempt to send it failed.

createdBy

string · uuid | null

The member who created it. Null when a campaign step did.

reviewedBy

string · uuid | null

The member who approved or discarded it.

reviewedAt

string · date-time | null

createdAt

string · date-time

updatedAt

string · date-time

requestId

string · uuid

Id of this request, for support and troubleshooting

Errors

  • 400: Bad request
  • 401: Unauthorized: missing or invalid API key
  • 403: Forbidden
  • 404: Not found
  • 409: The lead has no profile on the account’s channel, is on the do-not-contact list, or a campaign step already has a draft waiting in this conversation.
  • 422: Invalid request payload

Search docs

Search documentation, API reference, and MCP tools

We use cookies to enhance your experience on Needle and keep your data secure. Privacy Policy