Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ Every command supports these flags:
| `--no-color` | Disable colors |
| `--account "Name"` | Use a specific account for this command |

List flags documented as comma-separated split their value on every comma. When a value contains a comma itself – `Chicago, Illinois`, `Technology, Information and Internet`, `Example Co., Ltd.` – pass the whole list as a JSON array instead:

```bash
linkedin person search --term "designer" --locations '["Chicago, Illinois","London, United Kingdom"]' --json
```

---

## Command Reference
Expand Down Expand Up @@ -154,7 +160,8 @@ linkedin person search [flags]

| Flag | Type | Description |
|------|------|-------------|
| `--term` | string | Search keyword or phrase |
| `--term` | string | Search keyword or phrase; required unless `--url` is given |
| `--url` | string | LinkedIn people search URL (`linkedin.com/search/results/people/...`), such as the `searchUrl` of an anonymous viewer from `stats viewers`; overrides `--term` and the filters |
| `--limit` | integer | Max results to return |
| `--first-name` | string | Filter by first name |
| `--last-name` | string | Filter by last name |
Expand All @@ -167,8 +174,9 @@ linkedin person search [flags]

```bash
linkedin person search --term "revops engineer" --locations "San Francisco"
linkedin person search --current-companies "Linked API" --position "Engineer" --json
linkedin person search --schools "MIT" --industries "Software Development" --limit 20 --json
linkedin person search --term "engineer" --current-companies "Linked API" --json
linkedin person search --term "founder" --schools "MIT" --industries "Software Development" --limit 20 --json
linkedin person search --url "https://www.linkedin.com/search/results/people/?keywords=CTO" --json
```

---
Expand Down Expand Up @@ -229,15 +237,16 @@ linkedin company search [flags]

| Flag | Type | Description |
|------|------|-------------|
| `--term` | string | Search keyword or phrase |
| `--term` | string | Search keyword or phrase; required unless `--url` is given |
| `--url` | string | LinkedIn companies search URL (`linkedin.com/search/results/companies/...`); overrides `--term` and the filters |
| `--limit` | integer | Max results to return |
| `--sizes` | string | Company sizes, comma-separated (`1-10`, `11-50`, `51-200`, `201-500`, `501-1000`, `1001-5000`, `5001-10000`, `10001+`) |
| `--locations` | string | Comma-separated locations |
| `--industries` | string | Comma-separated industries |

```bash
linkedin company search --term "fintech" --sizes "11-50,51-200" --json
linkedin company search --industries "Software Development" --locations "Berlin" --json
linkedin company search --term "payments" --industries "Software Development" --locations "Berlin" --json
```

---
Expand Down Expand Up @@ -733,7 +742,8 @@ linkedin navigator person search [flags]

| Flag | Type | Description |
|------|------|-------------|
| `--term` | string | Search keyword or phrase |
| `--term` | string | Search keyword or phrase; required unless `--url` is given |
| `--url` | string | Sales Navigator people search URL (`linkedin.com/sales/search/people/...`); overrides `--term` and the filters |
| `--limit` | integer | Max results to return |
| `--first-name` | string | Filter by first name |
| `--last-name` | string | Filter by last name |
Expand All @@ -747,7 +757,7 @@ linkedin navigator person search [flags]

```bash
linkedin navigator person search --term "VP Marketing" --locations "United States"
linkedin navigator person search --years-of-experience "moreThanTen" --position "CEO" --json
linkedin navigator person search --term "CEO" --years-of-experience "moreThanTen" --json
```

#### `navigator company fetch`
Expand Down Expand Up @@ -792,7 +802,8 @@ linkedin navigator company search [flags]

| Flag | Type | Description |
|------|------|-------------|
| `--term` | string | Search keyword or phrase |
| `--term` | string | Search keyword or phrase; required unless `--url` is given |
| `--url` | string | Sales Navigator companies search URL (`linkedin.com/sales/search/company/...`); overrides `--term` and the filters |
| `--limit` | integer | Max results to return |
| `--sizes` | string | Company sizes, comma-separated (`1-10`, `11-50`, `51-200`, `201-500`, `501-1000`, `1001-5000`, `5001-10000`, `10001+`) |
| `--locations` | string | Comma-separated locations |
Expand All @@ -802,7 +813,7 @@ linkedin navigator company search [flags]

```bash
linkedin navigator company search --term "fintech" --sizes "11-50,51-200"
linkedin navigator company search --revenue-min 10 --revenue-max 100 --locations "United States" --json
linkedin navigator company search --term "logistics" --revenue-min 10 --revenue-max 100 --locations "United States" --json
```

