Command reference
Every ConnectSafely CLI command with its flags, types and a runnable example — generated from the same OpenAPI specification as the REST API docs.
91 commands, generated from the same specification that produces the REST API reference and the MCP server — so a command here cannot exist in one surface and be missing from another.
Every command also documents itself in the binary, offline and with no API key:
connectsafely commands --search invitation # find it
connectsafely schema send-connection-request # its parameters, as JSON
connectsafely send-connection-request --help # the same, for a personGlobal flags — --json, --fields, --dry-run, --output and the rest — work on
every command and are listed in Getting started.
| Group | Commands | Writes |
|---|---|---|
| Account & quota | 11 | 0 |
| Search & sourcing | 13 | 0 |
| Profiles & companies | 6 | 3 |
| Relationship actions | 6 | 4 |
| Inbox & messaging | 17 | 12 |
| Posts & engagement | 23 | 11 |
| Analytics | 7 | 0 |
| Groups | 3 | 0 |
| Events | 1 | 0 |
| Sales Navigator | 4 | 2 |
Account & quota
| Command | Summary | |
|---|---|---|
get-account-activity | read | Get account activity history |
get-account-premium-status | read | Get account premium status |
get-account-quota | read | Quota usage for one account |
get-account-status | read | Get account status |
get-account-status-by-id | read | Get specific account status |
get-connections | read | Get connections list |
get-organizations | read | Get user organizations |
get-profile-visitors | read | Get profile visitors |
get-received-invitations | read | Get received invitations |
get-sent-invitations | read | Get sent connection invitations |
list-linkedin-accounts | read | List connected LinkedIn accounts (lightweight + searchable) |
get-account-activity
Get account activity history.
GET /account/{accountId}/activity · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | yes | Unique identifier for the LinkedIn account (24-character hex string) |
connectsafely get-account-activity --account-id "$CONNECTSAFELY_ACCOUNT_ID"get-account-premium-status
Get account premium status.
GET /account/{accountId}/premium · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | yes | Unique identifier for the LinkedIn account (24-character hex string) |
connectsafely get-account-premium-status --account-id "$CONNECTSAFELY_ACCOUNT_ID"get-account-quota
Quota usage for one account.
GET /account/{accountId}/quota · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | yes | LinkedIn account id (24-character Mongo ObjectId). Must be an account you own or one shared with you through a workspace. |
connectsafely get-account-quota --account-id "$CONNECTSAFELY_ACCOUNT_ID"get-account-status
Get account status.
GET /account/status · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | Optional LinkedIn account ID. If omitted, returns the most recently used account. |
connectsafely get-account-statusget-account-status-by-id
Get specific account status.
GET /account/{accountId}/status · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | yes | Unique identifier for the LinkedIn account (24-character hex string) |
connectsafely get-account-status-by-id --account-id "$CONNECTSAFELY_ACCOUNT_ID"get-connections
Get connections list.
GET /connections · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--start-index | number | Starting index for pagination (0-indexed), counted in connections. Advance using nextStartIndex from the previous response, never by your requested limit — see limit. — min 0 | |
--limit | number | Upper bound on how many connections to return. LinkedIn serves a fixed page (10 today) and offers no page-size control, so limit can only NARROW that page — asking for 12 returns 10. Read count for what you actually got and nextStartIndex for where to continue. — max 12 — min 1 | |
--sort-by | string | Sort order for connections. Options: recentlyAdded (default), firstName, lastName. — recentlyAdded | firstName | lastName |
connectsafely get-connectionsget-organizations
Get user organizations.
GET /organizations · read-only
Takes no parameters beyond the global flags.
connectsafely get-organizationsget-profile-visitors
Get profile visitors.
POST /profile/visitors · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--time-range | string | Time range to filter visitors — past_7_days | past_30_days | past_90_days | past_1_year | PAST_7_DAYS | PAST_30_DAYS | PAST_90_DAYS | ALL_TIME | |
--count | number | Page size for pagination (visitors fetched per API request). Use maxVisitors to control the total limit. — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--fetch-all | boolean | When true, automatically paginates to fetch all visitors up to maxVisitors limit | |
--max-visitors | number | yes | Total number of visitors to retrieve. This is the primary limit - use this parameter to specify how many visitors you want (e.g., maxVisitors: 50 for 50 visitors). — max 500 — min 1 |
connectsafely get-profile-visitors --max-visitors 20get-received-invitations
Get received invitations.
GET /invitations/received · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--start-index | number | Pagination start index (0-indexed), counted in invitations. Advance using nextStartIndex from the previous response, not by a fixed step — LinkedIn chooses the page size (10 today) and it is not guaranteed. — min 0 |
connectsafely get-received-invitationsget-sent-invitations
Get sent connection invitations.
GET /invitations/sent · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--start-index | number | Pagination start index (0-indexed), counted in invitations. Advance using nextStartIndex from the previous response, not by a fixed step — LinkedIn chooses the page size and it is not guaranteed to be 10. — min 0 |
connectsafely get-sent-invitationslist-linkedin-accounts
List connected LinkedIn accounts (lightweight + searchable).
GET /accounts · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--q | string | Optional search term. Matches firstName / lastName / publicId (case-insensitive), an exact 24-hex account id, or a LinkedIn profile URL (the public_id slug is extracted). |
connectsafely list-linkedin-accountsSearch & sourcing
| Command | Summary | |
|---|---|---|
get-company-details | read | Get company details |
get-group-details | read | Get group details |
get-job-details | read | Get job details |
search-companies | read | Search LinkedIn companies |
search-geo-locations | read | Search geo locations |
search-groups | read | Search LinkedIn groups |
search-jobs | read | Search LinkedIn jobs |
search-people | read | Search LinkedIn people |
search-people-alias | read | Search LinkedIn people (alias) |
search-people-v2 | read | Search LinkedIn people (V2 - with auto-pagination) |
search-posts-v2 | read | Search LinkedIn posts (V2 - with auto-pagination) |
search-schools | read | Search schools |
search-service-categories | read | Search service categories |
get-company-details
Get company details.
POST /search/companies/details · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--company-id | string | yes | LinkedIn company ID from search results or company page URL |
connectsafely get-company-details --company-id 1234567get-group-details
Get group details.
POST /search/groups/details · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--group-id | string | yes | LinkedIn group ID from search results or group page URL |
connectsafely get-group-details --group-id 1234567get-job-details
Get job details.
POST /search/jobs/details · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--job-id | string | yes | LinkedIn job ID from search results |
connectsafely get-job-details --job-id 1234567890search-companies
Search LinkedIn companies.
POST /search/companies · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use for the search. If not provided, uses the default account. | |
--keywords | string | Search keywords for company name or description (used for regular LinkedIn search) | |
--url | string | Sales Navigator company search URL (e.g., https://www.linkedin.com/sales/search/company?query=...). Requires Sales Navigator license. When provided, uses Sales Navigator API with advanced filters like revenue and employee count. | |
--count | number | Total number of results to return. Pages are walked internally to reach it — see the rate-limit note. — max 100 — min 1 | |
--start | number | Row offset to start from (0-indexed). Need not land on a page boundary. — min 0 | |
--filters | object | Optional filters to narrow down search results |
connectsafely search-companiessearch-geo-locations
Search geo locations.
POST /search/geo · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use for the search. If not provided, uses the default account. | |
--keywords | string | yes | Location name to search for (e.g., "San Francisco", "United States", "London") |
--country-codes | string[] | Limit results to specific countries using ISO country codes (e.g., ["US", "GB"]) |
connectsafely search-geo-locations --keywords "VP Marketing"search-groups
Search LinkedIn groups.
POST /search/groups · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use for the search. If not provided, uses the default account. | |
--keywords | string | Search keywords for group name or description | |
--count | number | Number of results to return per page — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--filters | object | Optional filters to narrow down search results |
connectsafely search-groupssearch-jobs
Search LinkedIn jobs.
POST /search/jobs · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use for the search. If not provided, uses the default account. | |
--keywords | string | Search keywords for job title, company, or description | |
--count | number | Number of results to return per page — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--filters | object | Optional filters to narrow down search results |
connectsafely search-jobssearch-people
Search LinkedIn people.
POST /search/people · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use for the search. If not provided, uses the default account. | |
--keywords | string | Search keywords for name, title, company, or skills | |
--count | number | Number of results to return per page — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--url | string | Sales Navigator search URL. When provided, the search will use Sales Navigator Lead Search instead of regular LinkedIn search. The URL should contain /sales/search/ path (e.g., https://www.linkedin.com/sales/search/people?query=...). | |
--filters | object | Optional filters to narrow down search results |
connectsafely search-peoplesearch-people-alias
Search LinkedIn people (alias).
POST /people/search · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use for the search. If not provided, uses the default account. | |
--keywords | string | Search keywords for name, title, company, or skills | |
--count | number | Number of results to return per page — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--filters | object | Optional filters to narrow down search results |
connectsafely search-people-aliassearch-people-v2
Search LinkedIn people (V2 - with auto-pagination).
POST /search/people/v2 · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--keywords | string | Search keywords for name, title, company, or skills | |
--count | number | Total number of results to return. API will automatically paginate through LinkedIn pages (each page ~10 results) to collect this many. — max 100 — min 1 | |
--start | number | Starting offset (0-indexed). Used to calculate which page to start from. — min 0 | |
--filters | object | Optional filters to narrow down search results |
connectsafely search-people-v2search-posts-v2
Search LinkedIn posts (V2 - with auto-pagination).
POST /search/posts/v2 · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--keywords | string | Search keywords for post content | |
--count | number | Total number of posts to return. API will automatically paginate (10 per page) to collect this many. — max 50 — min 1 | |
--start | number | Starting offset (0-indexed) for pagination. — min 0 | |
--exact-search | boolean | When true (default), the keyword is wrapped in double quotes for an exact-phrase match. Set to false for a broader search that also matches individual terms. | |
--filters | object | Optional filters to narrow down search results |
connectsafely search-posts-v2search-schools
Search schools.
POST /search/schools · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use for the search. If not provided, uses the default account. | |
--keywords | string | yes | School name to search for (e.g., "Stanford", "Pune", "MIT") |
connectsafely search-schools --keywords "VP Marketing"search-service-categories
Search service categories.
POST /search/service-categories · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use for the search. If not provided, uses the default account. | |
--keywords | string | yes | Service category name to search for (e.g., "Fina", "Marketing", "Accounting") |
connectsafely search-service-categories --keywords "VP Marketing"Profiles & companies
| Command | Summary | |
|---|---|---|
endorse-skill | writes | Endorse a skill on a LinkedIn profile |
fetch-profile | read | Fetch LinkedIn profile information |
get-company-followers | read | Get company/organization followers |
get-profile | read | Fetch LinkedIn profile information (GET) |
send-company-follow-invitations | writes | Send company follow invitations |
visit-profile | writes | Visit a LinkedIn profile |
endorse-skill
Endorse a skill on a LinkedIn profile.
POST /endorse-skill · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--profile-id | string | yes | LinkedIn profile vanity URL slug (the part after linkedin.com/in/, e.g., "john-doe-123") |
--skill-id | string | Specific skill ID to endorse (from skills list) | |
--random | boolean | If true, randomly select an unendorsed skill to endorse |
connectsafely endorse-skill --profile-id ada-lovelacefetch-profile
Fetch LinkedIn profile information.
POST /profile · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--profile-id | string | yes | LinkedIn profile vanity URL slug (the part after linkedin.com/in/, e.g., "john-doe-123") |
--include-geo-location | boolean | Include detailed geo location data (city, country, coordinates) | |
--include-contact | boolean | Include contact info (email, phone) if visible to viewer | |
--include-experience | boolean | Include work experience history | |
--include-education | boolean | Include education history | |
--include-skills | boolean | Include skills with endorsement counts | |
--force-refresh | boolean | Skip cache and fetch fresh data from LinkedIn. Use sparingly as it counts against rate limit. |
connectsafely fetch-profile --profile-id ada-lovelaceget-company-followers
Get company/organization followers.
GET /organizations/{companyId}/followers · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--company-id | string | yes | LinkedIn company ID (numeric ID from organization URN) |
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--count | number | Number of followers to return per page (max 100) — max 100 — min 1 | |
--follower-type | string | Type of followers to retrieve: MEMBER (people) or PAGE (company pages) — MEMBER | PAGE |
connectsafely get-company-followers --company-id 1234567get-profile
Fetch LinkedIn profile information (GET).
GET /profile · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--profile-id | string | yes | LinkedIn profile vanity URL slug (the part after linkedin.com/in/, e.g., "john-doe-123") |
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--include-geo-location | boolean | Include detailed geo location data | |
--include-contact | boolean | Include contact info if visible | |
--force-refresh | boolean | Skip cache and fetch fresh data |
connectsafely get-profile --profile-id ada-lovelacesend-company-follow-invitations
Send company follow invitations.
POST /organizations/{companyId}/follow-invitations · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--company-id | string | yes | LinkedIn company ID (numeric ID from organization URN) |
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--profile-urns | string[] | yes | Array of LinkedIn profile URNs to invite (max 50 per request) |
connectsafely send-company-follow-invitations --company-id 1234567 --profile-urns 'urn:li:fsd_profile:ACoAAB1example'visit-profile
Visit a LinkedIn profile.
POST /profile/visit · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--profile-id | string | yes | LinkedIn profile vanity URL slug of the user to visit (the part after linkedin.com/in/, e.g., "john-doe-123") |
--account-id | string | LinkedIn account ID to use for the visit. If not provided, uses the default account. |
connectsafely visit-profile --profile-id ada-lovelaceRelationship actions
| Command | Summary | |
|---|---|---|
check-relationship | read | Check relationship status with profile |
check-relationship-specific-account | read | Check relationship status with specific account |
follow-user | writes | Follow or unfollow a LinkedIn profile |
respond-to-received-invitation | writes | Accept or ignore a received invitation |
send-connection-request | writes | Send a connection request |
withdraw-invitation | writes | Withdraw a sent connection invitation |
check-relationship
Check relationship status with profile.
GET /relationship/{profileId} · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--profile-id | string | yes | LinkedIn profile vanity URL slug (the part after linkedin.com/in/, e.g., "john-doe-123") |
connectsafely check-relationship --profile-id ada-lovelacecheck-relationship-specific-account
Check relationship status with specific account.
GET /relationship/{accountId}/{profileId} · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | yes | Unique identifier for the LinkedIn account to check from |
--profile-id | string | yes | Target LinkedIn profile vanity URL slug (the part after linkedin.com/in/, e.g., "john-doe-123") |
connectsafely check-relationship-specific-account --account-id "$CONNECTSAFELY_ACCOUNT_ID" --profile-id ada-lovelacefollow-user
Follow or unfollow a LinkedIn profile.
POST /follow · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--profile-id | string | LinkedIn profile vanity URL slug (the part after linkedin.com/in/, e.g., "john-doe-123"). Prefer profileUrn when available. | |
--profile-urn | string | LinkedIn profile URN (e.g., "urn:li:fsd_profile:ACoAABJefVoBrz2LR3f..."). Preferred over profileId. | |
--action | string | Action to perform: follow or unfollow the profile — follow | unfollow |
connectsafely follow-userrespond-to-received-invitation
Accept or ignore a received invitation.
POST /invitations/received/respond · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--action | string | yes | Action to perform on the invitation — ACCEPT | IGNORE |
--invitation-id | string | yes | LinkedIn invitation ID from the received invitation |
--validation-token | string | yes | Validation token from the received invitation |
--linked-in-invitation-type | string | yes | LinkedIn invitation type (e.g., GenericInvitationType_CONNECTION, GenericInvitationType_ORGANIZATION) |
--first-name | string | yes | First name of the inviter |
--last-name | string | yes | Last name of the inviter |
--profile-id | string | LinkedIn member ID (ACoAAA format). Optional, required for connection invitations. |
connectsafely respond-to-received-invitation --action ACCEPT --invitation-id invitation-1234567890 --validation-token validation-token-abc --linked-in-invitation-type 'YOUR_LINKED_IN_INVITATION_TYPE' --first-name Ada --last-name Lovelacesend-connection-request
Send a connection request.
POST /connect · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--profile-id | string | Target LinkedIn profile vanity URL slug (e.g., "john-doe-123"). Either this or profileUrn is required. Prefer profileUrn when available. | |
--profile-urn | string | Target LinkedIn profile URN (e.g., "urn:li:fsd_profile:ACoAABJefVoBrz2LR3f..."). Either this or profileId is required. Preferred over profileId. | |
--custom-message | string | Personalized connection message (max 300 characters). Leave empty for default request. |
connectsafely send-connection-requestwithdraw-invitation
Withdraw a sent connection invitation.
POST /invitations/withdraw · writes · destructive, needs --yes off a terminal
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--profile-id | string | yes | LinkedIn profile vanity URL slug (the part after linkedin.com/in/) of the person whose invitation to withdraw. This is the only required field. |
--member-id | string | LinkedIn member ID (ACoAAA format). Optional - will be auto-fetched from profile if not provided. | |
--first-name | string | First name of the person. Optional - will be auto-fetched from profile if not provided. | |
--last-name | string | Last name of the person. Optional - will be auto-fetched from profile if not provided. | |
--profile-urn | string | LinkedIn profile URN. Optional - will be auto-fetched from profile if not provided. | |
--invitation-id | string | LinkedIn invitation ID. Optional - will be auto-fetched from profile if not provided. |
connectsafely withdraw-invitation --profile-id ada-lovelaceInbox & messaging
| Command | Summary | |
|---|---|---|
check-email-support | writes | Check if profile supports email messaging |
conversation-exists | read | Check if a conversation exists with a profile |
conversations-delete-message | writes | Delete (recall) a message |
conversations-download-media | writes | Download media from message |
conversations-mark-unread | writes | Mark a conversation as unread |
conversations-react-message | writes | React or unreact to a message |
conversations-refresh | writes | Refresh conversation messages |
conversations-send-message | writes | Send message (with channel selection) |
conversations-star | writes | Star a conversation |
conversations-sync | writes | Trigger conversation sync |
conversations-sync-status | read | Get sync status |
conversations-unstar | writes | Unstar a conversation |
conversations-upload-attachment | writes | Upload message attachment |
get-conversation-messages | read | Get conversation messages |
get-inmail-credits | read | Get InMail credits |
list-conversations | read | List conversations |
send-group-message | writes | Send message with group context |
check-email-support
Check if profile supports email messaging.
POST /messaging/check-email-support · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--profile-id | string | LinkedIn profile vanity URL slug (e.g., "john-doe-123"). Prefer profileUrn when available. | |
--profile-urn | string | LinkedIn profile URN (e.g., "urn:li:fsd_profile:ACoAAFpqSoMB8vTqRbg4mN..."). Preferred over profileId. |
connectsafely check-email-supportconversation-exists
Check if a conversation exists with a profile.
GET /conversations/exists/{profileId} · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--profile-id | string | yes | LinkedIn profile vanity URL slug (the part after linkedin.com/in/, e.g., "john-doe-123") |
--account-id | string | LinkedIn account ID to check from. Omit to use the default account for the authenticated user. |
connectsafely conversation-exists --profile-id ada-lovelaceconversations-delete-message
Delete (recall) a message.
DELETE /conversations/{conversationUrn}/messages/{messageUrn} · writes · destructive, needs --yes off a terminal
| Flag | Type | Required | Description |
|---|---|---|---|
--conversation-urn | string | yes | Conversation URN (URL-encoded) |
--message-urn | string | yes | URN of the message to delete (URL-encoded) |
--account-id | string | LinkedIn account ID |
connectsafely conversations-delete-message --conversation-urn 'urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAB1example,2-abc==)' --message-urn 'urn:li:msg_message:(urn:li:fsd_profile:ACoAAB1example,2-abc==)'conversations-download-media
Download media from message.
POST /conversations/download-media · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | yes | LinkedIn account ID |
--url | string | yes | Media URL from message attachment (www.linkedin.com or media.licdn.com) |
connectsafely conversations-download-media --account-id "$CONNECTSAFELY_ACCOUNT_ID" --url 'https://example.com/file.pdf'conversations-mark-unread
Mark a conversation as unread.
PATCH /conversations/{conversationUrn}/mark-unread · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--conversation-urn | string | yes | Conversation URN (URL-encoded) |
connectsafely conversations-mark-unread --conversation-urn 'urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAB1example,2-abc==)'conversations-react-message
React or unreact to a message.
POST /conversations/{conversationUrn}/messages/{messageUrn}/react · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--conversation-urn | string | yes | Conversation URN (URL-encoded) |
--message-urn | string | yes | URN of the message to react to (URL-encoded) |
--account-id | string | LinkedIn account ID | |
--emoji | string | yes | Emoji to react with (e.g., "👍") |
--react | boolean | yes | true to add the reaction, false to remove it |
connectsafely conversations-react-message --conversation-urn 'urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAB1example,2-abc==)' --message-urn 'urn:li:msg_message:(urn:li:fsd_profile:ACoAAB1example,2-abc==)' --emoji 'YOUR_EMOJI' --react trueconversations-refresh
Refresh conversation messages.
POST /conversations/refresh · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID | |
--conversation-urn | string | yes | Conversation URN to refresh |
connectsafely conversations-refresh --conversation-urn 'urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAB1example,2-abc==)'conversations-send-message
Send message (with channel selection).
POST /conversations/send · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to send from. Accepted in this body OR as a query parameter. If omitted entirely, the most recently used account on the subscription is selected — on a multi-seat subscription that may not be the one you intend, and a send from an account that is not connected to the recipient fails with NOT_ENOUGH_INMAIL_CREDIT. Always pass it, and check the accountId echoed in the response. | |
--recipient-profile-id | string | Recipient LinkedIn profile vanity URL slug (e.g., "john-doe-123"). Prefer recipientProfileUrn when available. | |
--recipient-profile-urn | string | Recipient LinkedIn profile URN (e.g., "urn:li:fsd_profile:ACoAABJefVoBrz2LR3f..."). Preferred over recipientProfileId. | |
--conversation-urn | string | Existing conversation URN (skips recipient lookup) | |
--message | string | yes | Message text |
--subject | string | Message subject (optional) | |
--attachments | object[] | File attachments from the upload-attachment endpoint. Each item must wrap the upload response in a file key: [{ "file": { assetUrn, byteSize, mediaType, name } }]. Files uploaded with an image/* content type render inline as photos; others render as downloadable files. | |
--messaging-channel | string | Controls which messaging channel to use. Defaults to "auto" if not provided. Options: "auto" — automatically detects the best channel based on account premium status (Sales Navigator accounts use Sales Nav API, others use standard inbox). "sales_navigator" — explicitly send via Sales Navigator API. Use this when the user wants to send through Sales Navigator. Returns a 400 error with a clear message if the account does not have Sales Navigator. "linkedin_inbox" — explicitly send via standard LinkedIn inbox. Use this when the user wants to bypass Sales Navigator and send through the regular LinkedIn messaging, even if the account has a Sales Navigator subscription. — auto | sales_navigator | linkedin_inbox |
connectsafely conversations-send-message --message "Thanks for connecting — what are you working on?"conversations-star
Star a conversation.
PATCH /conversations/{conversationUrn}/star · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--conversation-urn | string | yes | Conversation URN (URL-encoded) |
connectsafely conversations-star --conversation-urn 'urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAB1example,2-abc==)'conversations-sync
Trigger conversation sync.
POST /conversations/sync · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID | |
--force | boolean | Force sync even if recently synced |
connectsafely conversations-syncconversations-sync-status
Get sync status.
GET /conversations/sync/status · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | Account ID (optional, returns all if omitted) |
connectsafely conversations-sync-statusconversations-unstar
Unstar a conversation.
PATCH /conversations/{conversationUrn}/unstar · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--conversation-urn | string | yes | Conversation URN (URL-encoded) |
connectsafely conversations-unstar --conversation-urn 'urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAB1example,2-abc==)'conversations-upload-attachment
Upload message attachment.
POST /conversations/upload-attachment · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID. If omitted, resolved from the authenticated user's default account. | |
--filename | string | Original file name including extension (e.g. "photo.png"). Defaults to "attachment" if omitted. |
connectsafely conversations-upload-attachmentget-conversation-messages
Get conversation messages.
GET /conversations/{conversationUrn}/messages · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--conversation-urn | string | yes | Conversation URN (URL-encoded) |
--account-id | string | LinkedIn account ID. Honoured as a FILTER: if the conversation does not belong to this account you get an empty messages array, not another seat's thread. Omit it and the conversation's own account is used. Required for a thread we have not synced yet (and for Sales Navigator threads), since there is no stored account to infer. | |
--count | number | Number of messages — max 100 — min 1 | |
--cursor | string | Timestamp cursor for older messages | |
--since | number | Timestamp to fetch messages newer than (polling). Returns oldest-first, unlike every other call here. Ignored when cursor is also supplied — paginating backwards and polling forwards are mutually exclusive, and cursor wins. | |
--sync | boolean | Wait for LinkedIn response (sync mode) |
connectsafely get-conversation-messages --conversation-urn 'urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAB1example,2-abc==)'get-inmail-credits
Get InMail credits.
GET /inmail/credits · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID. If omitted, uses the default account. | |
--debug | string | Set to "true" to include raw API response in the result. — true | false |
connectsafely get-inmail-creditslist-conversations
List conversations.
GET /conversations · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | Single LinkedIn account ID | |
--linkedin-account-ids | string | Comma-separated account IDs for multi-account batch | |
--count | number | Number of conversations. Served from our cache, so up to 100 is honoured. Pages that fall through to LinkedIn are capped at 25 by LinkedIn itself (a higher count is silently clamped there), so a deep page may return fewer rows than a shallow one for the same count. — max 100 — min 1 | |
--next-cursor | string | Pagination cursor — pass back the nextCursor from the previous response verbatim; never construct one. A plain timestamp pages our cache, a linkedin:-prefixed one continues the walk on LinkedIn. Drive the walk by nextCursor (or hasMore, which now always agrees with it) and stop when it is null. On a FILTERED listing (unreadOnly, labeledOnly, labelId, archived, snoozed, source=sales_navigator) the walk ends at the edge of our cache and returns nextCursor: null — LinkedIn cannot continue a filtered walk, so ending is deliberate rather than returning rows that do not match your filter. | |
--label-id | string | Filter by label ID | |
--labeled-only | boolean | Only labeled conversations |
connectsafely list-conversationssend-group-message
Send message with group context.
POST /messaging/send-group · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--recipient-profile-urn | string | yes | Recipient LinkedIn profile URN (e.g., "urn:li:fsd_profile:ACoAABJefVoBrz2LR3f..."). Preferred over recipientProfileId. |
--group-id | string | yes | LinkedIn group ID that both sender and recipient are members of |
--message | string | yes | Message content to send |
connectsafely send-group-message --recipient-profile-urn 'urn:li:fsd_profile:ACoAAB1example' --group-id 1234567 --message "Thanks for connecting — what are you working on?"Posts & engagement
| Command | Summary | |
|---|---|---|
comment-on-post | writes | Comment on a LinkedIn post |
create-post | writes | Create a LinkedIn post |
delete-scheduled-post | writes | Cancel a scheduled post |
get-all-post-comments | read | Get all comments from a post |
get-feed | read | Get the current user's LinkedIn home feed |
get-latest-posts | read | Get latest posts from a profile |
get-post-comments | read | Get comments from a post |
get-post-reactions | read | Get reactions from a post |
get-post-reactions-v2 | read | Get reactions from a post (v2 - with vanity names) |
get-reposts | read | Get the list of people who reposted a post |
get-scheduled-week | read | What is queued this week, and whether a boost slot is free |
like-comment | writes | Like a comment |
list-scheduled-posts | read | List scheduled posts |
react-to-post | writes | React to a LinkedIn post |
reply-to-comment | writes | Reply to a comment |
repost-post | writes | Repost a LinkedIn post |
schedule-post | writes | Schedule a LinkedIn post for later |
scrape-post | read | Scrape LinkedIn post details |
search-posts | read | Search posts by keyword |
upload-and-post | writes | Upload media and create a LinkedIn post (server-side) |
upload-complete | writes | Complete multipart video upload |
upload-document-status | read | Check document (PDF) processing status |
upload-init | writes | Initialize media upload — get pre-signed URL(s) |
comment-on-post
Comment on a LinkedIn post.
POST /posts/comment · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--post-url | string | yes | Full URL of the LinkedIn post to comment on |
--comment | string | yes | Comment text content. Supports @mentions and hashtags. When tagPostAuthor is true, place a {{author}} placeholder where the author tag should appear — otherwise the author name is prepended. |
--tag-post-author | boolean | When true, tags the post author with a real @mention that notifies them. The tag is inserted at a {{author}} placeholder in comment if present, otherwise the author name is prepended. | |
--company-urn | string | Company URN to post comment as company page instead of personal profile |
connectsafely comment-on-post --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504' --comment "This matches what we saw last quarter."create-post
Create a LinkedIn post.
POST /posts/create · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | Which connected account posts. Omit to use the default account. | |
--text | string | yes | The post body (max 3,000 characters). |
--visibility | string | Who can see the post. — ANYONE | CONNECTIONS_ONLY | |
--media-type | string | What you are posting. Use "image" for a carousel too (with assetUrns). — none | image | video | document | |
--asset-urn | string | Single uploaded asset from /posts/upload/init. Required for image / video / document (a single image, video, or PDF). | |
--asset-urns | object[] | Carousel only: 2–9 uploaded images. Each item is { assetUrn, altText? }. Use instead of assetUrn with mediaType "image". | |
--recipes | string[] | From /posts/upload/init. Required for video and document. | |
--alt-text | string | Accessibility alt text for a single image (mediaType "image"). | |
--title | string | Document title shown on the post (mediaType "document"). | |
--company-urn | string | Optional. Post as a company page you administer instead of your personal profile. Provide the company URN (e.g., "urn:li:fsd_company:105672170"). |
connectsafely create-post --text "Three things we learned this quarter…"delete-scheduled-post
Cancel a scheduled post.
DELETE /posts/schedule/{id} · writes · destructive, needs --yes off a terminal
| Flag | Type | Required | Description |
|---|---|---|---|
--id | string | yes | Scheduled post id, as returned by schedule-post or list-scheduled-posts. |
connectsafely delete-scheduled-post --id 'YOUR_ID'get-all-post-comments
Get all comments from a post.
POST /posts/comments/all · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--post-url | string | yes | Full URL of the LinkedIn post to get all comments from |
--batch-size | number | Number of comments to fetch per internal request — max 100 — min 10 | |
--max-comments | number | Maximum total comments to retrieve (safety limit) — max 5000 — min 10 |
connectsafely get-all-post-comments --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504'get-feed
Get the current user's LinkedIn home feed.
POST /feed · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--count | number | Number of feed posts to retrieve (max 50) — max 50 — min 1 | |
--start | number | Starting offset for pagination — min 0 | |
--sort-order | string | Feed sort order: relevance (default algorithm) or recent (newest first) — relevance | recent |
connectsafely get-feedget-latest-posts
Get latest posts from a profile.
POST /posts/latest · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--profile-id | string | LinkedIn profile vanity URL slug (the part after linkedin.com/in/, e.g., "john-doe-123"). When possible, use profileUrn instead for more reliable results. | |
--profile-urn | string | LinkedIn profile URN (e.g., "urn:li:fsd_profile:ACoAABJefVoBrz2LR3f..."). Preferred over profileId — avoids an extra API call to resolve the vanity name. | |
--count | number | Number of recent posts to retrieve (max 20) — max 20 — min 1 | |
--include-reposts | boolean | Whether to include reposts/shares in results |
connectsafely get-latest-postsget-post-comments
Get comments from a post.
POST /posts/comments · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--post-url | string | yes | Full URL of the LinkedIn post to get comments from |
--comment-count | number | Number of comments per page (enables pagination mode) — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--pagination-token | string | Token from previous response to fetch next page | |
--max-comments | number | Maximum total comments to retrieve — max 5000 — min 10 | |
--batch-size | number | Internal batch size for fetching — max 100 — min 10 |
connectsafely get-post-comments --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504'get-post-reactions
Get reactions from a post.
POST /posts/reactions · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--post-url | string | yes | Full URL of the LinkedIn post to get reactions from |
--count | number | Number of reactions per page (default 10) — max 100 — min 1 | |
--pagination-token | string | Token from previous response to fetch next page | |
--page-token | string | Deprecated alias for paginationToken, kept for existing v2 clients | |
--start | number | Deprecated. LinkedIn pages this endpoint by token only, so this value is ignored. Use paginationToken. — min 0 |
connectsafely get-post-reactions --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504'get-post-reactions-v2
Get reactions from a post (v2 - with vanity names).
POST /posts/reactions/v2 · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--post-url | string | yes | Full URL of the LinkedIn post to get reactions from |
--count | number | Number of reactions per page (default 10) — max 100 — min 1 | |
--pagination-token | string | Token from previous response to fetch next page | |
--page-token | string | Deprecated alias for paginationToken, kept for existing v2 clients | |
--start | number | Deprecated. LinkedIn pages this endpoint by token only, so this value is ignored. Use paginationToken. — min 0 |
connectsafely get-post-reactions-v2 --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504'get-reposts
Get the list of people who reposted a post.
POST /posts/reposts · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--post-url | string | yes | Full URL of the LinkedIn post to get reposters from |
--count | number | Number of reposters to request per page (default 50) — max 100 — min 1 | |
--start-index | number | Offset for pagination (default 0). Use pagination.nextStartIndex from the previous response. — min 0 | |
--token | string | Cursor token from a previous response (pagination.token). Required together with startIndex for subsequent pages. |
connectsafely get-reposts --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504'get-scheduled-week
What is queued this week, and whether a boost slot is free.
GET /posts/schedule/week · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | Scopes the post list and picks the workspace whose boost quota is reported. Omit to use the default account. | |
--week-start | string | Start of the 7-day window. Defaults to Monday 00:00 UTC of the current week. | |
--timezone | string | IANA name deciding which local day each post and boost slot falls on. Defaults to UTC. |
connectsafely get-scheduled-weeklike-comment
Like a comment.
POST /like-comment · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--comment-id | string | yes | ID of the comment to like (same format as used in reply endpoint, from /posts/comments response) |
--post-url | string | Optional post URL for referer header (helps with browser simulation) | |
--company-urn | string | Optional company URN if liking as a company page |
connectsafely like-comment --comment-id comment-1234567890list-scheduled-posts
List scheduled posts.
GET /posts/schedule/list · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | Only posts for this connected account. | |
--from | string | Earliest scheduledAt to include. | |
--to | string | Latest scheduledAt to include. | |
--status | string | DRAFT | PENDING | PUBLISHED | FAILED | |
--limit | integer | max 200 |
connectsafely list-scheduled-postsreact-to-post
React to a LinkedIn post.
POST /posts/react · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--post-url | string | yes | Full URL of the LinkedIn post to react to. Can also provide threadUrn directly instead. |
--thread-urn | string | Thread URN of the post. If provided, skips URL scraping for faster execution. | |
--reaction-type | string | Reaction type: LIKE (thumbs up), PRAISE (clap), APPRECIATION (heart), EMPATHY (caring), INTEREST (insightful), ENTERTAINMENT (funny) — LIKE | PRAISE | APPRECIATION | EMPATHY | INTEREST | ENTERTAINMENT | |
--company-urn | string | Company URN to react as company page instead of personal profile (e.g., "urn:li:fsd_company:123456"). Requires admin access to the company page. |
connectsafely react-to-post --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504'reply-to-comment
Reply to a comment.
POST /reply · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--comment-id | string | yes | ID of the comment to reply to (from /posts/comments response) |
--reply | string | yes | Reply text content. Supports hashtags. When mention is provided, place a {{user}} placeholder where the tag should appear — otherwise the tagged member's name is prepended. |
--mention | object | Optional @mention to tag a member in the reply. Produces a real LinkedIn tag that notifies the member (e.g. tag the original commenter). The visible tag replaces the {{user}} placeholder in reply (or is prepended if no placeholder is present). |
connectsafely reply-to-comment --comment-id comment-1234567890 --reply "Agreed — the second point especially."repost-post
Repost a LinkedIn post.
POST /posts/repost · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--post-url | string | Full URL of the LinkedIn post to repost. Will be scraped to extract URNs. | |
--share-urn | string | Share URN of the post (e.g., "urn:li:share:7416350085304987648"). Use if you already have the URN. | |
--ugc-post-urn | string | UGC Post URN (e.g., "urn:li:ugcPost:7417595827650519041"). Used as fallback if shareUrn not available. | |
--activity-urn | string | Activity URN for pre-repost signal (e.g., "urn:li:activity:7416350088379338752"). Optional but recommended. | |
--company-urn | string | Optional. Repost as a company page you administer instead of your personal profile. Provide the company URN (e.g., "urn:li:fsd_company:134684122"). |
connectsafely repost-postschedule-post
Schedule a LinkedIn post for later.
POST /posts/schedule · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | Which connected account posts. Omit to use the default account. | |
--text | string | yes | The post body (max 3,000 characters). |
--scheduled-at | string | When to publish, as an absolute UTC timestamp in the future. OMIT IT TO PUBLISH NOW — which still gives you the first comment on its natural delay, plus reposts and boost, in a single call. The response returns status PENDING with an id; read list-scheduled-posts for publishedUrl once it goes live. | |
--timezone | string | IANA timezone name stored with the post and used for boost day windows. Defaults to UTC. | |
--company-urn | string | Optional. Publish as a company page you administer instead of your personal profile. | |
--media-type | string | What you are posting. Use "image" for a carousel too (with assetUrns). Documents are not schedulable. — none | image | video | |
--file-url | string | Public URL of the image or video. The server downloads it and uploads it to LinkedIn, so you do not need to upload anything yourself. Max 30MB. Use this OR assetUrn/assetUrns, not both. | |
--asset-urn | string | Alternative to fileUrl: an asset you already uploaded via /posts/upload/init. | |
--asset-urns | object[] | Carousel only: 2-9 uploaded images, each { assetUrn, altText? }. Use instead of assetUrn with mediaType "image". | |
--recipes | string[] | From /posts/upload/init. Required for a pre-uploaded video; not needed with fileUrl. | |
--thumbnail-url | string | Preview image shown in the ConnectSafely composer. Generated for you when you pass an image fileUrl. Pass it yourself for video, or when supplying a pre-uploaded assetUrn — without one the composer shows no media for the post (the published post is unaffected). | |
--alt-text | string | Accessibility alt text for the image. Always set this. | |
--first-comment | string | Posted as a comment 20-30 seconds after the post goes live. | |
--reposts | object[] | Other connected accounts that reshare this post after a delay. | |
--boost | object | Optional engagement boost that runs after the post publishes. Requires a paid plan. |
connectsafely schedule-post --text "Three things we learned this quarter…"scrape-post
Scrape LinkedIn post details.
POST /posts/scrape · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--post-url | string | yes | Full LinkedIn post URL to scrape |
--account-id | string | LinkedIn account ID for authenticated scraping (gets more data than public) | |
--use-cache | boolean | Whether to use cached results if available | |
--max-cache-age | number | Maximum age of cached data in hours before refresh | |
--max-proxy-retries | number | Number of proxy rotation attempts on failure | |
--force-refresh | boolean | Force fresh scrape ignoring cache |
connectsafely scrape-post --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504'search-posts
Search posts by keyword.
POST /posts/search · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--keywords | string | yes | Search keywords to find in post content |
--count | number | Number of posts to return per page — max 500 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--date-posted | string | Filter by when post was published — past-24h | past-week | past-month | any-time | |
--sort-by | string | Sort order: relevance (best match) or date_posted (newest first) — relevance | date_posted | |
--author-job-titles | string[] | Filter by author job titles (e.g., ["CEO", "VP Marketing"]) | |
--exact-search | boolean | When true (default), the keyword is wrapped in double quotes for an exact-phrase match. Set to false for a broader search that also matches individual terms. |
connectsafely search-posts --keywords "VP Marketing"upload-and-post
Upload media and create a LinkedIn post (server-side).
POST /posts/upload-and-post · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID. If omitted, uses the default account. | |
--file-url | string | yes | Public URL of the file to download and upload to LinkedIn. Maximum 100MB. |
--text | string | yes | Post text content. |
--media-type | string | yes | Type of media being uploaded. — image | video |
--visibility | string | Post visibility. — ANYONE | CONNECTIONS_ONLY | |
--alt-text | string | Alt text for images. |
connectsafely upload-and-post --file-url 'https://example.com/chart.png' --text "Three things we learned this quarter…" --media-type imageupload-complete
Complete multipart video upload.
POST /posts/upload/complete · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | ||
--media-artifact-urn | string | yes | From /upload/init response. |
--multipart-metadata | string | From /upload/init response. | |
--part-upload-responses | object[] | yes |
connectsafely upload-complete --media-artifact-urn 'urn:li:digitalmediaMediaArtifact:D4E10AQexample' --part-upload-responses '[{}]'upload-document-status
Check document (PDF) processing status.
GET /posts/upload/document-status · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--asset-urn | string | yes | Document asset URN from /posts/upload/init. |
--account-id | string | LinkedIn account ID. If omitted, uses the default account. |
connectsafely upload-document-status --asset-urn 'urn:li:digitalmediaAsset:D4E10AQexample'upload-init
Initialize media upload — get pre-signed URL(s).
POST /posts/upload/init · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID. | |
--media-type | string | yes | image / video / document (PDF). Documents upload as SINGLE and require a processing poll (see /posts/upload/document-status). — image | video | document |
--file-size | number | yes | File size in bytes. |
--filename | string | yes | Filename with extension. |
--company-urn | string | Optional. When the post will be authored by a company page you administer, pass the company URN here so the uploaded asset is registered with the organization as owner. Required for company-page image/video posts — without it LinkedIn accepts the later share (HTTP 200) but silently creates no post (no share URN). Must match the companyUrn passed to /posts/create. |
connectsafely upload-init --media-type image --file-size 10 --filename chart.pngAnalytics
| Command | Summary | |
|---|---|---|
get-account-comments | read | List an account's own comments |
get-account-reactions | read | List an account's own reactions |
get-connection-count | read | Get exact connection count |
get-creator-dashboard | read | Get creator dashboard overview |
get-followers-analytics | read | Get followers analytics |
get-network-summary | read | Get "Manage my network" counts |
get-post-analytics-summary | read | Get per-post analytics |
get-account-comments
List an account's own comments.
GET /account/{accountId}/comments · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | yes | LinkedIn account ID (24-character hex string) |
--count | number | Number of comments to return per page — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed). Ignored when paginationToken is provided. — min 0 | |
--pagination-token | string | Token from a previous response to fetch the next page |
connectsafely get-account-comments --account-id "$CONNECTSAFELY_ACCOUNT_ID"get-account-reactions
List an account's own reactions.
GET /account/{accountId}/reactions · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | yes | LinkedIn account ID (24-character hex string) |
--count | number | Number of reactions to return per page — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed). Ignored when paginationToken is provided. — min 0 | |
--pagination-token | string | Token from a previous response to fetch the next page |
connectsafely get-account-reactions --account-id "$CONNECTSAFELY_ACCOUNT_ID"get-connection-count
Get exact connection count.
GET /analytics/connections/count · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If omitted, uses the default account. |
connectsafely get-connection-countget-creator-dashboard
Get creator dashboard overview.
GET /analytics/creator/dashboard · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If omitted, uses the default account. |
connectsafely get-creator-dashboardget-followers-analytics
Get followers analytics.
GET /analytics/followers · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--result-type | string | Type of analytics data to retrieve — AUDIENCES | CONTENT | ENGAGEMENT | GROWTH | |
--time-range | string | Time range for analytics data — past_7_days | past_14_days | past_30_days | past_90_days | past_year | custom | |
--line-chart-type | string | Granularity for line chart data — daily | weekly | monthly | |
--metric-type | string | Specific metric to retrieve | |
--start-date | string | Start date for custom range (YYYY-MM-DD) | |
--end-date | string | End date for custom range (YYYY-MM-DD) |
connectsafely get-followers-analyticsget-network-summary
Get "Manage my network" counts.
GET /analytics/network/summary · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If omitted, uses the default account. |
connectsafely get-network-summaryget-post-analytics-summary
Get per-post analytics.
POST /analytics/post/summary · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--post-url | string | yes | The post, named any way you have it: an activity id, a share or ugcPost id/urn, a /feed/update/ URL, a /posts/ slug, or an lnkd.in short link. |
--account-id | string | LinkedIn account ID to use. If omitted, uses the default account. |
connectsafely get-post-analytics-summary --post-url 'https://www.linkedin.com/feed/update/urn:li:activity:7429892659739029504'Groups
| Command | Summary | |
|---|---|---|
get-group-members | read | Get group members by group ID |
get-group-members-by-url | read | Get group members by group URL |
get-group-members-legacy | read | Get group members (legacy endpoint) |
get-group-members
Get group members by group ID.
POST /groups/members · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--group-id | string | yes | LinkedIn group ID (numeric ID from group URL) |
--count | number | Number of members to return per page (max 100) — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--membership-statuses | string[] | Filter by membership status: OWNER (group owners), MANAGER (group admins), MEMBER (regular members) | |
--typeahead-query | string | Search query to filter members by name |
connectsafely get-group-members --group-id 1234567get-group-members-by-url
Get group members by group URL.
POST /groups/members-by-url · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--group-url | string | yes | Full LinkedIn group URL (e.g., "https://www.linkedin.com/groups/12345") |
--count | number | Number of members to return per page (max 100) — max 100 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--membership-statuses | string[] | Filter by membership status: OWNER (group owners), MANAGER (group admins), MEMBER (regular members) | |
--typeahead-query | string | Search query to filter members by name |
connectsafely get-group-members-by-url --group-url 'https://www.linkedin.com/groups/1234567/'get-group-members-legacy
Get group members (legacy endpoint).
POST /group-members · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID to use. If not provided, uses the default account. | |
--group-url | string | Full LinkedIn group URL (e.g., "https://www.linkedin.com/groups/12345") | |
--group-urn | string | LinkedIn group URN (e.g., "urn:li:fsd_group:12345") | |
--group-id | string | LinkedIn group ID (numeric ID from group URL) | |
--count | number | Number of members to return per page — max 50 — min 1 | |
--start | number | Pagination offset (0-indexed) — min 0 | |
--membership-statuses | string[] | Filter by membership status: OWNER (group owners), MANAGER (group admins), MEMBER (regular members) | |
--typeahead-query | string | Search query to filter members by name |
connectsafely get-group-members-legacyEvents
| Command | Summary | |
|---|---|---|
get-event-attendees | read | Get event attendees |
get-event-attendees
Get event attendees.
GET /events/{eventId}/attendees · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--event-id | string | yes | LinkedIn event ID (numeric), full event URL, or search URL with eventAttending parameter. |
--account-id | string | LinkedIn account ID. If omitted, uses the default account. | |
--start | integer | Pagination offset (0-indexed). Increment by 10 to paginate. — min 0 | |
--count | integer | Number of attendees to return per page (max 100, LinkedIn typically returns 10). — max 100 — min 1 |
connectsafely get-event-attendees --event-id 1234567890Sales Navigator
| Command | Summary | |
|---|---|---|
sales-nav-get-thread | read | Get Sales Navigator thread with messages |
sales-nav-list-threads | read | List Sales Navigator threads |
sales-nav-mark-read | writes | Mark Sales Navigator thread as read |
sales-nav-send-message | writes | Send Sales Navigator message |
sales-nav-get-thread
Get Sales Navigator thread with messages.
GET /sales-nav/threads/{threadId} · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--thread-id | string | yes | Sales Navigator thread ID |
--account-id | string | LinkedIn account ID | |
--message-count | number | Number of messages — max 100 — min 1 |
connectsafely sales-nav-get-thread --thread-id thread-1234567890sales-nav-list-threads
List Sales Navigator threads.
GET /sales-nav/threads · read-only
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID | |
--count | number | Number of threads — max 50 — min 1 | |
--filter | string | Thread filter — INBOX | UNREAD | ARCHIVED | |
--page-starts-at | number | Pagination offset |
connectsafely sales-nav-list-threadssales-nav-mark-read
Mark Sales Navigator thread as read.
POST /sales-nav/mark-read · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID | |
--thread-id | string | yes | Thread ID to mark as read |
connectsafely sales-nav-mark-read --thread-id thread-1234567890sales-nav-send-message
Send Sales Navigator message.
POST /sales-nav/send · writes
| Flag | Type | Required | Description |
|---|---|---|---|
--account-id | string | LinkedIn account ID | |
--thread-id | string | Existing thread ID to reply to | |
--recipients | string[] | Profile URNs for new conversation (required if no threadId) | |
--body | string | yes | Message text |
--copy-to-crm | boolean | Copy message to CRM |
connectsafely sales-nav-send-message --body "Thursday at 10 works."Getting started
Install the ConnectSafely CLI and run your own LinkedIn account from a terminal, a CI job or an AI agent — no server to host, no protocol to speak.
Agent skills
Eight skills ship inside the CLI that teach Claude Code, Cursor and any other agent how to use it well — installable into your project with one command.
