recruiter.startChat
Start a Recruiter chat (InMail).
Prerequisites
- A Curviate API key, passed as
apiKeywhen you construct the client. Quickstart shows how to create one. - A connected LinkedIn account. This resource is account-scoped: the
account_idis injected automatically by the account-scoped accessor, so you pass it once tocurviate.account(...)and every call below inherits it. Quickstart covers connecting one, and accounts.list returns theaccount_idof each account already connected. - Requires a Recruiter subscription on the connected LinkedIn account. Without it, calls return
LINKEDIN_FEATURE_NOT_SUBSCRIBED(403); activate it on LinkedIn, as reconnecting will not help.
Signature
startChat(body: RecruiterStartChatBody): Promise<RecruiterStartChatResult>Example
import { Curviate } from "@curviate/sdk";
const curviate = new Curviate({
apiKey: "cvt_live_...",
baseUrl: "https://api.curviate.com",
});
const result = await curviate.account("acc_YOUR_ACCOUNT_ID").recruiter.startChat({ attendees_ids: ["YOUR_PROFILE_ID"], text: "Thanks for reaching out, happy to help.", subject: "Quick question", signature: "YOUR_SIGNATURE" });
console.log(result.chat_id);Parameters
| Name | Type | Required | Description |
|---|---|---|---|
attendees_ids | array | Yes | One or more Recruiter member IDs (AE... format) to include in the chat. |
text | string | Yes | Opening message text (1-8000 chars). This call keeps nothing and logs nothing. Once sent it is a message in the account's InMail inbox, so reading that chat back through Curviate stores its body in your tenant's inbox records, with no expiry. |
subject | string | Yes | Subject line; REQUIRED for Recruiter (InMail-based messaging), unlike the classic surface (<= 200 chars). |
signature | string | Yes | Sender signature; REQUIRED for Recruiter. Kept as a field by neither this call nor the log. The platform renders it into the sent message body, which is stored if that chat is later read back through Curviate. |
visibility | string | No | Visibility of the recruiter chat. |
intent | string | No | Whether this outreach is on behalf of a client or the operator's own company. |
send_as | string | No | Send the opening message as an InMail or as email. |
channel_type | string | No | Sourcing channel for tracking purposes (e.g. CAREER_SITE, MANUAL_IMPORT, INTERNAL_CANDIDATES, RECRUITER_SEARCH, REFERRAL; the vendor's own vocabulary is broader than this illustrative set, so any non-empty value is accepted rather than a closed enum). |
follow_up | object | No | Recruiter PRO only: schedule a follow-up message. subject: This call keeps nothing and logs nothing, and unlike the message body the platform does not render it into what is sent. Once sent it is an InMail in the account's inbox: if a message read surfaces this subject, reading that chat back stores it in your tenant's inbox records like a body, with no expiry. text: This call keeps nothing and logs nothing. Once sent it is a message in the account's InMail inbox, so reading that chat back through Curviate stores its body in your tenant's inbox records, with no expiry. |
attachments | array | No | Optional file / voice / video attachments (base64-encoded). |
Returns
Resolves to RecruiterStartChatResult. Top-level fields: object, chat_id, message_id, safety_warning.
Error codes
| Code | What it means, and what to do |
|---|---|
UNAUTHORIZED | The API key is missing, malformed, or revoked. Check the key you passed to the client. |
INVALID_REQUEST | A parameter failed validation. The message names the offending field; fix the request rather than retrying it. |
RATE_LIMIT_ACCOUNT | This account's own quota is exhausted. Wait for the window in the Retry-After header, then retry. |
RATE_LIMIT_TENANT | The tenant-wide quota is exhausted across all accounts. Slow the whole workload, not just this call. |
PLATFORM_RATE_LIMIT | LinkedIn is throttling this account. Back off well beyond the hinted delay; sustained pressure risks the account. |
PLATFORM_ERROR | An upstream failure, usually transient: retry once with backoff before treating it as a real error. Check the response first, though. When it carries retry_likely_to_succeed: false and retry_hint: {kind: "never"}, retrying cannot help and backing off only delays the real answer. |
ACCOUNT_NOT_FOUND | No connected account with that id belongs to this tenant. List your accounts to get a current id. |
ACCOUNT_RESTRICTED | LinkedIn has restricted the account, so it cannot act until that is cleared. Retrying will not help. |
INTERNAL | An unexpected server error. Retry once; if it persists, it is ours, not yours. |
LINKEDIN_AUTH_FAILED | LinkedIn rejected the credentials. Confirm them with the account owner. |
LINKEDIN_FEATURE_NOT_SUBSCRIBED | The connected LinkedIn account does not have the subscription this operation needs. Activate it on LinkedIn; reconnecting will not help. |
NO_ACTIVE_SEAT | The targeted account is not on an active seat. Buy or attach a seat in Billing, then retry. |
PAYLOAD_TOO_LARGE | Three limits can trigger this. The platform's own ceiling on total request size is the lowest and the one you are most likely to hit: it starts rejecting at roughly 1 MB, so a handful of photo-sized images is refused even though it clears everything below. Above that, this API caps one attachment at 5 MiB of file content and the whole request body at 9 MiB. Attachments travel base64-encoded, which inflates them by about a third, so a 5 MiB file costs roughly 6.7 MiB of the body budget. Send fewer or smaller attachments; retrying unchanged will not help. |
RESOURCE_NOT_FOUND | The id in the path does not exist, or is not visible to this account. Re-read it from the list endpoint that produced it. |
UNSUPPORTED_MEDIA_TYPE | The request was not sent as JSON. Every endpoint takes application/json, including file attachments, which travel base64-encoded. |
Every code above is a stable CurviateError.code you can branch on. The full list, the response envelope, and retry semantics are in the Error codes reference.
Next steps
recruiter.listApplicants: List applicants in a project's talent pool (POST-as-list; the body carries filters, no state mutates).recruiter.listJobs: List Recruiter job postings.recruiter.listPipeline: List candidates in a project's pipeline (POST-as-list; the body carries an all-optional filter set, no state mutates).- SDK Quick Start: installation, the client, account scoping, and pagination.