#### `navigator message send`
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@linkedapi/linkedin-cli",
"version": "1.2.23",
"version": "1.2.24",
"description": "AI-agent-friendly CLI for controlling LinkedIn accounts and retrieving real-time data.",
"author": "Linked API",
"license": "MIT",
Expand Down
21 changes: 11 additions & 10 deletions src/commands/company/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Args, Flags } from '@oclif/core';
import { BaseCommand } from '@base-command';
import { formatOutput } from '@core/output/formatter';
import { runWorkflow } from '@core/workflow/workflow-runner';
import { splitListFlag } from '@utils/split-list-flag';

export default class CompanyFetch extends BaseCommand {
static override description = 'Fetch a LinkedIn company profile';
Expand Down Expand Up @@ -41,13 +42,16 @@ export default class CompanyFetch extends BaseCommand {
description: 'Filter employees by position',
}),
'employees-locations': Flags.string({
description: 'Filter employees by locations (comma-separated)',
description:
'Filter employees by locations (comma-separated, or a JSON array if a value contains a comma)',
}),
'employees-industries': Flags.string({
description: 'Filter employees by industries (comma-separated)',
description:
'Filter employees by industries (comma-separated, or a JSON array if a value contains a comma)',
}),
'employees-schools': Flags.string({
description: 'Filter employees by schools (comma-separated)',
description:
'Filter employees by schools (comma-separated, or a JSON array if a value contains a comma)',
}),
'employees-connection-degrees': Flags.string({
description: 'Filter employees by your connection degree (comma-separated: 1st,2nd,3rd+)',
Expand Down Expand Up @@ -90,15 +94,12 @@ export default class CompanyFetch extends BaseCommand {
if (flags['employees-last-name']) filter.lastName = flags['employees-last-name'];
if (flags['employees-position']) filter.position = flags['employees-position'];
if (flags['employees-locations'])
filter.locations = flags['employees-locations'].split(',').map((s) => s.trim());
filter.locations = splitListFlag(flags['employees-locations']);
if (flags['employees-industries'])
filter.industries = flags['employees-industries'].split(',').map((s) => s.trim());
if (flags['employees-schools'])
filter.schools = flags['employees-schools'].split(',').map((s) => s.trim());
filter.industries = splitListFlag(flags['employees-industries']);
if (flags['employees-schools']) filter.schools = splitListFlag(flags['employees-schools']);
if (flags['employees-connection-degrees'])
filter.connectionDegrees = flags['employees-connection-degrees']
.split(',')
.map((s) => s.trim());
filter.connectionDegrees = splitListFlag(flags['employees-connection-degrees']);

if (Object.keys(filter).length > 0) config.filter = filter;
if (Object.keys(config).length > 0) params.employeesRetrievalConfig = config;
Expand Down
29 changes: 22 additions & 7 deletions src/commands/company/search.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { Flags } from '@oclif/core';

import { BaseCommand } from '@base-command';
import { EXIT_CODE } from '@core/errors/exit-codes';
import { formatOutput } from '@core/output/formatter';
import { runWorkflow } from '@core/workflow/workflow-runner';
import { splitListFlag } from '@utils/split-list-flag';

export default class CompanySearch extends BaseCommand {
static override description = 'Search for companies on LinkedIn';

static override flags = {
...BaseCommand.baseFlags,
term: Flags.string({
description: 'Search keyword or phrase',
description: 'Search keyword or phrase (required unless --url is given)',
}),
url: Flags.string({
description:
'LinkedIn companies search URL (linkedin.com/search/results/companies/...). Overrides --term and the filters',
}),
limit: Flags.integer({
description: 'Max results to return',
Expand All @@ -19,31 +25,40 @@ export default class CompanySearch extends BaseCommand {
description: 'Filter by company sizes (comma-separated, e.g. "1-10,11-50,51-200")',
}),
locations: Flags.string({
description: 'Filter by locations (comma-separated)',
description:
'Filter by locations (comma-separated, or a JSON array if a value contains a comma)',
}),
industries: Flags.string({
description: 'Filter by industries (comma-separated)',
description:
'Filter by industries (comma-separated, or a JSON array if a value contains a comma)',
}),
};

static override examples = [
'<%= config.bin %> company search --term "fintech" --sizes "11-50,51-200"',
'<%= config.bin %> company search --industries "Software Development" --json',
'<%= config.bin %> company search --term "payments" --industries "Software Development" --json',
];

public async run(): Promise<void> {
const { flags } = await this.parse(CompanySearch);

if (!flags.term && !flags.url) {
this.error('Either --term or --url is required; filters alone are not accepted.', {
exit: EXIT_CODE.VALIDATION,
});
}

const client = await this.buildAuthenticatedClient();

const params: Record<string, unknown> = {};
if (flags.term) params.term = flags.term;
if (flags.url) params.customSearchUrl = flags.url;
if (flags.limit) params.limit = flags.limit;

const filter: Record<string, unknown> = {};
if (flags.sizes) filter.sizes = flags.sizes.split(',').map((s) => s.trim());
if (flags.locations) filter.locations = flags.locations.split(',').map((s) => s.trim());
if (flags.industries) filter.industries = flags.industries.split(',').map((s) => s.trim());
if (flags.sizes) filter.sizes = splitListFlag(flags.sizes);
if (flags.locations) filter.locations = splitListFlag(flags.locations);
if (flags.industries) filter.industries = splitListFlag(flags.industries);

if (Object.keys(filter).length > 0) {
params.filter = filter;
Expand Down
26 changes: 16 additions & 10 deletions src/commands/connection/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Flags } from '@oclif/core';
import { BaseCommand } from '@base-command';
import { formatOutput } from '@core/output/formatter';
import { runWorkflow } from '@core/workflow/workflow-runner';
import { splitListFlag } from '@utils/split-list-flag';

export default class ConnectionList extends BaseCommand {
static override description = 'List your LinkedIn connections';
Expand All @@ -25,19 +26,24 @@ export default class ConnectionList extends BaseCommand {
description: 'Filter by job position',
}),
locations: Flags.string({
description: 'Filter by locations (comma-separated)',
description:
'Filter by locations (comma-separated, or a JSON array if a value contains a comma)',
}),
industries: Flags.string({
description: 'Filter by industries (comma-separated)',
description:
'Filter by industries (comma-separated, or a JSON array if a value contains a comma)',
}),
'current-companies': Flags.string({
description: 'Filter by current companies (comma-separated)',
description:
'Filter by current companies (comma-separated, or a JSON array if a value contains a comma)',
}),
'previous-companies': Flags.string({
description: 'Filter by previous companies (comma-separated)',
description:
'Filter by previous companies (comma-separated, or a JSON array if a value contains a comma)',
}),
schools: Flags.string({
description: 'Filter by schools (comma-separated)',
description:
'Filter by schools (comma-separated, or a JSON array if a value contains a comma)',
}),
};

Expand All @@ -59,13 +65,13 @@ export default class ConnectionList extends BaseCommand {
if (flags['first-name']) filter.firstName = flags['first-name'];
if (flags['last-name']) filter.lastName = flags['last-name'];
if (flags.position) filter.position = flags.position;
if (flags.locations) filter.locations = flags.locations.split(',').map((s) => s.trim());
if (flags.industries) filter.industries = flags.industries.split(',').map((s) => s.trim());
if (flags.locations) filter.locations = splitListFlag(flags.locations);
if (flags.industries) filter.industries = splitListFlag(flags.industries);
if (flags['current-companies'])
filter.currentCompanies = flags['current-companies'].split(',').map((s) => s.trim());
filter.currentCompanies = splitListFlag(flags['current-companies']);
if (flags['previous-companies'])
filter.previousCompanies = flags['previous-companies'].split(',').map((s) => s.trim());
if (flags.schools) filter.schools = flags.schools.split(',').map((s) => s.trim());
filter.previousCompanies = splitListFlag(flags['previous-companies']);
if (flags.schools) filter.schools = splitListFlag(flags.schools);

if (Object.keys(filter).length > 0) {
params.filter = filter;
Expand Down
40 changes: 21 additions & 19 deletions src/commands/jobs/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BaseCommand } from '@base-command';
import { EXIT_CODE } from '@core/errors/exit-codes';
import { formatOutput } from '@core/output/formatter';
import { runWorkflow } from '@core/workflow/workflow-runner';
import { splitListFlag } from '@utils/split-list-flag';

export default class JobsSearch extends BaseCommand {
static override description = 'Search for jobs on LinkedIn';
Expand Down Expand Up @@ -39,13 +40,16 @@ export default class JobsSearch extends BaseCommand {
description: 'Filter by workplace types (comma-separated: onSite, remote, hybrid)',
}),
companies: Flags.string({
description: 'Filter by company names (comma-separated)',
description:
'Filter by company names (comma-separated, or a JSON array if a value contains a comma)',
}),
industries: Flags.string({
description: 'Filter by industries (comma-separated)',
description:
'Filter by industries (comma-separated, or a JSON array if a value contains a comma)',
}),
'job-functions': Flags.string({
description: 'Filter by job functions (comma-separated)',
description:
'Filter by job functions (comma-separated, or a JSON array if a value contains a comma)',
}),
'easy-apply': Flags.boolean({
description: 'Only jobs with Easy Apply',
Expand Down Expand Up @@ -80,7 +84,8 @@ export default class JobsSearch extends BaseCommand {
'AI-powered search: prefer employment types (comma-separated: fullTime, partTime, contract, internship, volunteer)',
}),
'pref-companies': Flags.string({
description: 'AI-powered search: prefer company names (comma-separated)',
description:
'AI-powered search: prefer company names (comma-separated, or a JSON array if a value contains a comma)',
}),
'pref-remote': Flags.boolean({
description: 'AI-powered search: prefer remote jobs',
Expand All @@ -100,7 +105,7 @@ export default class JobsSearch extends BaseCommand {
}),
'pref-keywords': Flags.string({
description:
'AI-powered search: prefer skills, technologies or topics (comma-separated), such as AWS or Fintech',
'AI-powered search: prefer skills, technologies or topics (comma-separated, or a JSON array if a value contains a comma), such as AWS or Fintech',
}),
};

Expand All @@ -122,12 +127,13 @@ export default class JobsSearch extends BaseCommand {
const filter: Record<string, unknown> = {};
if (flags['date-posted']) filter.datePosted = flags['date-posted'];
if (flags['experience-levels'])
filter.experienceLevels = splitCsv(flags['experience-levels']);
if (flags['employment-types']) filter.employmentTypes = splitCsv(flags['employment-types']);
if (flags['workplace-types']) filter.workplaceTypes = splitCsv(flags['workplace-types']);
if (flags.companies) filter.companies = splitCsv(flags.companies);
if (flags.industries) filter.industries = splitCsv(flags.industries);
if (flags['job-functions']) filter.jobFunctions = splitCsv(flags['job-functions']);
filter.experienceLevels = splitListFlag(flags['experience-levels']);
if (flags['employment-types'])
filter.employmentTypes = splitListFlag(flags['employment-types']);
if (flags['workplace-types']) filter.workplaceTypes = splitListFlag(flags['workplace-types']);
if (flags.companies) filter.companies = splitListFlag(flags.companies);
if (flags.industries) filter.industries = splitListFlag(flags.industries);
if (flags['job-functions']) filter.jobFunctions = splitListFlag(flags['job-functions']);
if (flags['easy-apply']) filter.easyApply = true;
if (flags['has-verifications']) filter.hasVerifications = true;
if (flags['under-10-applicants']) filter.under10Applicants = true;
Expand All @@ -137,15 +143,15 @@ export default class JobsSearch extends BaseCommand {
const preferences: Record<string, unknown> = {};
if (flags['pref-date-posted']) preferences.datePosted = flags['pref-date-posted'];
if (flags['pref-experience-levels'])
preferences.experienceLevels = splitCsv(flags['pref-experience-levels']);
preferences.experienceLevels = splitListFlag(flags['pref-experience-levels']);
if (flags['pref-employment-types'])
preferences.employmentTypes = splitCsv(flags['pref-employment-types']);
if (flags['pref-companies']) preferences.companies = splitCsv(flags['pref-companies']);
preferences.employmentTypes = splitListFlag(flags['pref-employment-types']);
if (flags['pref-companies']) preferences.companies = splitListFlag(flags['pref-companies']);
if (flags['pref-remote']) preferences.remote = true;
if (flags['pref-easy-apply']) preferences.easyApply = true;
if (flags['pref-under-10-applicants']) preferences.under10Applicants = true;
if (flags['pref-in-your-network']) preferences.inYourNetwork = true;
if (flags['pref-keywords']) preferences.keywords = splitCsv(flags['pref-keywords']);
if (flags['pref-keywords']) preferences.keywords = splitListFlag(flags['pref-keywords']);

if (Object.keys(filter).length > 0 && Object.keys(preferences).length > 0) {
this.error(
Expand Down Expand Up @@ -181,7 +187,3 @@ export default class JobsSearch extends BaseCommand {
}
}
}

function splitCsv(value: string): Array<string> {
return value.split(',').map((s) => s.trim());
}
Loading
Loading