├── .env.local.example
├── .eslintrc.cjs
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── dependabot.yml
├── pull_request_template.md
└── workflows
│ ├── publish.yaml
│ └── test.yaml
├── .gitignore
├── .ncurc.json
├── LICENSE
├── README.md
├── example
├── index.js
├── package.json
└── pnpm-lock.yaml
├── package.json
├── pnpm-lock.yaml
├── src
├── endpoints
│ ├── autocomplete
│ │ └── index.ts
│ ├── bulkCompanyEnrichment
│ │ └── index.ts
│ ├── bulkEnrichment
│ │ └── index.ts
│ ├── bulkRetrieve
│ │ └── index.ts
│ ├── cleaner
│ │ └── index.ts
│ ├── enrichment
│ │ └── index.ts
│ ├── enrichmentPreview
│ │ └── index.ts
│ ├── identify
│ │ └── index.ts
│ ├── index.ts
│ ├── ip
│ │ └── index.ts
│ ├── jobTitle
│ │ └── index.ts
│ ├── retrieve
│ │ └── index.ts
│ └── search
│ │ └── index.ts
├── errors.ts
├── index.ts
├── types
│ ├── api-types.ts
│ ├── autocomplete-types.ts
│ ├── bulk-retrieve-types.ts
│ ├── bulk-types.ts
│ ├── canonical-types.ts
│ ├── cleaner-types.ts
│ ├── common-types.ts
│ ├── enrichment-types.ts
│ ├── error-types.ts
│ ├── identify-types.ts
│ ├── ip-types.ts
│ ├── jobTitle-types.ts
│ ├── retrieve-types.ts
│ ├── search-types.ts
│ └── utility-types.ts
└── utils
│ └── api-utils.ts
├── tests
└── index.test.js
├── tsconfig.eslint.json
└── tsconfig.json
/.env.local.example:
--------------------------------------------------------------------------------
1 | PDL_API_KEY=...
2 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2021: true,
5 | },
6 | extends: [
7 | 'airbnb-base',
8 | 'airbnb-typescript/base',
9 | ],
10 | parser: '@typescript-eslint/parser',
11 | parserOptions: {
12 | ecmaVersion: 'latest',
13 | sourceType: 'module',
14 | project: './tsconfig.eslint.json',
15 | },
16 | plugins: [
17 | '@stylistic',
18 | '@typescript-eslint',
19 | 'simple-import-sort',
20 | 'sort-destructure-keys',
21 | 'typescript-sort-keys',
22 | 'import-newlines',
23 | ],
24 | rules: {
25 | 'max-len': 'off',
26 | 'simple-import-sort/imports': 'error',
27 | 'simple-import-sort/exports': 'error',
28 | 'object-curly-newline': 'off',
29 | 'typescript-sort-keys/interface': ['error', 'asc', {
30 | caseSensitive: false,
31 | natural: true,
32 | requiredFirst: false,
33 | }],
34 | 'typescript-sort-keys/string-enum': ['error', 'asc', {
35 | caseSensitive: false,
36 | natural: true,
37 | }],
38 | 'import-newlines/enforce': ['error', {
39 | items: 5000,
40 | multiline: false,
41 | }],
42 | '@stylistic/member-delimiter-style': ['error', {
43 | multiline: {
44 | delimiter: 'semi',
45 | requireLast: true,
46 | },
47 | singleline: {
48 | delimiter: 'comma',
49 | requireLast: false,
50 | },
51 | }],
52 | '@stylistic/type-annotation-spacing': 'error',
53 | '@stylistic/type-generic-spacing': ['error'],
54 | '@stylistic/type-named-tuple-spacing': ['error'],
55 | 'sort-destructure-keys/sort-destructure-keys': [2, {
56 | caseSensitive: false,
57 | }],
58 | },
59 | };
60 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 |
16 | **Expected behavior**
17 | A clear and concise description of what you expected to happen.
18 |
19 | **Screenshots**
20 | If applicable, add screenshots to help explain your problem.
21 | - peopledatalabs Library Version
22 | - Node Version
23 | - NPM Version
24 |
25 | **Additional context**
26 | Add any other context about the problem here.
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "npm"
4 | open-pull-requests-limit: 10
5 | directory: "/"
6 | schedule:
7 | interval: "weekly"
8 | day: "sunday"
9 | time: "09:00"
10 | timezone: "America/Los_Angeles"
11 | labels:
12 | - "dependencies"
13 | ignore:
14 | - dependency-name: "@stylistic/eslint-plugin"
15 | - dependency-name: "@typescript-eslint/eslint-plugin"
16 | - dependency-name: "@typescript-eslint/parser"
17 | - dependency-name: "copy-anything"
18 | - dependency-name: "eslint"
19 | - dependency-name: "eslint-plugin-unused-imports"
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Description of the change
2 |
3 | - Description here
4 |
5 | ## Type of change
6 |
7 | - [ ] Bug fix (non-breaking change that fixes an issue)
8 | - [ ] Chore (cleanup or minor QOL tweak that has little to no impact on functionality)
9 | - [ ] New feature (non-breaking change that adds functionality)
10 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
11 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yaml:
--------------------------------------------------------------------------------
1 | name: Publish Package to NPM and GitHub
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | test:
9 | runs-on: ubuntu-latest
10 | permissions:
11 | contents: read
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: actions/setup-node@v4
15 | with:
16 | node-version: 22
17 | - run: npm install -g pnpm
18 | - run: pnpm install --frozen-lockfile
19 | - run: pnpm test
20 | env:
21 | PDL_API_KEY: ${{secrets.PDL_API_KEY}}
22 |
23 | publish-npm:
24 | needs: test
25 | runs-on: ubuntu-latest
26 | permissions:
27 | contents: read
28 | packages: write
29 | id-token: write
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: actions/setup-node@v4
33 | with:
34 | node-version: 22
35 | registry-url: https://registry.npmjs.org/
36 | - run: npm install -g pnpm
37 | - run: pnpm install --frozen-lockfile
38 | - run: pnpm pub
39 | env:
40 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
--------------------------------------------------------------------------------
/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | name: Test Package
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | test:
11 | runs-on: ubuntu-latest
12 | permissions:
13 | contents: read
14 | steps:
15 | - uses: actions/checkout@v4
16 | - uses: actions/setup-node@v4
17 | with:
18 | node-version: 22
19 | - run: npm install -g pnpm
20 | - run: pnpm install --frozen-lockfile
21 | - run: pnpm test
22 | env:
23 | PDL_API_KEY: ${{secrets.PDL_API_KEY}}
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 | .pnpm-debug.log*
9 |
10 | # Diagnostic reports (https://nodejs.org/api/report.html)
11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12 |
13 | # Runtime data
14 | pids
15 | *.pid
16 | *.seed
17 | *.pid.lock
18 |
19 | # Directory for instrumented libs generated by jscoverage/JSCover
20 | lib-cov
21 |
22 | # Coverage directory used by tools like istanbul
23 | coverage
24 | *.lcov
25 |
26 | # nyc test coverage
27 | .nyc_output
28 |
29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30 | .grunt
31 |
32 | # Bower dependency directory (https://bower.io/)
33 | bower_components
34 |
35 | # node-waf configuration
36 | .lock-wscript
37 |
38 | # Compiled binary addons (https://nodejs.org/api/addons.html)
39 | build/Release
40 |
41 | # Dependency directories
42 | node_modules/
43 | jspm_packages/
44 |
45 | # Snowpack dependency directory (https://snowpack.dev/)
46 | web_modules/
47 |
48 | # TypeScript cache
49 | *.tsbuildinfo
50 |
51 | # Optional npm cache directory
52 | .npm
53 |
54 | # Optional eslint cache
55 | .eslintcache
56 |
57 | # Optional stylelint cache
58 | .stylelintcache
59 |
60 | # Microbundle cache
61 | .rpt2_cache/
62 | .rts2_cache_cjs/
63 | .rts2_cache_es/
64 | .rts2_cache_umd/
65 |
66 | # Optional REPL history
67 | .node_repl_history
68 |
69 | # Output of 'npm pack'
70 | *.tgz
71 |
72 | # Yarn Integrity file
73 | .yarn-integrity
74 |
75 | # dotenv environment variable files
76 | .env
77 | .env.development.local
78 | .env.test.local
79 | .env.production.local
80 | .env.local
81 |
82 | # parcel-bundler cache (https://parceljs.org/)
83 | .cache
84 | .parcel-cache
85 |
86 | # Next.js build output
87 | .next
88 | out
89 |
90 | # Nuxt.js build / generate output
91 | .nuxt
92 | dist
93 |
94 | # Gatsby files
95 | .cache/
96 | # Comment in the public line in if your project uses Gatsby and not Next.js
97 | # https://nextjs.org/blog/next-9-1#public-directory-support
98 | # public
99 |
100 | # vuepress build output
101 | .vuepress/dist
102 |
103 | # vuepress v2.x temp and cache directory
104 | .temp
105 | .cache
106 |
107 | # Docusaurus cache and generated files
108 | .docusaurus
109 |
110 | # Serverless directories
111 | .serverless/
112 |
113 | # FuseBox cache
114 | .fusebox/
115 |
116 | # DynamoDB Local files
117 | .dynamodb/
118 |
119 | # TernJS port file
120 | .tern-port
121 |
122 | # Stores VSCode versions used for testing VSCode extensions
123 | .vscode-test
124 |
125 | # yarn v2
126 | .yarn/cache
127 | .yarn/unplugged
128 | .yarn/build-state.yml
129 | .yarn/install-state.gz
130 | .pnp.*
131 |
132 | # Mac OS
133 | .DS_Store
134 |
135 | # Cache Files
136 | .rpt2_cache
137 | .rts2_cache_cjs
138 | .rts2_cache_es
139 | .rts2_cache_umd
140 |
141 | # VS Code
142 | .vscode
143 |
144 | # pnpm
145 | .pnpm/
146 | .pnp.cjs
147 | .pnp.loader.mjs
148 | .pnpm-store/
149 | pnpm-debug.log*
--------------------------------------------------------------------------------
/.ncurc.json:
--------------------------------------------------------------------------------
1 | {
2 | "interactive": true,
3 | "packageManager": "pnpm",
4 | "reject": [
5 | "@stylistic/eslint-plugin",
6 | "@typescript-eslint/eslint-plugin",
7 | "@typescript-eslint/parser",
8 | "copy-anything",
9 | "eslint",
10 | "eslint-plugin-unused-imports"
11 | ],
12 | "root": true
13 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 People Data Labs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | People Data Labs JavaScript Library
5 |
6 | JavaScript client with TypeScript support for the People Data Labs API.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | #
22 |
23 | This is a simple JavaScript client library to access the various API endpoints provided by [People Data Labs](https://www.peopledatalabs.com/).
24 |
25 | This library bundles up PDL API requests into simple function calls, making it easy to integrate into your projects. You can use the various [API endpoints](#endpoints) to access up-to-date, real-world data from our massive [Person](https://docs.peopledatalabs.com/docs/stats) and [Company](https://docs.peopledatalabs.com/docs/company-stats) Datasets.
26 |
27 | ## ✨ Features
28 |
29 | - Supports all People Data Labs API endpoints
30 | - Built-in Typescript support
31 |
32 | ## Table of Contents
33 |
34 | - [🔧 Installation](#installation)
35 | - [🚀 Usage](#usage)
36 | - [🌐 Endpoints](#endpoints)
37 | - [📘 Documentation](#documentation)
38 | - [Special Note about Search API Support](#special-note)
39 | - [Upgrading to v6.X.X](#upgrading-to-v6)
40 | - [Upgrading to v5.X.X](#upgrading-to-v5)
41 |
42 | ## 🔧 Installation
43 |
44 | 1. Pull the package from the npm repository:
45 |
46 | ```bash
47 | yarn add peopledatalabs
48 | ```
49 |
50 | or
51 |
52 | ```bash
53 | npm i peopledatalabs
54 | ```
55 |
56 | 2. If you get a error while running a typescript project, add `"esModuleInterop": true` to your tsconfig
57 |
58 | 3. Sign up for a [free PDL API key](https://www.peopledatalabs.com/signup)
59 |
60 | ## 🚀 Usage
61 |
62 | First, create the PDLJS client:
63 |
64 | ```js
65 | import PDLJS from 'peopledatalabs';
66 |
67 | const PDLJSClient = new PDLJS({ apiKey: 'YOUR API KEY' })
68 | ```
69 |
70 | Then, send requests to any PDL API Endpoint:
71 |
72 | **Using Person APIs**
73 |
74 | ```js
75 | // By Enrichment
76 | try {
77 | const response = await PDLJSClient.person.enrichment({ phone: '4155688415' });
78 |
79 | console.log(response);
80 | } catch (error) {
81 | console.log(error);
82 | }
83 |
84 | // By Preview Enrichment
85 | try {
86 | const response = await PDLJSClient.person.enrichmentPreview({ phone: '4155688415' });
87 |
88 | console.log(response);
89 | } catch (error) {
90 | console.log(error);
91 | }
92 |
93 | // By Bulk Enrichment
94 | const bulkEnrichmentRecords = {
95 | requests: [
96 | {
97 | params: {
98 | profile: ['linkedin.com/in/seanthorne'],
99 | },
100 | },
101 | {
102 | params: {
103 | profile: ['linkedin.com/in/randrewn'],
104 | },
105 | },
106 | ],
107 | };
108 |
109 | try {
110 | const response = await PDLJSClient.person.bulk.enrichment(bulkEnrichmentRecords);
111 |
112 | console.log(response.items);
113 | } catch (error) {
114 | console.log(error);
115 | }
116 |
117 | // By Search (SQL)
118 | const sqlQuery = "SELECT * FROM person WHERE location_country='mexico' AND job_title_role='health'AND phone_numbers IS NOT NULL;"
119 |
120 | try {
121 | const response = await PDLJSClient.person.search.sql({ searchQuery: sqlQuery, size: 10 });
122 |
123 | console.log(response.total);
124 | } catch (error) {
125 | console.log(error);
126 | }
127 |
128 | // By Search (Elasticsearch)
129 | const esQuery = {
130 | query: {
131 | bool: {
132 | must:[
133 | { term: { location_country: 'mexico' } },
134 | { term: { job_title_role: 'health' } },
135 | { exists: { field: 'phone_numbers' } }
136 | ]
137 | }
138 | }
139 | }
140 |
141 | try {
142 | const response = await PDLJSClient.person.search.elastic({ searchQuery: esQuery, size: 10 });
143 |
144 | console.log(response.total);
145 | } catch (error) {
146 | console.log(error);
147 | }
148 |
149 | // By Fuzzy Enrichment
150 | try {
151 | const response = await PDLJSClient.person.identify({ name: 'sean thorne' });
152 |
153 | console.log(response);
154 | } catch (error) {
155 | console.log(error);
156 | }
157 | ```
158 |
159 | **Using Company APIs**
160 |
161 | ```js
162 | // By Enrichment
163 | try {
164 | const response = await PDLJSClient.company.enrichment({ website: 'peopledatalabs.com' });
165 |
166 | console.log(response);
167 | } catch (error) {
168 | console.log(error);
169 | }
170 |
171 | // By Bulk Enrichment
172 | const bulkEnrichmentRecords = {
173 | requests: [
174 | {
175 | params: {
176 | profile: ['linkedin.com/in/peopledatalabs'],
177 | },
178 | },
179 | {
180 | params: {
181 | profile: ['linkedin.com/in/apple'],
182 | },
183 | },
184 | ],
185 | };
186 |
187 | try {
188 | const response = await PDLJSClient.company.bulk.enrichment(bulkEnrichmentRecords);
189 |
190 | console.log(response.items);
191 | } catch (error) {
192 | console.log(error);
193 | }
194 |
195 | // By Search (SQL)
196 | const sqlQuery = "SELECT * FROM company WHERE tags='big data' AND industry='financial services' AND location.country='united states';"
197 |
198 | try {
199 | const response = await PDLJSClient.company.search.sql({ searchQuery: sqlQuery, size: 10 });
200 |
201 | console.log(response.total);
202 | } catch (error) {
203 | console.log(error);
204 | }
205 |
206 | // By Search (Elasticsearch)
207 | const esQuery = {
208 | query: {
209 | bool: {
210 | must:[
211 | { term: { tags: 'big data' } },
212 | { term: { industry: 'financial services' } },
213 | { term: { location_country: 'united states' } }
214 | ]
215 | }
216 | }
217 | }
218 |
219 | try {
220 | const response = await PDLJSClient.company.search.elastic({ searchQuery: esQuery, size: 10 });
221 |
222 | console.log(response.total);
223 | } catch (error) {
224 | console.log(error);
225 | }
226 |
227 | ```
228 |
229 | **Using Autocomplete API**
230 |
231 | ```js
232 | // Get Autocomplete Suggestions
233 | try {
234 | const response = await PDLJSClient.autocomplete({ field: 'title', text: 'full', size: 10 });
235 |
236 | console.log(response);
237 | } catch (error) {
238 | console.log(error);
239 | }
240 | ```
241 |
242 | **Using Cleaner APIs**
243 |
244 | ```js
245 | // Clean Raw Company Strings
246 | try {
247 | const response = await PDLJSClient.company.cleaner({ name: 'peOple DaTa LabS' });
248 |
249 | console.log(response);
250 | } catch (error) {
251 | console.log(error);
252 | }
253 |
254 | // Clean Raw Location Strings
255 | try {
256 | const response = await PDLJSClient.location.cleaner({ location: '455 Market Street, San Francisco, California 94105, US' });
257 |
258 | console.log(response);
259 | } catch (error) {
260 | console.log(error);
261 | }
262 |
263 | // Clean Raw School Strings
264 | try {
265 | const response = await PDLJSClient.school.cleaner({ name: 'university of oregon' });
266 |
267 | console.log(response);
268 | } catch (error) {
269 | console.log(error);
270 | }
271 | ```
272 |
273 | **Using Job Title Enrichment API**
274 |
275 | ```js
276 | // Enrich a Job Title
277 | try {
278 | const response = await PDLJSClient.jobTitle({ jobTitle: 'software engineer' });
279 |
280 | console.log(response);
281 | } catch (error) {
282 | console.log(error);
283 | }
284 | ```
285 |
286 | **Using IP Enrichment API**
287 |
288 | ```js
289 | // Enrich an IP Address
290 | try {
291 | const response = await PDLJSClient.ip({ ip: '72.212.42.228' });
292 |
293 | console.log(response);
294 | } catch (error) {
295 | console.log(error);
296 | }
297 | ```
298 |
299 | **Using Sandbox APIs**
300 |
301 | ```js
302 | // By Person Enrichment
303 | try {
304 | const response = await PDLJSClient.person.enrichment({
305 | email: 'reneewillis74@aol.com',
306 | sandbox: true,
307 | });
308 |
309 | console.log(response);
310 | } catch (error) {
311 | console.log(error);
312 | }
313 |
314 | // By Person Search (SQL)
315 | try {
316 | const response = await PDLJSClient.person.search.sql({
317 | searchQuery: "SELECT * FROM person WHERE location_country='united states';",
318 | size: 10,
319 | sandbox: true,
320 | });
321 |
322 | console.log(response.total);
323 | } catch (error) {
324 | console.log(error);
325 | }
326 |
327 | // By Person Search (Elasticsearch)
328 | const esQuery = {
329 | query: {
330 | bool: {
331 | must:[
332 | { term: { location_country: 'united states' } }
333 | ]
334 | }
335 | }
336 | }
337 |
338 | try {
339 | const response = await PDLJSClient.person.search.elastic({ searchQuery: esQuery, size: 10, sandbox: true });
340 |
341 | console.log(response.total);
342 | } catch (error) {
343 | console.log(error);
344 | }
345 |
346 | // By Person Fuzzy Enrichment
347 | try {
348 | const response = PDLJSClient.person.identify({ email: 'reneewillis74@aol.com', sandbox: true });
349 |
350 | console.log(response);
351 | } catch (error) {
352 | console.log(error);
353 | }
354 |
355 | // By Company Enrichment
356 | try {
357 | const response = await PDLJSClient.company.enrichment({ website: 'kohlerinteriors.com', sandbox: true });
358 |
359 | console.log(response);
360 | } catch (error) {
361 | console.log(error);
362 | }
363 |
364 | // By Company Search (SQL)
365 | const sqlQuery = "SELECT * FROM company WHERE tags='hotel consultant' AND industry='hospitality';"
366 |
367 | try {
368 | const response = await PDLJSClient.company.search.sql({ searchQuery: sqlQuery, size: 10, sandbox: true });
369 |
370 | console.log(response.total);
371 | } catch (error) {
372 | console.log(error);
373 | }
374 |
375 | // By Company Search (Elasticsearch)
376 | const esQuery = {
377 | query: {
378 | bool: {
379 | must:[
380 | { term: { tags: 'hotel consultant' } },
381 | { term: { industry: 'hospitality' } }
382 | ]
383 | }
384 | }
385 | }
386 |
387 | try {
388 | const response = await PDLJSClient.company.search.elastic({ searchQuery: esQuery, size: 10, sandbox: true });
389 |
390 | console.log(response.total);
391 | } catch (error) {
392 | console.log(error);
393 | }
394 | ```
395 |
396 | ## 🌐 Endpoints
397 |
398 | **Person Endpoints**
399 | | API Endpoint | PDLJS Function |
400 | |-|-|
401 | | [Person Enrichment API](https://docs.peopledatalabs.com/docs/enrichment-api) | `PDLJS.person.enrichment({ ...params })` |
402 | | [Person Preview Enrichment API](https://docs.peopledatalabs.com/docs/preview-enrichment-api) | `PDLJS.person.enrichmentPreview({ ...params })` |
403 | | [Person Bulk Person Enrichment API](https://docs.peopledatalabs.com/docs/bulk-enrichment-api) | `PDLJS.person.bulk.enrichment({ ...records })` |
404 | | [Person Search API](https://docs.peopledatalabs.com/docs/search-api) | SQL: `PDLJS.person.search.sql({ ...params })`
Elasticsearch: `PDLJS.person.search.elastic({ ...params })`|
405 | | [Person Identify API](https://docs.peopledatalabs.com/docs/identify-api) | `PDLJS.person.identify({ ...params })` |
406 |
407 | **Company Endpoints**
408 | | API Endpoint | PDLJS Function |
409 | |-|-|
410 | | [Company Enrichment API](https://docs.peopledatalabs.com/docs/company-enrichment-api) | `PDLJS.company.enrichment({ ...params })` |
411 | | [Company Bulk Enrichment API](https://docs.peopledatalabs.com/docs/bulk-company-enrichment-api) | `PDLJS.company.bulk.enrichment({ ...records })` |
412 | | [Company Search API](https://docs.peopledatalabs.com/docs/company-search-api) | SQL: `PDLJS.company.search.sql({ ...params })`
Elasticsearch: `PDLJS.company.search.elastic({ ...params })`|
413 |
414 | **Supporting Endpoints**
415 | | API Endpoint | PDLJS Function |
416 | |-|-|
417 | | [Autocomplete API](https://docs.peopledatalabs.com/docs/autocomplete-api) | `PDLJS.autocomplete({ ...params })` |
418 | | [Company Cleaner API](https://docs.peopledatalabs.com/docs/cleaner-apis#companyclean) | `PDLJS.company.cleaner({ ...params })` |
419 | | [Location Cleaner API](https://docs.peopledatalabs.com/docs/cleaner-apis#locationclean) | `PDLJS.location.cleaner({ ...params })` |
420 | | [School Cleaner API](https://docs.peopledatalabs.com/docs/cleaner-apis#schoolclean) | `PDLJS.school.cleaner({ ...params })` |
421 | | [Job Title Enrichment API](https://docs.peopledatalabs.com/docs/job-title-enrichment-api) | `PDLJS.jobTitle({ ...params })` |
422 | | [IP Enrichment API](https://docs.peopledatalabs.com/docs/ip-enrichment-api) | `PDLJS.ip({ ...params })` |
423 |
424 | **Sandbox Endpoints**
425 | | API Endpoint | PDLJS Function |
426 | |-|-|
427 | | [Person Enrichment Sandbox API](https://docs.peopledatalabs.com/docs/sandbox-apis) | `PDLJS.person.enrichment({ ...params, sandbox: true })` |
428 | | [Person Search Sandbox API](https://docs.peopledatalabs.com/docs/sandbox-apis) | SQL: `PDLJS.person.search.sql({ ...params, sandbox: true })`
Elasticsearch: `PDLJS.person.search.elastic({ ...params, sandbox: true })`|
429 | | [Person Identify Sandbox API](https://docs.peopledatalabs.com/docs/sandbox-apis) | `PDLJS.person.identify({ ...params, sandbox: true })` |
430 | | [Company Enrichment Sandbox API](https://docs.peopledatalabs.com/docs/sandbox-apis) | `PDLJS.company.enrichment({ ...params, sandbox: true })` |
431 | | [Company Search Sandbox API](https://docs.peopledatalabs.com/docs/sandbox-apis) | SQL: `PDLJS.company.search.sql({ ...params, sandbox: true })`
Elasticsearch: `PDLJS.company.search.elastic({ ...params, sandbox: true })`|
432 |
433 | ## 📘 Documentation
434 |
435 | All of our API endpoints are documented at:
436 |
437 | These docs describe the supported input parameters, output responses and also provide additional technical context.
438 |
439 | As illustrated in the [Endpoints](#endpoints) section above, each of our API endpoints is mapped to a specific method in the PDLJS class. For each of these class methods, **all function inputs are mapped as input parameters to the respective API endpoint**, meaning that you can use the API documentation linked above to determine the input parameters for each endpoint.
440 |
441 | As an example:
442 |
443 | The following is **valid** because `name` is a [supported input parameter to the Person Identify API](https://docs.peopledatalabs.com/docs/identify-api-reference#input-parameters):
444 |
445 | ```js
446 | PDLJS.person.identify({ name: 'sean thorne' })
447 | ```
448 |
449 | Conversely, this would be **invalid** because `fake_parameter` is not an input parameter to the Person Identify API:
450 |
451 | ```js
452 | PDLJS.person.identify({ fake_parameter: 'anything' })
453 | ```
454 |
455 | #### Special Note about Search API Support
456 |
457 | Our Person Search API and Company Search API endpoints both support two types of query syntax: you can construct search queries using either `SQL` or `Elasticsearch` syntax.
458 |
459 | In the PDLJS class, the person and company search functions are broken out into two syntax-specific methods as follows:
460 | | Data Type | Search Query Syntax | Function |
461 | | -- | -- | -- |
462 | | Person | SQL | `PDLJS.person.search.sql({ ...params })` |
463 | | Person | Elasticsearch | `PDLJS.person.search.elastic({ ...params })` |
464 | | Company | SQL | `PDLJS.company.search.sql({ ...params })` |
465 | | Company | Elasticsearch | `PDLJS.company.search.elastic({ ...params })` |
466 |
467 | You can pass your query to these methods using the special `searchQuery` function argument, as shown in the following example:
468 |
469 | ```js
470 | const sqlQuery = "SELECT * FROM company WHERE website='peopledatalabs.com';"
471 |
472 | try {
473 | const response = await PDLJS.company.search.sql({ searchQuery: sqlQuery, size: 10 });
474 |
475 | console.log(response.total)
476 | } catch (error) {
477 | console.log(error)
478 | }
479 | ```
480 |
481 | #### Upgrading to v6.X.X
482 |
483 | NOTE: When upgrading to v6.X.X from vX.X.X and below, Retrieve and Bulk Retrieve were both changed to make the `pretty`, `titlecase` and `filter_updated` to be siblings of the `requests` parameter.
484 |
485 | #### Upgrading to v5.X.X
486 |
487 | NOTE: When upgrading to v5.X.X from v4.X.X and below, Bulk Enrichment was moved from `PDLJS.person.bulk({ ...records })` to `PDLJS.person.bulk.enrichment({ ...records })`
488 |
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: "off" */
2 |
3 | import dotenv from 'dotenv';
4 | import PDLJS from 'peopledatalabs';
5 |
6 | dotenv.config({ path: '../.env.local' });
7 |
8 | const PDLJSClient = new PDLJS({ apiKey: process.env.PDL_API_KEY });
9 |
10 | // Person APIs
11 |
12 | PDLJSClient.person.enrichment({ phone: '4155688415' }).then((data) => {
13 | console.log('Person Enrichment API');
14 | console.log(data);
15 | }).catch((error) => {
16 | console.log('Person Enrichment API');
17 | console.log(error);
18 | });
19 |
20 | PDLJSClient.person.enrichmentPreview({ phone: '4155688415' }).then((data) => {
21 | console.log('Person Preview Enrichment API');
22 | console.log(data);
23 | }).catch((error) => {
24 | console.log('Person Preview Enrichment API');
25 | console.log(error);
26 | });
27 |
28 | PDLJSClient.person.identify({ phone: '4155688415' }).then((data) => {
29 | console.log('Person Identify API');
30 | console.log(data);
31 | }).catch((error) => {
32 | console.log('Person Identify API');
33 | console.log(error);
34 | });
35 |
36 | const bulkEnrichmentRecords = {
37 | requests: [
38 | { params: { profile: ['linkedin.com/in/seanthorne'] } },
39 | { params: { profile: ['linkedin.com/in/randrewn'] } },
40 | ],
41 | };
42 |
43 | PDLJSClient.person.bulk.enrichment(bulkEnrichmentRecords).then((data) => {
44 | console.log('Person Bulk Enrichment API');
45 | console.log(data);
46 | }).catch((error) => {
47 | console.log('Person Bulk Enrichment API');
48 | console.log(error);
49 | });
50 |
51 | PDLJSClient.person.search.sql({
52 | searchQuery: "SELECT * FROM person WHERE location_country='mexico' AND job_title_role='health'AND phone_numbers IS NOT NULL;",
53 | size: 10,
54 | }).then((data) => {
55 | console.log('Person Search API - SQL');
56 | console.log(data);
57 | }).catch((error) => {
58 | console.log('Person Search API - SQL');
59 | console.log(error);
60 | });
61 |
62 | PDLJSClient.person.search.elastic({
63 | searchQuery: {
64 | query: {
65 | bool: {
66 | must: [{ term: { job_company_website: 'peopledatalabs.com' } }],
67 | },
68 | },
69 | },
70 | size: 10,
71 | }).then((data) => {
72 | console.log('Person Search API - Elastic');
73 | console.log(data);
74 | }).catch((error) => {
75 | console.log('Person Search API - Elastic');
76 | console.log(error);
77 | });
78 |
79 | // Company APIs
80 |
81 | PDLJSClient.company.enrichment({ website: 'peopledatalabs.com' }).then((data) => {
82 | console.log('Company Enrichment API');
83 | console.log(data);
84 | }).catch((error) => {
85 | console.log('Company Enrichment API');
86 | console.log(error);
87 | });
88 |
89 | const bulkCompanyEnrichmentRecords = {
90 | requests: [
91 | { params: { profile: ['linkedin.com/company/peopledatalabs'] } },
92 | { params: { profile: ['linkedin.com/company/apple'] } },
93 | ],
94 | };
95 |
96 | PDLJSClient.company.bulk.enrichment(bulkCompanyEnrichmentRecords).then((data) => {
97 | console.log('Company Bulk Enrichment API');
98 | console.log(data);
99 | }).catch((error) => {
100 | console.log('Company Bulk Enrichment API');
101 | console.log(error);
102 | });
103 |
104 | PDLJSClient.company.search.sql({
105 | searchQuery: "SELECT * FROM company WHERE website = 'peopledatalabs.com';",
106 | size: 10,
107 | }).then((data) => {
108 | console.log('Company Search API - SQL');
109 | console.log(data);
110 | }).catch((error) => {
111 | console.log('Company Search API - SQL');
112 | console.log(error);
113 | });
114 |
115 | PDLJSClient.company.search.elastic({
116 | searchQuery: {
117 | query: {
118 | bool: {
119 | must: [{ term: { website: 'peopledatalabs.com' } }],
120 | },
121 | },
122 | },
123 | size: 10,
124 | }).then((data) => {
125 | console.log('Company Search API - Elastic');
126 | console.log(data);
127 | }).catch((error) => {
128 | console.log('Company Search API - Elastic');
129 | console.log(error);
130 | });
131 |
132 | // IP APIs
133 |
134 | PDLJSClient.ip({ ip: '72.212.42.228' }).then((data) => {
135 | console.log('IP Enrichment API');
136 | console.log(data);
137 | }).catch((error) => {
138 | console.log('IP Enrichment API');
139 | console.log(error);
140 | });
141 |
142 | // Supporting APIs
143 |
144 | PDLJSClient.autocomplete({
145 | field: 'skill',
146 | text: 'c++',
147 | size: 10,
148 | }).then((data) => {
149 | console.log('Autocomplete API');
150 | console.log(data);
151 | }).catch((error) => {
152 | console.log('Autocomplete API');
153 | console.log(error);
154 | });
155 |
156 | PDLJSClient.company.cleaner({ name: 'peopledatalabs' }).then((data) => {
157 | console.log('Company Cleaner API');
158 | console.log(data);
159 | }).catch((error) => {
160 | console.log('Company Cleaner API');
161 | console.log(error);
162 | });
163 |
164 | PDLJSClient.location.cleaner({ location: '455 Market Street, San Francisco, California 94105, US' }).then((data) => {
165 | console.log('Location Cleaner API');
166 | console.log(data);
167 | }).catch((error) => {
168 | console.log('Location Cleaner API');
169 | console.log(error);
170 | });
171 |
172 | PDLJSClient.school.cleaner({ name: 'university of oregon' }).then((data) => {
173 | console.log('School Cleaner API');
174 | console.log(data);
175 | }).catch((error) => {
176 | console.log('School Cleaner API');
177 | console.log(error);
178 | });
179 |
180 | PDLJSClient.jobTitle({ jobTitle: 'software engineer' }).then((data) => {
181 | console.log('Job Title API');
182 | console.log(data);
183 | }).catch((error) => {
184 | console.log('Job Title API');
185 | console.log(error);
186 | });
187 |
188 | // Sandbox APIs
189 |
190 | PDLJSClient.person.enrichment({ email: 'chad_taylor@carroll-inc.com', sandbox: true }).then((data) => {
191 | console.log('Person Enrichment Sandbox API');
192 | console.log(data);
193 | }).catch((error) => {
194 | console.log('Person Enrichment Sandbox API');
195 | console.log(error);
196 | });
197 |
198 | PDLJSClient.person.search.sql({
199 | searchQuery: "SELECT * FROM person WHERE location_country='united states';",
200 | size: 10,
201 | sandbox: true,
202 | }).then((data) => {
203 | console.log('Person Search Sandbox API - SQL');
204 | console.log(data.rateLimit);
205 | }).catch((error) => {
206 | console.log('Person Search Sandbox API - SQL');
207 | console.log(error);
208 | });
209 |
210 | PDLJSClient.person.identify({ company: 'carroll inc', sandbox: true }).then((data) => {
211 | console.log('Person Identify Sandbox API');
212 | console.log(data);
213 | }).catch((error) => {
214 | console.log('Person Identify Sandbox API');
215 | console.log(error);
216 | });
217 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "peopledatalabs-example",
3 | "version": "1.0.0",
4 | "description": "Example project with People Data Labs API library",
5 | "packageManager": "pnpm@10.9.0",
6 | "main": "index.js",
7 | "type": "module",
8 | "scripts": {
9 | "start": "node index.js",
10 | "clean": "rm -rf node_modules && rm -rf pnpm-lock.yaml",
11 | "check-packages": "pnpm dlx npm-check-updates"
12 | },
13 | "author": "People Data Labs",
14 | "license": "MIT",
15 | "dependencies": {
16 | "dotenv": "^16.5.0",
17 | "peopledatalabs": "*"
18 | }
19 | }
--------------------------------------------------------------------------------
/example/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | dotenv:
12 | specifier: ^16.5.0
13 | version: 16.5.0
14 | peopledatalabs:
15 | specifier: '*'
16 | version: 10.0.1
17 |
18 | packages:
19 |
20 | asynckit@0.4.0:
21 | resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
22 |
23 | axios@1.8.3:
24 | resolution: {integrity: sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==}
25 |
26 | call-bind-apply-helpers@1.0.2:
27 | resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
28 | engines: {node: '>= 0.4'}
29 |
30 | combined-stream@1.0.8:
31 | resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
32 | engines: {node: '>= 0.8'}
33 |
34 | copy-anything@3.0.5:
35 | resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
36 | engines: {node: '>=12.13'}
37 |
38 | delayed-stream@1.0.0:
39 | resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
40 | engines: {node: '>=0.4.0'}
41 |
42 | dotenv@16.5.0:
43 | resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==}
44 | engines: {node: '>=12'}
45 |
46 | dunder-proto@1.0.1:
47 | resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
48 | engines: {node: '>= 0.4'}
49 |
50 | es-define-property@1.0.1:
51 | resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
52 | engines: {node: '>= 0.4'}
53 |
54 | es-errors@1.3.0:
55 | resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
56 | engines: {node: '>= 0.4'}
57 |
58 | es-object-atoms@1.1.1:
59 | resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
60 | engines: {node: '>= 0.4'}
61 |
62 | es-set-tostringtag@2.1.0:
63 | resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
64 | engines: {node: '>= 0.4'}
65 |
66 | follow-redirects@1.15.9:
67 | resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
68 | engines: {node: '>=4.0'}
69 | peerDependencies:
70 | debug: '*'
71 | peerDependenciesMeta:
72 | debug:
73 | optional: true
74 |
75 | form-data@4.0.2:
76 | resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==}
77 | engines: {node: '>= 6'}
78 |
79 | function-bind@1.1.2:
80 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
81 |
82 | get-intrinsic@1.3.0:
83 | resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
84 | engines: {node: '>= 0.4'}
85 |
86 | get-proto@1.0.1:
87 | resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
88 | engines: {node: '>= 0.4'}
89 |
90 | gopd@1.2.0:
91 | resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
92 | engines: {node: '>= 0.4'}
93 |
94 | has-symbols@1.1.0:
95 | resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
96 | engines: {node: '>= 0.4'}
97 |
98 | has-tostringtag@1.0.2:
99 | resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
100 | engines: {node: '>= 0.4'}
101 |
102 | hasown@2.0.2:
103 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
104 | engines: {node: '>= 0.4'}
105 |
106 | is-what@4.1.16:
107 | resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
108 | engines: {node: '>=12.13'}
109 |
110 | math-intrinsics@1.1.0:
111 | resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
112 | engines: {node: '>= 0.4'}
113 |
114 | mime-db@1.52.0:
115 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
116 | engines: {node: '>= 0.6'}
117 |
118 | mime-types@2.1.35:
119 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
120 | engines: {node: '>= 0.6'}
121 |
122 | peopledatalabs@10.0.1:
123 | resolution: {integrity: sha512-r/fBFLABLE+hJS+6dSvBFiaD4RQao1rdjzDjdwzRBAdJkQJ5Rd5YLsylp6kpVosPdRkqCj4nW/OIA6ufUEgZAQ==}
124 |
125 | proxy-from-env@1.1.0:
126 | resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
127 |
128 | snapshots:
129 |
130 | asynckit@0.4.0: {}
131 |
132 | axios@1.8.3:
133 | dependencies:
134 | follow-redirects: 1.15.9
135 | form-data: 4.0.2
136 | proxy-from-env: 1.1.0
137 | transitivePeerDependencies:
138 | - debug
139 |
140 | call-bind-apply-helpers@1.0.2:
141 | dependencies:
142 | es-errors: 1.3.0
143 | function-bind: 1.1.2
144 |
145 | combined-stream@1.0.8:
146 | dependencies:
147 | delayed-stream: 1.0.0
148 |
149 | copy-anything@3.0.5:
150 | dependencies:
151 | is-what: 4.1.16
152 |
153 | delayed-stream@1.0.0: {}
154 |
155 | dotenv@16.5.0: {}
156 |
157 | dunder-proto@1.0.1:
158 | dependencies:
159 | call-bind-apply-helpers: 1.0.2
160 | es-errors: 1.3.0
161 | gopd: 1.2.0
162 |
163 | es-define-property@1.0.1: {}
164 |
165 | es-errors@1.3.0: {}
166 |
167 | es-object-atoms@1.1.1:
168 | dependencies:
169 | es-errors: 1.3.0
170 |
171 | es-set-tostringtag@2.1.0:
172 | dependencies:
173 | es-errors: 1.3.0
174 | get-intrinsic: 1.3.0
175 | has-tostringtag: 1.0.2
176 | hasown: 2.0.2
177 |
178 | follow-redirects@1.15.9: {}
179 |
180 | form-data@4.0.2:
181 | dependencies:
182 | asynckit: 0.4.0
183 | combined-stream: 1.0.8
184 | es-set-tostringtag: 2.1.0
185 | mime-types: 2.1.35
186 |
187 | function-bind@1.1.2: {}
188 |
189 | get-intrinsic@1.3.0:
190 | dependencies:
191 | call-bind-apply-helpers: 1.0.2
192 | es-define-property: 1.0.1
193 | es-errors: 1.3.0
194 | es-object-atoms: 1.1.1
195 | function-bind: 1.1.2
196 | get-proto: 1.0.1
197 | gopd: 1.2.0
198 | has-symbols: 1.1.0
199 | hasown: 2.0.2
200 | math-intrinsics: 1.1.0
201 |
202 | get-proto@1.0.1:
203 | dependencies:
204 | dunder-proto: 1.0.1
205 | es-object-atoms: 1.1.1
206 |
207 | gopd@1.2.0: {}
208 |
209 | has-symbols@1.1.0: {}
210 |
211 | has-tostringtag@1.0.2:
212 | dependencies:
213 | has-symbols: 1.1.0
214 |
215 | hasown@2.0.2:
216 | dependencies:
217 | function-bind: 1.1.2
218 |
219 | is-what@4.1.16: {}
220 |
221 | math-intrinsics@1.1.0: {}
222 |
223 | mime-db@1.52.0: {}
224 |
225 | mime-types@2.1.35:
226 | dependencies:
227 | mime-db: 1.52.0
228 |
229 | peopledatalabs@10.0.1:
230 | dependencies:
231 | axios: 1.8.3
232 | copy-anything: 3.0.5
233 | transitivePeerDependencies:
234 | - debug
235 |
236 | proxy-from-env@1.1.0: {}
237 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "peopledatalabs",
3 | "version": "12.1.0",
4 | "description": "JavaScript client with TypeScript support for the People Data Labs API",
5 | "packageManager": "pnpm@10.11.0",
6 | "type": "module",
7 | "main": "dist/index.cjs",
8 | "module": "dist/index.m.js",
9 | "umd:main": "dist/index.umd.js",
10 | "types": "dist/index.d.ts",
11 | "source": "src/index.ts",
12 | "files": [
13 | "dist/**"
14 | ],
15 | "scripts": {
16 | "build": "rm -rf dist && microbundle",
17 | "dev": "microbundle watch -p 6008",
18 | "test": "pnpm run build && pnpm run mocha",
19 | "mocha": "mocha --recursive 'tests/**/*.js' --timeout 5000",
20 | "pub": "pnpm run build && pnpm publish --no-git-checks --provenance --access public",
21 | "lint": "eslint ./src --fix",
22 | "clean": "rm -rf node_modules && rm -rf pnpm-lock.yaml",
23 | "check-packages": "pnpm dlx npm-check-updates"
24 | },
25 | "repository": {
26 | "type": "git",
27 | "url": "git+https://github.com/peopledatalabs/peopledatalabs-js.git"
28 | },
29 | "keywords": [
30 | "peopledatalabs",
31 | "People Data Labs",
32 | "data enrichment",
33 | "person enrichment",
34 | "person search",
35 | "company enrichment",
36 | "company search",
37 | "javascript",
38 | "api",
39 | "client",
40 | "sdk"
41 | ],
42 | "author": "People Data Labs",
43 | "license": "MIT",
44 | "bugs": {
45 | "url": "https://github.com/peopledatalabs/peopledatalabs-js/issues"
46 | },
47 | "homepage": "https://docs.peopledatalabs.com/docs/javascript-sdk",
48 | "devDependencies": {
49 | "@stylistic/eslint-plugin": "^3.1.0",
50 | "@typescript-eslint/eslint-plugin": "7.18.0",
51 | "@typescript-eslint/parser": "7.18.0",
52 | "chai": "^5.2.0",
53 | "dotenv": "^16.5.0",
54 | "eslint": "^8.57.1",
55 | "eslint-config-airbnb": "^19.0.4",
56 | "eslint-config-airbnb-base": "^15.0.0",
57 | "eslint-config-airbnb-typescript": "^18.0.0",
58 | "eslint-plugin-import": "^2.31.0",
59 | "eslint-plugin-import-newlines": "^1.4.0",
60 | "eslint-plugin-jsx-a11y": "^6.10.2",
61 | "eslint-plugin-react": "^7.37.5",
62 | "eslint-plugin-react-hooks": "^5.2.0",
63 | "eslint-plugin-simple-import-sort": "^12.1.1",
64 | "eslint-plugin-sort-destructure-keys": "^2.0.0",
65 | "eslint-plugin-sort-keys-fix": "^1.1.2",
66 | "eslint-plugin-typescript-sort-keys": "^3.3.0",
67 | "eslint-plugin-unused-imports": "^3.2.0",
68 | "esm": "^3.2.25",
69 | "microbundle": "^0.15.1",
70 | "mocha": "^11.5.0",
71 | "typescript": "^5.8.3"
72 | },
73 | "dependencies": {
74 | "axios": "^1.9.0",
75 | "copy-anything": "3.0.5"
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/endpoints/autocomplete/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import type { AutoCompleteParams, AutoCompleteResponse } from '../../types/autocomplete-types.js';
5 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
6 |
7 | export default (
8 | basePath: string,
9 | apiKey: string,
10 | params: AutoCompleteParams,
11 | ) => new Promise((resolve, reject) => {
12 | check(params, basePath, apiKey, null, 'autocomplete').then(() => {
13 | const { field, pretty, size, text, titlecase } = params;
14 |
15 | const autocompleteParams = {
16 | field,
17 | text: text || '',
18 | size: size || 10,
19 | pretty: pretty || false,
20 | titlecase: titlecase || false,
21 | };
22 |
23 | const headers = {
24 | 'Accept-Encoding': 'gzip',
25 | 'User-Agent': 'PDL-JS-SDK',
26 | };
27 |
28 | axios.get(`${basePath}/autocomplete`, {
29 | params: {
30 | api_key: apiKey,
31 | ...autocompleteParams,
32 | },
33 | headers,
34 | }).then((response) => {
35 | if (response?.data?.status === 200) {
36 | resolve(parseRateLimitingResponse(response));
37 | }
38 | }).catch((error) => {
39 | reject(errorHandler(error));
40 | });
41 | }).catch((error) => {
42 | reject(error);
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/src/endpoints/bulkCompanyEnrichment/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import { BulkCompanyEnrichmentParams, BulkCompanyEnrichmentResponse } from '../../types/bulk-types.js';
5 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
6 |
7 | export default (basePath: string, apiKey: string, records: BulkCompanyEnrichmentParams) => {
8 | const headers = {
9 | 'Content-Type': 'application/json',
10 | 'Accept-Encoding': 'gzip',
11 | 'X-Api-Key': apiKey,
12 | 'User-Agent': 'PDL-JS-SDK',
13 | };
14 |
15 | return new Promise((resolve, reject) => {
16 | check(records, basePath, apiKey, 'Records', 'bulk').then(() => {
17 | axios.post(`${basePath}/company/enrich/bulk`, records, {
18 | headers,
19 | }).then((response) => {
20 | resolve(parseRateLimitingResponse(response));
21 | }).catch((error) => {
22 | reject(errorHandler(error));
23 | });
24 | }).catch((error) => {
25 | reject(error);
26 | });
27 | });
28 | };
29 |
--------------------------------------------------------------------------------
/src/endpoints/bulkEnrichment/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import { BulkPersonEnrichmentParams, BulkPersonEnrichmentResponse } from '../../types/bulk-types.js';
5 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
6 |
7 | export default (basePath: string, apiKey: string, records: BulkPersonEnrichmentParams) => {
8 | const headers = {
9 | 'Content-Type': 'application/json',
10 | 'Accept-Encoding': 'gzip',
11 | 'X-Api-Key': apiKey,
12 | 'User-Agent': 'PDL-JS-SDK',
13 | };
14 |
15 | return new Promise((resolve, reject) => {
16 | check(records, basePath, apiKey, 'Records', 'bulk').then(() => {
17 | axios.post(`${basePath}/person/bulk`, records, {
18 | headers,
19 | }).then((response) => {
20 | resolve(parseRateLimitingResponse(response));
21 | }).catch((error) => {
22 | reject(errorHandler(error));
23 | });
24 | }).catch((error) => {
25 | reject(error);
26 | });
27 | });
28 | };
29 |
--------------------------------------------------------------------------------
/src/endpoints/bulkRetrieve/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import { ApiBulkPersonRetrieveParams, BulkPersonRetrieveParams, BulkPersonRetrieveResponse } from '../../types/bulk-retrieve-types.js';
5 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
6 |
7 | const transformBulkRetrieveParams = (params: BulkPersonRetrieveParams): ApiBulkPersonRetrieveParams => {
8 | const filter = params.filter_updated;
9 | if (filter == null) {
10 | return {
11 | ...params,
12 | filter_updated: undefined,
13 | };
14 | }
15 | const filtersArray = Array.isArray(filter) ? filter : [filter];
16 | const filterUpdated = filtersArray.join(',');
17 | return {
18 | ...params,
19 | filter_updated: filterUpdated,
20 | };
21 | };
22 |
23 | export default (basePath: string, apiKey: string, records: BulkPersonRetrieveParams) => {
24 | const headers = {
25 | 'Content-Type': 'application/json',
26 | 'Accept-Encoding': 'gzip',
27 | 'X-Api-Key': apiKey,
28 | 'User-Agent': 'PDL-JS-SDK',
29 | };
30 |
31 | return new Promise((resolve, reject) => {
32 | check(records, basePath, apiKey, 'Records', 'bulk').then(() => {
33 | const apiParams = transformBulkRetrieveParams(records);
34 | axios.post(`${basePath}/person/retrieve/bulk`, apiParams, {
35 | headers,
36 | }).then((response) => {
37 | resolve(parseRateLimitingResponse(response));
38 | }).catch((error) => {
39 | reject(errorHandler(error));
40 | });
41 | }).catch((error) => {
42 | reject(error);
43 | });
44 | });
45 | };
46 |
--------------------------------------------------------------------------------
/src/endpoints/cleaner/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import { BaseResponse } from '../../types/api-types.js';
5 | import { CleanerType } from '../../types/cleaner-types.js';
6 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
7 |
8 | export default (
9 | basePath: string,
10 | apiKey: string,
11 | params: T,
12 | type: CleanerType,
13 | ) => new Promise((resolve, reject) => {
14 | check(params, basePath, apiKey, null, 'cleaner').then(() => {
15 | const headers = {
16 | 'Accept-Encoding': 'gzip',
17 | 'User-Agent': 'PDL-JS-SDK',
18 | };
19 |
20 | axios.get(`${basePath}/${type}/clean`, {
21 | params: {
22 | api_key: apiKey,
23 | ...params,
24 | },
25 | headers,
26 | }).then((response) => {
27 | if (response?.data?.status === 200) {
28 | resolve(parseRateLimitingResponse(response));
29 | }
30 | }).catch((error) => {
31 | reject(errorHandler(error));
32 | });
33 | }).catch((error) => {
34 | reject(error);
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/src/endpoints/enrichment/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import { copy } from 'copy-anything';
3 |
4 | import { check, errorHandler } from '../../errors.js';
5 | import { CompanyEnrichmentParams, CompanyEnrichmentResponse, EnrichmentType, PersonEnrichmentParams, PersonEnrichmentResponse } from '../../types/enrichment-types.js';
6 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
7 |
8 | export default (
9 | basePath: string,
10 | sandboxBasePath: string,
11 | apiKey: string,
12 | params: T,
13 | type: EnrichmentType,
14 | ) => new Promise((resolve, reject) => {
15 | check(params, basePath, apiKey, null, 'enrichment').then(() => {
16 | const headers = {
17 | 'Accept-Encoding': 'gzip',
18 | 'User-Agent': 'PDL-JS-SDK',
19 | };
20 |
21 | const url = params.sandbox && type === 'person' ? `${sandboxBasePath}/${type}/enrich` : `${basePath}/${type}/enrich`;
22 |
23 | const newParams = copy(params);
24 | const p = new URLSearchParams();
25 | delete newParams.sandbox;
26 |
27 | Object.entries(newParams).forEach(([key, value]: [string, any]) => {
28 | if (key === 'profile') {
29 | if (Array.isArray(value)) {
30 | p.append(key, JSON.stringify(value));
31 | } else if (value) {
32 | p.append(key, value);
33 | }
34 | } else if (typeof value === 'object') {
35 | if (Array.isArray(value)) {
36 | value.forEach((member) => {
37 | if (member) {
38 | p.append(key, (member));
39 | }
40 | });
41 | } else if (value) {
42 | p.append(key, JSON.stringify(value));
43 | }
44 | } else if (value) {
45 | p.append(key, (value));
46 | }
47 | });
48 |
49 | p.append('api_key', apiKey);
50 |
51 | axios.get(url, {
52 | params: p,
53 | headers,
54 | }).then((response) => {
55 | if (response?.data?.status === 200) {
56 | resolve(parseRateLimitingResponse(response));
57 | }
58 | }).catch((error) => {
59 | reject(errorHandler(error));
60 | });
61 | }).catch((error) => {
62 | reject(error);
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/src/endpoints/enrichmentPreview/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import { copy } from 'copy-anything';
3 |
4 | import { check, errorHandler } from '../../errors.js';
5 | import { PersonEnrichmentPreviewParams, PersonEnrichmentPreviewResponse } from '../../types/enrichment-types.js';
6 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
7 |
8 | export default (
9 | basePath: string,
10 | sandboxBasePath: string,
11 | apiKey: string,
12 | params: PersonEnrichmentPreviewParams,
13 | ) => new Promise((resolve, reject) => {
14 | check(params, basePath, apiKey, null, 'enrichment').then(() => {
15 | const headers = {
16 | 'Accept-Encoding': 'gzip',
17 | 'User-Agent': 'PDL-JS-SDK',
18 | };
19 |
20 | const url = params.sandbox ? `${sandboxBasePath}/person/enrich/preview` : `${basePath}/person/enrich/preview`;
21 |
22 | const newParams = copy(params);
23 | const p = new URLSearchParams();
24 | delete newParams.sandbox;
25 |
26 | Object.entries(newParams).forEach(([key, value]: [string, any]) => {
27 | if (key === 'profile') {
28 | if (Array.isArray(value)) {
29 | p.append(key, JSON.stringify(value));
30 | } else if (value) {
31 | p.append(key, value);
32 | }
33 | } else if (typeof value === 'object') {
34 | if (Array.isArray(value)) {
35 | value.forEach((member) => {
36 | if (member) {
37 | p.append(key, (member));
38 | }
39 | });
40 | } else if (value) {
41 | p.append(key, JSON.stringify(value));
42 | }
43 | } else if (value) {
44 | p.append(key, (value));
45 | }
46 | });
47 |
48 | p.append('api_key', apiKey);
49 |
50 | axios.get(url, {
51 | params: p,
52 | headers,
53 | }).then((response) => {
54 | if (response?.data?.status === 200) {
55 | resolve(parseRateLimitingResponse(response));
56 | }
57 | }).catch((error) => {
58 | reject(errorHandler(error));
59 | });
60 | }).catch((error) => {
61 | reject(error);
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/src/endpoints/identify/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import { copy } from 'copy-anything';
3 |
4 | import { check, errorHandler } from '../../errors.js';
5 | import { IdentifyParams, IdentifyResponse } from '../../types/identify-types.js';
6 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
7 |
8 | export default (
9 | basePath: string,
10 | sandboxBasePath: string,
11 | apiKey: string,
12 | params: IdentifyParams,
13 | ) => new Promise((resolve, reject) => {
14 | check(params, basePath, apiKey, null, 'identify').then(() => {
15 | const headers = {
16 | 'Accept-Encoding': 'gzip',
17 | 'User-Agent': 'PDL-JS-SDK',
18 | };
19 |
20 | const url = params.sandbox ? `${sandboxBasePath}/person/identify` : `${basePath}/person/identify`;
21 |
22 | const newParams = copy(params);
23 | const p = new URLSearchParams();
24 | delete newParams.sandbox;
25 |
26 | Object.entries(newParams).forEach(([key, value]: [string, any]) => {
27 | if (key === 'profile') {
28 | if (Array.isArray(value)) {
29 | p.append(key, JSON.stringify(value));
30 | } else if (value) {
31 | p.append(key, value);
32 | }
33 | } else if (typeof value === 'object') {
34 | if (Array.isArray(value)) {
35 | value.forEach((member) => {
36 | if (member) {
37 | p.append(key, (member));
38 | }
39 | });
40 | } else if (value) {
41 | p.append(key, JSON.stringify(value));
42 | }
43 | } else if (value) {
44 | p.append(key, (value));
45 | }
46 | });
47 |
48 | p.append('api_key', apiKey);
49 |
50 | axios.get(url, {
51 | params: p,
52 | headers,
53 | }).then((response) => {
54 | if (response?.data?.status === 200) {
55 | resolve(parseRateLimitingResponse(response));
56 | }
57 | }).catch((error) => {
58 | reject(errorHandler(error));
59 | });
60 | }).catch((error) => {
61 | reject(error);
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/src/endpoints/index.ts:
--------------------------------------------------------------------------------
1 | import autocomplete from './autocomplete/index.js';
2 | import bulkCompanyEnrichment from './bulkCompanyEnrichment/index.js';
3 | import bulkEnrichment from './bulkEnrichment/index.js';
4 | import bulkRetrieve from './bulkRetrieve/index.js';
5 | import cleaner from './cleaner/index.js';
6 | import enrichment from './enrichment/index.js';
7 | import enrichmentPreview from './enrichmentPreview/index.js';
8 | import identify from './identify/index.js';
9 | import jobTitle from './jobTitle/index.js';
10 | import retrieve from './retrieve/index.js';
11 | import search from './search/index.js';
12 |
13 | export { autocomplete, bulkCompanyEnrichment, bulkEnrichment, bulkRetrieve, cleaner, enrichment, enrichmentPreview, identify, jobTitle, retrieve, search };
14 |
--------------------------------------------------------------------------------
/src/endpoints/ip/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import { IPParams, IPResponse } from '../../types/ip-types.js';
5 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
6 |
7 | export default (
8 | basePath: string,
9 | apiKey: string,
10 | params: IPParams,
11 | ) => new Promise((resolve, reject) => {
12 | check(params, basePath, apiKey, null, 'ip').then(() => {
13 | const headers = {
14 | 'Accept-Encoding': 'gzip',
15 | 'User-Agent': 'PDL-JS-SDK',
16 | };
17 |
18 | axios.get(`${basePath}/ip/enrich`, {
19 | params: {
20 | api_key: apiKey,
21 | ...params,
22 | },
23 | headers,
24 | }).then((response) => {
25 | if (response?.data?.status === 200) {
26 | resolve(parseRateLimitingResponse(response));
27 | }
28 | }).catch((error) => {
29 | reject(errorHandler(error));
30 | });
31 | }).catch((error) => {
32 | reject(error);
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/src/endpoints/jobTitle/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import { JobTitleParams, JobTitleResponse } from '../../types/jobTitle-types.js';
5 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
6 |
7 | export default (
8 | basePath: string,
9 | apiKey: string,
10 | params: JobTitleParams,
11 | ) => new Promise((resolve, reject) => {
12 | check(params, basePath, apiKey, null, 'jobTitle').then(() => {
13 | const {
14 | jobTitle, pretty,
15 | } = params;
16 |
17 | const jobTitleParams = {
18 | job_title: jobTitle,
19 | pretty: pretty || false,
20 | };
21 |
22 | const headers = {
23 | 'Accept-Encoding': 'gzip',
24 | 'User-Agent': 'PDL-JS-SDK',
25 | };
26 |
27 | axios.get(`${basePath}/job_title/enrich`, {
28 | params: {
29 | api_key: apiKey,
30 | ...jobTitleParams,
31 | },
32 | headers,
33 | }).then((response) => {
34 | if (response?.data?.status === 200) {
35 | resolve(parseRateLimitingResponse(response));
36 | }
37 | }).catch((error) => {
38 | reject(errorHandler(error));
39 | });
40 | }).catch((error) => {
41 | reject(error);
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/src/endpoints/retrieve/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import { ApiRetrieveParams, RetrieveParams, RetrieveResponse } from '../../types/retrieve-types.js';
5 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
6 |
7 | const transformRetrieveParams = (params: RetrieveParams): ApiRetrieveParams => {
8 | const filter = params.filter_updated;
9 | if (filter == null) {
10 | return {
11 | ...params,
12 | filter_updated: undefined,
13 | };
14 | }
15 | const filtersArray = Array.isArray(filter) ? filter : [filter];
16 | const filterUpdated = filtersArray.join(',');
17 | return {
18 | ...params,
19 | filter_updated: filterUpdated,
20 | };
21 | };
22 |
23 | export default (
24 | basePath: string,
25 | apiKey: string,
26 | params: RetrieveParams,
27 | ) => new Promise((resolve, reject) => {
28 | check(params, basePath, apiKey, 'ID', 'retrieve').then(() => {
29 | const headers = {
30 | 'Accept-Encoding': 'gzip',
31 | 'User-Agent': 'PDL-JS-SDK',
32 | };
33 | const apiParams = transformRetrieveParams(params);
34 |
35 | axios.get(`${basePath}/person/retrieve/${params.id}`, {
36 | params: {
37 | api_key: apiKey,
38 | ...apiParams,
39 | },
40 | headers,
41 | }).then((response) => {
42 | if (response?.data?.status === 200) {
43 | resolve(parseRateLimitingResponse(response));
44 | }
45 | }).catch((error) => {
46 | reject(errorHandler(error));
47 | });
48 | }).catch((error) => {
49 | reject(error);
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/src/endpoints/search/index.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { check, errorHandler } from '../../errors.js';
4 | import { BaseResponse } from '../../types/api-types.js';
5 | import { BaseSearchParams, SearchType } from '../../types/search-types.js';
6 | import { parseRateLimitingResponse } from '../../utils/api-utils.js';
7 |
8 | export default (
9 | basePath: string,
10 | sandboxBasePath: string,
11 | apiKey: string,
12 | searchType: SearchType,
13 | params: T,
14 | type: string,
15 | ) => new Promise((resolve, reject) => {
16 | check(params, basePath, apiKey, null, 'search').then(() => {
17 | const {
18 | // eslint-disable-next-line @typescript-eslint/naming-convention
19 | data_include, dataset, pretty, sandbox, scroll_token, searchQuery, size, titlecase,
20 | } = params;
21 |
22 | const searchParams = {
23 | titlecase: titlecase || false,
24 | dataset: dataset || 'all',
25 | scroll_token: scroll_token || null,
26 | size: size || 10,
27 | [`${searchType === 'sql' ? 'sql' : 'query'}`]: searchQuery,
28 | pretty: pretty || false,
29 | data_include: data_include || null,
30 | };
31 |
32 | const headers = {
33 | 'Content-Type': 'application/json',
34 | 'Accept-Encoding': 'gzip',
35 | 'X-Api-Key': apiKey,
36 | 'User-Agent': 'PDL-JS-SDK',
37 | };
38 |
39 | const url = sandbox && type === 'person' ? `${sandboxBasePath}/person/search` : `${basePath}/${type}/search`;
40 |
41 | axios.post(url, searchParams, {
42 | headers,
43 | }).then((response) => {
44 | if (response?.data?.status === 200) {
45 | resolve(parseRateLimitingResponse(response));
46 | }
47 | }).catch((error) => {
48 | reject(errorHandler(error));
49 | });
50 | }).catch((error) => {
51 | reject(error);
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/src/errors.ts:
--------------------------------------------------------------------------------
1 | import { AxiosError } from 'axios';
2 |
3 | import { AutoCompleteParams } from './types/autocomplete-types.js';
4 | import { ErrorEndpoint, PdlError } from './types/error-types.js';
5 | import { IPParams } from './types/ip-types.js';
6 | import { JobTitleParams } from './types/jobTitle-types.js';
7 | import { RetrieveParams } from './types/retrieve-types.js';
8 | import { BaseSearchParams } from './types/search-types.js';
9 | import { parseRateLimitingResponse } from './utils/api-utils.js';
10 |
11 | const check = (
12 | params: unknown,
13 | basePath: string,
14 | apiKey: string,
15 | type: string | null,
16 | endpoint: ErrorEndpoint,
17 | ) => new Promise((resolve, reject) => {
18 | const error: { message?: string, status?: number } = { };
19 |
20 | if (!params) {
21 | error.message = `Missing ${type || 'Params'}`;
22 | error.status = 400;
23 | reject(error);
24 | }
25 |
26 | if (endpoint === 'search') {
27 | const { searchQuery } = params as BaseSearchParams;
28 | if (!searchQuery) {
29 | error.message = 'Missing searchQuery';
30 | error.status = 400;
31 | reject(error);
32 | }
33 | }
34 |
35 | if (endpoint === 'retrieve') {
36 | const { id } = params as RetrieveParams;
37 | if (!id) {
38 | error.message = 'Missing id';
39 | error.status = 400;
40 | reject(error);
41 | }
42 | }
43 |
44 | if (endpoint === 'autocomplete') {
45 | const { field } = params as AutoCompleteParams;
46 | const validFields = ['all_location', 'class', 'company', 'country', 'industry', 'location', 'location_name', 'major', 'region', 'role', 'school', 'sub_role', 'skill', 'title'];
47 | if (!field) {
48 | error.message = 'Missing field';
49 | error.status = 400;
50 | reject(error);
51 | } else if (validFields.indexOf(field) === -1) {
52 | error.message = `field should be one of: ${validFields}`;
53 | error.status = 400;
54 | reject(error);
55 | }
56 | }
57 |
58 | if (endpoint === 'jobTitle') {
59 | const { jobTitle } = params as JobTitleParams;
60 | if (!jobTitle) {
61 | error.message = 'Missing jobTitle';
62 | error.status = 400;
63 | reject(error);
64 | }
65 | }
66 |
67 | if (endpoint === 'ip') {
68 | const { ip } = params as IPParams;
69 | if (!ip) {
70 | error.message = 'Missing ip';
71 | error.status = 400;
72 | reject(error);
73 | }
74 | }
75 |
76 | if (!basePath) {
77 | error.message = 'Missing API Base Path';
78 | error.status = 400;
79 | reject(error);
80 | }
81 |
82 | if (!apiKey || apiKey.length !== 64) {
83 | error.message = 'Invalid API Key';
84 | error.status = 401;
85 | reject(error);
86 | }
87 |
88 | resolve();
89 | });
90 |
91 | const errorHandler = (error: AxiosError): PdlError => {
92 | const errorMessages = {
93 | 400: 'Request contained either missing or invalid parameters',
94 | 401: 'Request contained a missing or invalid key',
95 | 402: 'Payment Required, You have hit your account maximum (all matches used)',
96 | 404: 'No records were found matching your request',
97 | 405: 'Request method is not allowed on the requested resource',
98 | 429: 'An error occurred due to requests hitting the API too quick',
99 | 500: 'The server encountered an unexpected condition which prevented it from fulfilling the request',
100 | };
101 |
102 | if (error.response) {
103 | const { status } = error.response;
104 | const statusCode = status >= 500 && status < 600 ? 500 : status;
105 | const { rateLimit } = parseRateLimitingResponse(error.response);
106 |
107 | return ({
108 | status: statusCode,
109 | message: errorMessages[statusCode as keyof typeof errorMessages],
110 | rateLimit,
111 | });
112 | }
113 |
114 | return ({
115 | status: 500,
116 | message: errorMessages[500],
117 | });
118 | };
119 |
120 | export { check, errorHandler };
121 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { autocomplete, bulkCompanyEnrichment, bulkEnrichment, bulkRetrieve, cleaner, enrichment, enrichmentPreview, identify, jobTitle, retrieve, search } from './endpoints/index.js';
2 | import ip from './endpoints/ip/index.js';
3 | import { APISettings } from './types/api-types.js';
4 | import { AutoCompleteParams, AutoCompleteResponse } from './types/autocomplete-types.js';
5 | import { BulkPersonRetrieveParams, BulkPersonRetrieveResponse } from './types/bulk-retrieve-types.js';
6 | import { BulkCompanyEnrichmentParams, BulkCompanyEnrichmentResponse, BulkPersonEnrichmentParams, BulkPersonEnrichmentResponse } from './types/bulk-types.js';
7 | import { CompanyCleanerParams, CompanyCleanerResponse, LocationCleanerParams, LocationCleanerResponse, SchoolCleanerParams, SchoolCleanerResponse } from './types/cleaner-types.js';
8 | import { CompanyResponse, PersonResponse } from './types/common-types.js';
9 | import { CompanyEnrichmentParams, CompanyEnrichmentResponse, PersonEnrichmentParams, PersonEnrichmentPreviewParams, PersonEnrichmentPreviewResponse, PersonEnrichmentResponse, PersonPreviewResponse } from './types/enrichment-types.js';
10 | import { IdentifyParams, IdentifyResponse } from './types/identify-types.js';
11 | import { IPParams, IPResponse } from './types/ip-types.js';
12 | import { JobTitleParams, JobTitleResponse } from './types/jobTitle-types.js';
13 | import { RetrieveParams, RetrieveResponse } from './types/retrieve-types.js';
14 | import { CompanySearchParams, CompanySearchResponse, PersonSearchParams, PersonSearchResponse } from './types/search-types.js';
15 |
16 | class PDLJS {
17 | private readonly apiKey: string;
18 |
19 | private readonly basePath: string;
20 |
21 | private readonly sandboxBasePath: string;
22 |
23 | public person: {
24 | bulk: {
25 | enrichment: (records: BulkPersonEnrichmentParams) => Promise;
26 | retrieve: (records: BulkPersonRetrieveParams) => Promise;
27 | };
28 | enrichment: (params: PersonEnrichmentParams) => Promise;
29 | enrichmentPreview: (params: PersonEnrichmentPreviewParams) => Promise;
30 | identify: (params: IdentifyParams) => Promise;
31 | retrieve: (params: RetrieveParams) => Promise;
32 | search: {
33 | elastic: (params: PersonSearchParams) => Promise;
34 | sql: (params: PersonSearchParams) => Promise;
35 | };
36 | };
37 |
38 | public company: {
39 | bulk: {
40 | enrichment: (records: BulkCompanyEnrichmentParams) => Promise;
41 | };
42 | cleaner: (params: CompanyCleanerParams) => Promise;
43 | enrichment: (params: CompanyEnrichmentParams) => Promise;
44 | search: {
45 | elastic: (params: CompanySearchParams) => Promise;
46 | sql: (params: CompanySearchParams) => Promise;
47 | };
48 | };
49 |
50 | public school: { cleaner: (params: SchoolCleanerParams) => Promise };
51 |
52 | public location: { cleaner: (params: LocationCleanerParams) => Promise };
53 |
54 | public autocomplete: (params: AutoCompleteParams) => Promise;
55 |
56 | public jobTitle: (params: JobTitleParams) => Promise;
57 |
58 | public ip: (params: IPParams) => Promise;
59 |
60 | constructor({
61 | apiKey,
62 | basePath,
63 | sandboxBasePath,
64 | version,
65 | }: APISettings) {
66 | this.apiKey = apiKey;
67 | this.basePath = basePath || `https://api.peopledatalabs.com/${version || 'v5'}`;
68 | this.sandboxBasePath = sandboxBasePath || `https://sandbox.api.peopledatalabs.com/${version || 'v5'}`;
69 |
70 | this.person = {
71 | enrichment: (params) => enrichment(this.basePath, this.sandboxBasePath, this.apiKey, params, 'person'),
72 | enrichmentPreview: (params) => enrichmentPreview(this.basePath, this.sandboxBasePath, this.apiKey, params),
73 | search: {
74 | elastic: (params) => search(this.basePath, this.sandboxBasePath, this.apiKey, 'elastic', params, 'person'),
75 | sql: (params) => search(this.basePath, this.sandboxBasePath, this.apiKey, 'sql', params, 'person'),
76 | },
77 | bulk: {
78 | enrichment: (records) => bulkEnrichment(this.basePath, this.apiKey, records),
79 | retrieve: (records) => bulkRetrieve(this.basePath, this.apiKey, records),
80 | },
81 | identify: (params) => identify(this.basePath, this.sandboxBasePath, this.apiKey, params),
82 | retrieve: (params) => retrieve(this.basePath, this.apiKey, params),
83 | };
84 |
85 | this.company = {
86 | enrichment: (params) => enrichment(this.basePath, this.sandboxBasePath, this.apiKey, params, 'company'),
87 | search: {
88 | elastic: (params) => search(this.basePath, this.sandboxBasePath, this.apiKey, 'elastic', params, 'company'),
89 | sql: (params) => search(this.basePath, this.sandboxBasePath, this.apiKey, 'sql', params, 'company'),
90 | },
91 | bulk: {
92 | enrichment: (records) => bulkCompanyEnrichment(this.basePath, this.apiKey, records),
93 | },
94 | cleaner: (params) => cleaner(this.basePath, this.apiKey, params, 'company'),
95 | };
96 |
97 | this.school = {
98 | cleaner: (params) => cleaner(this.basePath, this.apiKey, params, 'school'),
99 | };
100 |
101 | this.location = {
102 | cleaner: (params) => cleaner(this.basePath, this.apiKey, params, 'location'),
103 | };
104 |
105 | this.autocomplete = (params: AutoCompleteParams) => autocomplete(this.basePath, this.apiKey, params);
106 |
107 | this.jobTitle = (params: JobTitleParams) => jobTitle(this.basePath, this.apiKey, params);
108 |
109 | this.ip = (params: IPParams) => ip(this.basePath, this.apiKey, params);
110 | }
111 | }
112 |
113 | export default PDLJS;
114 |
115 | export type {
116 | APISettings,
117 | AutoCompleteParams,
118 | AutoCompleteResponse,
119 | BulkCompanyEnrichmentParams,
120 | BulkCompanyEnrichmentResponse,
121 | BulkPersonEnrichmentParams,
122 | BulkPersonEnrichmentResponse,
123 | BulkPersonRetrieveParams,
124 | BulkPersonRetrieveResponse,
125 | CompanyCleanerParams,
126 | CompanyCleanerResponse,
127 | CompanyEnrichmentParams,
128 | CompanyEnrichmentResponse,
129 | CompanyResponse,
130 | CompanySearchParams,
131 | CompanySearchResponse,
132 | IdentifyParams,
133 | IdentifyResponse,
134 | IPParams,
135 | IPResponse,
136 | JobTitleParams,
137 | JobTitleResponse,
138 | LocationCleanerParams,
139 | LocationCleanerResponse,
140 | PersonEnrichmentParams,
141 | PersonEnrichmentPreviewParams,
142 | PersonEnrichmentPreviewResponse,
143 | PersonEnrichmentResponse,
144 | PersonPreviewResponse,
145 | PersonResponse,
146 | PersonSearchParams,
147 | PersonSearchResponse,
148 | RetrieveParams,
149 | RetrieveResponse,
150 | SchoolCleanerParams,
151 | SchoolCleanerResponse,
152 | };
153 |
--------------------------------------------------------------------------------
/src/types/api-types.ts:
--------------------------------------------------------------------------------
1 | export interface APISettings {
2 | apiKey: string;
3 | basePath?: string;
4 | sandboxBasePath?: string;
5 | version?: string;
6 | }
7 |
8 | export interface RateLimit {
9 | callCreditsSpent?: number | null;
10 | callCreditsType?: string | null;
11 | lifetimeUsed?: number | null;
12 | rateLimitLimit?: RateLimitLimit | null;
13 | rateLimitRemaining?: RateLimitRemaining | null;
14 | rateLimitReset?: string | null;
15 | totalLimitOveragesRemaining?: number | null;
16 | totalLimitPurchasedRemaining?: number | null;
17 | totalLimitRemaining?: number | null;
18 | }
19 |
20 | export interface BaseResponse {
21 | rateLimit: RateLimit;
22 | status: number;
23 | }
24 |
25 | export interface RateLimitRemaining {
26 | day?: number | null;
27 | minute?: number | null;
28 | month?: number | null;
29 | }
30 |
31 | export interface RateLimitLimit {
32 | day?: number | null;
33 | minute?: number | null;
34 | month?: number | null;
35 | }
36 |
--------------------------------------------------------------------------------
/src/types/autocomplete-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse } from './api-types.js';
2 | import { IndustryType, JobTitleRole } from './canonical-types.js';
3 |
4 | export type AutoCompleteField = 'all_location' | 'class' | 'company' | 'country' | 'industry' | 'location' | 'location_name' | 'major' | 'region' | 'role' | 'school' | 'sub_role' | 'skill' | 'title' | 'website';
5 |
6 | export interface AutoCompleteParams {
7 | field: AutoCompleteField;
8 | pretty?: boolean;
9 | size?: number;
10 | text?: string;
11 | titlecase?: boolean;
12 | }
13 |
14 | export interface AutoCompleteResponse extends BaseResponse {
15 | data?: Array<{
16 | count: number | null;
17 | meta?: {
18 | alternative_names?: Array | null;
19 | country?: string | null;
20 | display_name?: string | null;
21 | display_name_history?: Array | null;
22 | fields?: Array | null;
23 | id?: string | null;
24 | industry?: IndustryType | null;
25 | locality?: string | null;
26 | location_name?: string | null;
27 | region?: string | null;
28 | role?: JobTitleRole | null;
29 | website?: string | null;
30 | } | null;
31 | name?: string | null;
32 | }>;
33 | fields?: Array | null;
34 | }
35 |
--------------------------------------------------------------------------------
/src/types/bulk-retrieve-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse, RateLimit } from './api-types.js';
2 | import { PersonResponse } from './common-types.js';
3 | import { ApiRetrieveMetaParams, RetrieveMetaParams } from './retrieve-types.js';
4 |
5 | export type BulkPersonRetrieveRequest = {
6 | id: string;
7 | metadata?: unknown;
8 | };
9 |
10 | export interface BulkPersonRetrieveParams extends RetrieveMetaParams {
11 | requests: Array;
12 | }
13 |
14 | export interface ApiBulkPersonRetrieveParams extends ApiRetrieveMetaParams {
15 | requests: Array;
16 | }
17 |
18 | export interface BulkPersonRetrieveResponseItem extends BaseResponse {
19 | billed: boolean;
20 | data: PersonResponse;
21 | metadata?: unknown;
22 | }
23 |
24 | // This response does not extend from the BaseResponse since each item in the array has its own status
25 | // See https://docs.peopledatalabs.com/docs/bulk-requests
26 | export type BulkPersonRetrieveResponse = {
27 | items: Array;
28 | rateLimit: RateLimit;
29 | };
30 |
--------------------------------------------------------------------------------
/src/types/bulk-types.ts:
--------------------------------------------------------------------------------
1 | import { RateLimit } from './api-types.js';
2 | import { CompanyEnrichmentParams, CompanyEnrichmentResponse, PersonEnrichmentParams, PersonEnrichmentResponse } from './enrichment-types.js';
3 |
4 | export interface BulkPersonEnrichmentRequest {
5 | metadata?: unknown;
6 | params: PersonEnrichmentParams; // The user can define their own custom metadata
7 | }
8 |
9 | export interface BulkPersonEnrichmentParams {
10 | requests: Array & {
11 | include_if_matched?: boolean;
12 | pretty?: boolean;
13 | titlecase?: boolean;
14 | };
15 | }
16 |
17 | export interface BulkPersonEnrichmentResponseItem extends PersonEnrichmentResponse {
18 | metadata?: unknown;
19 | }
20 |
21 | export type BulkPersonEnrichmentResponse = {
22 | items: Array;
23 | rateLimit: RateLimit;
24 | };
25 |
26 | export interface BulkCompanyEnrichmentRequest {
27 | metadata?: unknown;
28 | params: CompanyEnrichmentParams; // The user can define their own custom metadata
29 | }
30 |
31 | export interface BulkCompanyEnrichmentParams {
32 | requests: Array & {
33 | include_if_matched?: boolean;
34 | pretty?: boolean;
35 | titlecase?: boolean;
36 | };
37 | }
38 |
39 | export interface BulkCompanyEnrichmentResponseItem extends CompanyEnrichmentResponse {
40 | metadata?: unknown;
41 | }
42 |
43 | export type BulkCompanyEnrichmentResponse = {
44 | items: Array;
45 | rateLimit: RateLimit;
46 | };
47 |
--------------------------------------------------------------------------------
/src/types/canonical-types.ts:
--------------------------------------------------------------------------------
1 | export type EmailType = 'current_professional' | 'disposable' | 'personal' | 'professional';
2 |
3 | export type CompanyType = 'educational' | 'government' | 'nonprofit' | 'private' | 'public' | 'public_subsidiary';
4 |
5 | export type CompanySize = '1-10' | '11-50' | '51-200' | '201-500' | '501-1000' | '1001-5000' | '5001-10000' | '10001+';
6 |
7 | export type Continent = 'africa' | 'antarctica' | 'asia' | 'europe' | 'north america' | 'oceania' | 'south america';
8 |
9 | export type Currencies = 'aed' | 'afn' | 'all' | 'amd' | 'ang' | 'aoa' | 'ars' | 'aud' | 'awg' | 'azn' | 'bam' | 'bbd' | 'bdt' | 'bgn' | 'bhd' | 'bif' | 'bmd' | 'bnd' | 'bob' | 'brl' | 'bsd' | 'btn' | 'bwp' | 'byr' | 'bzd' | 'cad' | 'cdf' | 'cfa' | 'chf' | 'clp' | 'cny' | 'cop' | 'crc' | 'cup' | 'cve' | 'czk' | 'djf' | 'dkk' | 'dop' | 'dzd' | 'ecs' | 'egp' | 'ern' | 'etb' | 'eur' | 'fjd' | 'fkp' | 'gbp' | 'gel' | 'ghs' | 'gip' | 'gmd' | 'gnf' | 'gyd' | 'hkd' | 'hnl' | 'hrk' | 'htg' | 'huf' | 'idr' | 'ils' | 'inr' | 'iqd' | 'irr' | 'isk' | 'jmd' | 'jod' | 'jpy' | 'kes' | 'kgs' | 'khr' | 'kmf' | 'kpw' | 'krw' | 'kwd' | 'kyd' | 'kzt' | 'lak' | 'lbp' | 'lkr' | 'lrd' | 'lsl' | 'ltl' | 'lvl' | 'lyd' | 'mad' | 'mdl' | 'mgf' | 'mkd' | 'mmr' | 'mnt' | 'mop' | 'mro' | 'mur' | 'mvr' | 'mwk' | 'mxn' | 'myr' | 'mzn' | 'nad' | 'ngn' | 'nio' | 'nok' | 'npr' | 'nzd' | 'omr' | 'pab' | 'pen' | 'pgk' | 'php' | 'pkr' | 'pln' | 'pyg' | 'qar' | 'qtq' | 'ron' | 'rsd' | 'rub' | 'rwf' | 'sar' | 'sbd' | 'scr' | 'sdg' | 'sek' | 'sgd' | 'shp' | 'sll' | 'sos' | 'srd' | 'ssp' | 'std' | 'svc' | 'syp' | 'szl' | 'thb' | 'tjs' | 'tmt' | 'tnd' | 'top' | 'try' | 'ttd' | 'tzs' | 'uah' | 'ugx' | 'usd' | 'uyu' | 'uzs' | 'vef' | 'vnd' | 'vuv' | 'wst' | 'xaf' | 'xcd' | 'xof' | 'xpf' | 'yer' | 'zar' | 'zmw' | 'zwd';
10 |
11 | export type FundingRoundType = 'angel' | 'convertible_note' | 'corporate_round' | 'debt_financing' | 'equity_crowdfunding' | 'funding_round' | 'grant' | 'initial_coin_offering' | 'non_equity_assistance' | 'post_ipo_debt' | 'post_ipo_equity' | 'post_ipo_secondary' | 'pre_seed' | 'private_equity' | 'product_crowdfunding' | 'secondary_market' | 'seed' | 'series_a' | 'series_b' | 'series_c' | 'series_d' | 'series_e' | 'series_f' | 'series_g' | 'series_h' | 'series_i' | 'series_j' | 'series_unknown' | 'undisclosed';
12 |
13 | export type IndustryType = 'accounting' | 'airlines/aviation' | 'alternative dispute resolution' | 'alternative medicine' | 'animation' | 'apparel & fashion' | 'architecture & planning' | 'arts and crafts' | 'automotive' | 'aviation & aerospace' | 'banking' | 'biotechnology' | 'broadcast media' | 'building materials' | 'business supplies and equipment' | 'capital markets' | 'chemicals' | 'civic & social organization' | 'civil engineering' | 'commercial real estate' | 'computer & network security' | 'computer games' | 'computer hardware' | 'computer networking' | 'computer software' | 'construction' | 'consumer electronics' | 'consumer goods' | 'consumer services' | 'cosmetics' | 'dairy' | 'defense & space' | 'design' | 'e-learning' | 'education management' | 'electrical/electronic manufacturing' | 'entertainment' | 'environmental services' | 'events services' | 'executive office' | 'facilities services' | 'farming' | 'financial services' | 'fine art' | 'fishery' | 'food & beverages' | 'food production' | 'fund-raising' | 'furniture' | 'gambling & casinos' | 'glass, ceramics & concrete' | 'government administration' | 'government relations' | 'graphic design' | 'health, wellness and fitness' | 'higher education' | 'hospital & health care' | 'hospitality' | 'human resources' | 'import and export' | 'individual & family services' | 'industrial automation' | 'information services' | 'information technology and services' | 'insurance' | 'international affairs' | 'international trade and development' | 'internet' | 'investment banking' | 'investment management' | 'judiciary' | 'law enforcement' | 'law practice' | 'legal services' | 'legislative office' | 'leisure, travel & tourism' | 'libraries' | 'logistics and supply chain' | 'luxury goods & jewelry' | 'machinery' | 'management consulting' | 'maritime' | 'market research' | 'marketing and advertising' | 'mechanical or industrial engineering' | 'media production' | 'medical devices' | 'medical practice' | 'mental health' | 'military' | 'mining & metals' | 'motion pictures and film' | 'museums and institutions' | 'music' | 'nanotechnology' | 'newspapers' | 'non-profit organization management' | 'oil & energy' | 'online media' | 'outsourcing/offshoring' | 'package/freight delivery' | 'packaging and containers' | 'paper & forest products' | 'performing arts' | 'pharmaceuticals' | 'philanthropy' | 'photography' | 'plastics' | 'political organization' | 'primary/secondary education' | 'printing' | 'professional training & coaching' | 'program development' | 'public policy' | 'public relations and communications' | 'public safety' | 'publishing' | 'railroad manufacture' | 'ranching' | 'real estate' | 'recreational facilities and services' | 'religious institutions' | 'renewables & environment' | 'research' | 'restaurants' | 'retail' | 'security and investigations' | 'semiconductors' | 'shipbuilding' | 'sporting goods' | 'sports' | 'staffing and recruiting' | 'supermarkets' | 'telecommunications' | 'textiles' | 'think tanks' | 'tobacco' | 'translation and localization' | 'transportation/trucking/railroad' | 'utilities' | 'venture capital & private equity' | 'veterinary' | 'warehousing' | 'wholesale' | 'wine and spirits' | 'wireless' | 'writing and editing';
14 |
15 | export type InferredRevenue = '$0-$1M' | '$1M-$10M' | '$10M-$25M' | '$25M-$50M' | '$50M-$100M' | '$100M-$250M' | '$250M-$500M' | '$500M-$1B' | '$1B-$10B' | '$10B+';
16 |
17 | export type InferredSalary = '<20,000' | '20,000-25,000' | '25,000-35,000' | '35,000-45,000' | '45,000-55,000' | '55,000-70,000' | '70,000-85,000' | '85,000-100,000' | '100,000-150,000' | '150,000-250,000' | '> 250,000';
18 |
19 | export type JobTitleClass = 'general_and_administrative' | 'research_and_development' | 'sales_and_marketing' | 'services' | 'unemployed';
20 |
21 | export type JobTitleLevel = 'cxo' | 'director' | 'entry' | 'manager' | 'owner' | 'partner' | 'senior' | 'training' | 'unpaid' | 'vp';
22 |
23 | export type JobTitleRole = 'advisory' | 'analyst' | 'creative' | 'education' | 'engineering' | 'finance' | 'fulfillment' | 'health' | 'hospitality' | 'human_resources' | 'legal' | 'manufacturing' | 'marketing' | 'operations' | 'partnerships' | 'product' | 'professional_service' | 'public_service' | 'research' | 'sales' | 'sales_engineering' | 'support' | 'trade' | 'unemployed';
24 |
25 | export type JobTitleSubRole = 'academic' | 'account_executive' | 'account_management' | 'accounting' | 'accounting_services' | 'administrative' | 'advisor' | 'agriculture' | 'aides' | 'architecture' | 'artist' | 'board_member' | 'bookkeeping' | 'brand' | 'building_and_grounds' | 'business_analyst' | 'business_development' | 'chemical' | 'compliance' | 'construction' | 'consulting' | 'content' | 'corporate_development' | 'curation' | 'customer_success' | 'customer_support' | 'data_analyst' | 'data_engineering' | 'data_science' | 'dental' | 'devops' | 'doctor' | 'electric' | 'electrical' | 'emergency_services' | 'entertainment' | 'executive' | 'fashion' | 'financial' | 'fitness' | 'fraud' | 'graphic_design' | 'growth' | 'hair_stylist' | 'hardware' | 'health_and_safety' | 'human_resources' | 'implementation' | 'industrial' | 'information_technology' | 'insurance' | 'investment_banking' | 'investor' | 'investor_relations' | 'journalism' | 'judicial' | 'legal' | 'legal_services' | 'logistics' | 'machinist' | 'marketing_design' | 'marketing_services' | 'mechanic' | 'mechanical' | 'military' | 'network' | 'nursing' | 'partnerships' | 'pharmacy' | 'planning_and_analysis' | 'plumbing' | 'political' | 'primary_and_secondary' | 'procurement' | 'product_design' | 'product_management' | 'professor' | 'project_management' | 'protective_service' | 'qa_engineering' | 'quality_assurance' | 'realtor' | 'recruiting' | 'restaurants' | 'retail' | 'revenue_operations' | 'risk' | 'sales_development' | 'scientific' | 'security' | 'social_service' | 'software' | 'solutions_engineer' | 'strategy' | 'student' | 'talent_analytics' | 'therapy' | 'tour_and_travel' | 'training' | 'translation' | 'transport' | 'unemployed' | 'veterinarian' | 'warehouse' | 'web' | 'wellness';
26 |
27 | export type LanguageName = 'afrikaans' | 'akan' | 'albanian' | 'amazigh' | 'american sign language' | 'amharic' | 'arabic' | 'aramaic' | 'armenian' | 'assamese' | 'aymara' | 'azerbaijani' | 'balochi' | 'bambara' | 'banda' | 'bashkort' | 'basque' | 'belarusian' | 'bemba' | 'bengali' | 'bhojpuri' | 'bislama' | 'bosnian' | 'brahui' | 'bulgarian' | 'burmese' | 'cantonese' | 'catalan' | 'cebuano' | 'chechen' | 'cherokee' | 'chewa' | 'croatian' | 'czech' | 'dakota' | 'danish' | 'dari' | 'dholuo' | 'dinka' | 'dutch' | 'english' | 'esperanto' | 'estonian' | 'ewe' | 'farsi' | 'filipino' | 'finnish' | 'fon' | 'french' | 'fula' | 'galician' | 'georgian' | 'german' | 'gikuyu' | 'greek' | 'guarani' | 'gujarati' | 'haitian creole' | 'hausa' | 'hawaiian' | 'hawaiian creole' | 'hebrew' | 'hiligaynon' | 'hindi' | 'hungarian' | 'icelandic' | 'igbo' | 'ilocano' | 'indonesian' | 'inuit/inupiaq' | 'irish gaelic' | 'italian' | 'japanese' | 'jarai' | 'javanese' | 'k\'iche\'' | 'kabyle' | 'kannada' | 'kashmiri' | 'kazakh' | 'khmer' | 'khoekhoe' | 'kinyarwanda' | 'kongo' | 'konkani' | 'korean' | 'kurdish' | 'kyrgyz' | 'lao' | 'latin' | 'latvian' | 'lingala' | 'lithuanian' | 'macedonian' | 'maithili' | 'malagasy' | 'malay' | 'malayalam' | 'mandarin' | 'mandinka' | 'marathi' | 'mende' | 'mongolian' | 'nahuatl' | 'navajo' | 'nepali' | 'norwegian' | 'ojibwa' | 'oriya' | 'oromo' | 'pashto' | 'persian' | 'polish' | 'portuguese' | 'punjabi' | 'quechua' | 'romani' | 'romanian' | 'russian' | 'samoan' | 'sanskrit' | 'serbian' | 'shona' | 'sindhi' | 'sinhala' | 'sinhalese' | 'slovak' | 'slovene' | 'slovenian' | 'somali' | 'songhay' | 'spanish' | 'swahili' | 'swazi' | 'swedish' | 'tachelhit' | 'tagalog' | 'taiwanese' | 'tajiki' | 'tamil' | 'tatar' | 'telugu' | 'thai' | 'tibetic languages' | 'tigrigna' | 'tok pisin' | 'tonga' | 'tsonga' | 'tswana' | 'tuareg' | 'turkish' | 'turkmen' | 'ukrainian' | 'urdu' | 'uyghur' | 'uzbek' | 'vietnamese' | 'warlpiri' | 'welsh' | 'wolof' | 'xhosa' | 'yakut' | 'yiddish' | 'yoruba' | 'yucatec' | 'zapotec' | 'zulu';
28 |
29 | export type MICCode = 'alxl' | 'asex' | 'bvca' | 'misx' | 'notc' | 'pinx' | 'xams' | 'xase' | 'xasx' | 'xber' | 'xbkk' | 'xbom' | 'xbru' | 'xbsp' | 'xbud' | 'xbue' | 'xcai' | 'xcnq' | 'xcol' | 'xcse' | 'xdub' | 'xdus' | 'xetr' | 'xfka' | 'xfra' | 'xham' | 'xhan' | 'xhkg' | 'xidx' | 'xist' | 'xjse' | 'xkls' | 'xkos' | 'xkrx' | 'xlon' | 'xmce' | 'xmex' | 'xmil' | 'xmun' | 'xnas' | 'xngm' | 'xnms' | 'xnse' | 'xnys' | 'xnys' | 'xnze' | 'xosl' | 'xpar' | 'xpra' | 'xsap' | 'xsau' | 'xses' | 'xsgo' | 'xshe' | 'xshg' | 'xsto' | 'xstu' | 'xtae' | 'xtai' | 'xtse' | 'xwbo';
30 |
31 | export type ProfileNetwork = 'aboutme' | 'angellist' | 'behance' | 'crunchbase' | 'dribbble' | 'ello' | 'facebook' | 'flickr' | 'foursquare' | 'github' | 'gitlab' | 'google' | 'gravatar' | 'indeed' | 'instagram' | 'klout' | 'linkedin' | 'medium' | 'meetup' | 'myspace' | 'pinterest' | 'quora' | 'reddit' | 'soundcloud' | 'stackoverflow' | 'twitter' | 'vimeo' | 'wordpress' | 'xing' | 'youtube';
32 |
--------------------------------------------------------------------------------
/src/types/cleaner-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse } from './api-types.js';
2 | import { LocationResponse } from './common-types.js';
3 | import { RequireAtLeastOne } from './utility-types.js';
4 |
5 | export type CleanerType = 'company' | 'school' | 'location';
6 |
7 | /* ---------------------------------------------------------- */
8 | /* ------------------------- Company ------------------------ */
9 | /* ---------------------------------------------------------- */
10 |
11 | export type CompanyCleanerParams = RequireAtLeastOne<{
12 | name: string;
13 | profile: string;
14 | website: string;
15 | }> & {
16 | pretty?: boolean;
17 | };
18 |
19 | export interface CompanyCleanerResponse extends BaseResponse {
20 | facebook_url: string | null;
21 | founded?: number | null;
22 | fuzzy_match: boolean | null;
23 | id?: string | null;
24 | industry?: string | null;
25 | linkedin_id: string | null;
26 | linkedin_url: string | null;
27 | location?: Omit | null;
28 | name?: string | null;
29 | score?: number | null;
30 | size?: string | null;
31 | ticker?: string | null;
32 | twitter_url: string | null;
33 | type?: string | null;
34 | website: string | null;
35 | }
36 |
37 | /* ---------------------------------------------------------- */
38 | /* ------------------------- School ------------------------- */
39 | /* ---------------------------------------------------------- */
40 |
41 | export type SchoolCleanerParams = RequireAtLeastOne<{
42 | name: string;
43 | profile: string;
44 | website: string;
45 | }> & {
46 | pretty?: boolean;
47 | };
48 |
49 | export interface SchoolCleanerResponse extends BaseResponse {
50 | domain?: string | null;
51 | facebook_url?: string | null;
52 | id?: string | null;
53 | linkedin_id?: string | null;
54 | linkedin_url?: string | null;
55 | location: {
56 | continent?: string | null;
57 | country?: string | null;
58 | locality?: string | null;
59 | name?: string | null;
60 | region?: string | null;
61 | } | null;
62 | name?: string | null;
63 | twitter_url?: string | null;
64 | type?: string | null;
65 | website?: string | null;
66 | }
67 |
68 | /* ---------------------------------------------------------- */
69 | /* ------------------------ Location ------------------------ */
70 | /* ---------------------------------------------------------- */
71 |
72 | export interface LocationCleanerParams {
73 | location: string;
74 | pretty?: boolean;
75 | }
76 |
77 | export interface LocationCleanerResponse extends BaseResponse {
78 | continent?: string | null;
79 | country?: string | null;
80 | geo?: string | null;
81 | locality?: string | null;
82 | name?: string | null;
83 | region?: string | null;
84 | subregion?: string | null;
85 | type?: string | null;
86 | }
87 |
--------------------------------------------------------------------------------
/src/types/common-types.ts:
--------------------------------------------------------------------------------
1 | import type { CompanySize, CompanyType, Continent, Currencies, EmailType, FundingRoundType, IndustryType, InferredRevenue, InferredSalary, JobTitleClass, JobTitleLevel, JobTitleRole, JobTitleSubRole, LanguageName, MICCode, ProfileNetwork } from './canonical-types.js';
2 |
3 | export interface LocationResponse {
4 | address_line_2?: string | null;
5 | continent?: Continent | null;
6 | country?: string | null;
7 | geo?: string | null;
8 | locality?: string | null;
9 | metro?: string | null;
10 | name?: string | null;
11 | postal_code?: string | null;
12 | region?: string | null;
13 | street_address?: string | null;
14 | }
15 |
16 | export interface PersonEmailResponse {
17 | address?: string | null;
18 | first_seen?: string | null;
19 | last_seen?: string | null;
20 | num_sources?: number | null;
21 | type?: EmailType | null;
22 | }
23 |
24 | export interface PersonExperienceResponse {
25 | company?: {
26 | facebook_url?: string | null;
27 | founded?: number | null;
28 | fuzzy_match?: boolean | null;
29 | id?: string | null;
30 | industry?: IndustryType | null;
31 | linkedin_id?: string | null;
32 | linkedin_url?: string | null;
33 | location?: LocationResponse | null;
34 | name?: string | null;
35 | raw?: Array | null;
36 | size?: CompanySize | null;
37 | ticker?: string | null;
38 | twitter_url?: string | null;
39 | type?: CompanyType | null;
40 | website?: string | null;
41 | } | null;
42 | end_date?: string | null;
43 | first_seen?: string | null;
44 | is_primary?: boolean | null;
45 | last_seen?: string | null;
46 | location_names?: Array | null;
47 | num_sources?: number | null;
48 | start_date?: string | null;
49 | summary?: string | null;
50 | title?: {
51 | class?: JobTitleClass | null;
52 | levels?: Array | null;
53 | name?: string | null;
54 | raw?: Array | null;
55 | role?: JobTitleRole | null;
56 | sub_role?: JobTitleSubRole | null;
57 | } | null;
58 | }
59 |
60 | export interface PersonEducationResponse {
61 | degrees?: Array | null;
62 | end_date?: string | null;
63 | gpa?: number | null;
64 | majors?: Array | null;
65 | minors?: Array | null;
66 | raw?: Array | null;
67 | school?: {
68 | domain?: string | null;
69 | facebook_url?: string | null;
70 | id?: string | null;
71 | linkedin_id?: string | null;
72 | linkedin_url?: string | null;
73 | location?: LocationResponse | null;
74 | name?: string | null;
75 | raw?: Array | null;
76 | twitter_url?: string | null;
77 | type?: string | null;
78 | website?: string | null;
79 | } | null;
80 | start_date?: string | null;
81 | summary?: string | null;
82 | }
83 |
84 | export interface PersonProfileResponse {
85 | first_seen?: string | null;
86 | id?: string | null;
87 | last_seen?: string | null;
88 | network?: ProfileNetwork | null;
89 | num_sources?: number | null;
90 | url?: string | null;
91 | username?: string | null;
92 | }
93 |
94 | export interface PersonPhoneResponse {
95 | first_seen?: string | null;
96 | last_seen?: string | null;
97 | num_sources?: number | null;
98 | number?: string | null;
99 | }
100 |
101 | export interface PersonStreetAddressResponse {
102 | address_line_2?: string | null;
103 | continent?: Continent | null;
104 | country?: string | null;
105 | first_seen?: string | null;
106 | full_address?: string | null;
107 | geo?: string | null;
108 | last_seen?: string | null;
109 | locality?: string | null;
110 | metro?: string | null;
111 | name?: string | null;
112 | num_sources?: number | null;
113 | postal_code?: string | null;
114 | region?: string | null;
115 | street_address?: string | null;
116 | }
117 |
118 | export interface PersonCertificateResponse {
119 | end_date?: string | null;
120 | name?: string | null;
121 | organization?: string | null;
122 | start_date?: string | null;
123 | }
124 |
125 | export interface PersonBirthdateResponse {
126 | day?: string | null;
127 | month?: string | null;
128 | year?: string | null;
129 | }
130 |
131 | export interface PersonLanguageResponse {
132 | name?: LanguageName | null;
133 | proficiency?: number | null;
134 | }
135 |
136 | export interface PersonJobHistoryResponse {
137 | company_id?: string | null;
138 | company_name?: string | null;
139 | first_seen?: string | null;
140 | last_seen?: string | null;
141 | num_sources?: number | null;
142 | title?: string | null;
143 | }
144 |
145 | export interface VersionStatus {
146 | contains?: Array | null;
147 | current_version?: string | null;
148 | previous_version?: string | null;
149 | status?: string | null;
150 | }
151 |
152 | export interface PersonResponse {
153 | birth_date?: string | boolean | null;
154 | birth_year?: number | boolean | null;
155 | certifications?: Array | null;
156 | countries?: Array | null;
157 | dataset_version?: string | null;
158 | education?: Array | null;
159 | emails?: Array | boolean | null;
160 | experience?: Array | null;
161 | facebook_friends?: number | null;
162 | facebook_id?: string | null;
163 | facebook_url?: string | null;
164 | facebook_username?: string | null;
165 | first_name?: string | null;
166 | first_seen?: string | null;
167 | full_name?: string | null;
168 | github_url?: string | null;
169 | github_username?: string | null;
170 | headline?: string | null;
171 | id?: string | null;
172 | industry?: IndustryType | null;
173 | inferred_salary?: InferredSalary | null;
174 | inferred_years_experience?: number | null;
175 | interests?: Array | null;
176 | job_company_12mo_employee_growth_rate?: number | null;
177 | job_company_employee_count?: number | null;
178 | job_company_facebook_url?: string | null;
179 | job_company_founded?: number | null;
180 | job_company_id?: string | null;
181 | job_company_industry?: IndustryType | null;
182 | job_company_inferred_revenue?: InferredRevenue | null;
183 | job_company_linkedin_id?: string | null;
184 | job_company_linkedin_url?: string | null;
185 | job_company_location_address_line_2?: string | null;
186 | job_company_location_continent?: Continent | null;
187 | job_company_location_country?: string | null;
188 | job_company_location_geo?: string | null;
189 | job_company_location_locality?: string | null;
190 | job_company_location_metro?: string | null;
191 | job_company_location_name?: string | null;
192 | job_company_location_postal_code?: string | null;
193 | job_company_location_region?: string | null;
194 | job_company_location_street_address?: string | null;
195 | job_company_name?: string | null;
196 | job_company_size?: CompanySize | null;
197 | job_company_ticker?: string | null;
198 | job_company_total_funding_raised?: number | null;
199 | job_company_twitter_url?: string | null;
200 | job_company_type?: CompanyType | null;
201 | job_company_website?: string | null;
202 | job_history?: Array | null;
203 | job_last_changed?: string | null;
204 | job_last_verified?: string | null;
205 | job_onet_broad_occupation?: string | null;
206 | job_onet_code?: string | null;
207 | job_onet_major_group?: string | null;
208 | job_onet_minor_group?: string | null;
209 | job_onet_specific_occupation?: string | null;
210 | job_onet_specific_occupation_detail?: string | null;
211 | job_start_date?: string | null;
212 | job_summary?: string | null;
213 | job_title?: string | null;
214 | job_title_class?: JobTitleClass | null;
215 | job_title_levels?: Array | null;
216 | job_title_role?: JobTitleRole | null;
217 | job_title_sub_role?: JobTitleSubRole | null;
218 | languages?: Array | null;
219 | last_initial?: string | null;
220 | last_name?: string | null;
221 | linkedin_connections?: number | null;
222 | linkedin_id?: string | null;
223 | linkedin_url?: string | null;
224 | linkedin_username?: string | null;
225 | location_address_line_2?: string | boolean | null;
226 | location_continent?: Continent | null;
227 | location_country?: string | null;
228 | location_geo?: string | boolean | null;
229 | location_last_updated?: string | null;
230 | location_locality?: string | boolean | null;
231 | location_metro?: string | boolean | null;
232 | location_name?: string | boolean | null;
233 | location_names?: Array | boolean | null;
234 | location_postal_code?: string | boolean | null;
235 | location_region?: string | boolean | null;
236 | location_street_address?: string | boolean | null;
237 | middle_initial?: string | null;
238 | middle_name?: string | null;
239 | mobile_phone?: string | boolean | null;
240 | name_aliases?: Array | null;
241 | num_records?: number | null;
242 | num_sources?: number | null;
243 | personal_emails?: Array | boolean | null;
244 | phone_numbers?: Array | boolean | null;
245 | phones?: Array | null;
246 | possible_birth_dates?: Array | null;
247 | possible_emails?: Array | null;
248 | possible_location_names?: Array | null;
249 | possible_phones?: Array | null;
250 | possible_profiles?: Array | null;
251 | possible_street_addresses?: Array | null;
252 | profiles?: Array | null;
253 | recommended_personal_email?: string | boolean | null;
254 | regions?: Array | boolean | null;
255 | sex?: 'female' | 'male' | null;
256 | skills?: Array | null;
257 | street_addresses?: Array | boolean | null;
258 | summary?: string | null;
259 | twitter_url?: string | null;
260 | twitter_username?: string | null;
261 | version_status?: VersionStatus | null;
262 | work_email?: string | boolean | null;
263 | }
264 |
265 | interface NaicsResponse {
266 | industry_group?: string | null;
267 | naics_code?: string | null;
268 | naics_industry?: string | null;
269 | national_industry?: string | null;
270 | sector?: string | null;
271 | sub_sector?: string | null;
272 | }
273 |
274 | export interface SicResponse {
275 | industry_group?: string | null;
276 | industry_sector?: string | null;
277 | major_group?: string | null;
278 | sic_code?: string | null;
279 | }
280 |
281 | export interface CompanyResponse {
282 | affiliated_profiles?: Array | null;
283 | all_subsidiaries?: Array | null;
284 | alternative_domains?: Array | null;
285 | alternative_names?: Array | null;
286 | average_employee_tenure?: number | null;
287 | average_tenure_by_level?: {
288 | cxo?: number | null;
289 | director?: number | null;
290 | entry?: number | null;
291 | manager?: number | null;
292 | owner?: number | null;
293 | partner?: number | null;
294 | senior?: number | null;
295 | training?: number | null;
296 | unpaid?: number | null;
297 | vp?: number | null;
298 | } | null;
299 | average_tenure_by_role?: {
300 | advisory?: number | null;
301 | analyst?: number | null;
302 | creative?: number | null;
303 | education?: number | null;
304 | engineering?: number | null;
305 | finance?: number | null;
306 | fulfillment?: number | null;
307 | health?: number | null;
308 | hospitality?: number | null;
309 | human_resources?: number | null;
310 | legal?: number | null;
311 | manufacturing?: number | null;
312 | marketing?: number | null;
313 | operations?: number | null;
314 | partnerships?: number | null;
315 | product?: number | null;
316 | professional_service?: number | null;
317 | public_service?: number | null;
318 | research?: number | null;
319 | sales?: number | null;
320 | sales_engineering?: number | null;
321 | support?: number | null;
322 | trade?: number | null;
323 | unemployed?: number | null;
324 | } | null;
325 | dataset_version?: string | null;
326 | direct_subsidiaries?: Array | null;
327 | display_name?: string | null;
328 | employee_churn_rate: {
329 | '3_month'?: number | null;
330 | '6_month'?: number | null;
331 | '12_month'?: number | null;
332 | '24_month'?: number | null;
333 | } | null;
334 | employee_count?: number | null;
335 | employee_count_by_country?: object | null;
336 | employee_count_by_month?: object | null;
337 | employee_count_by_month_by_level?: object | null;
338 | employee_count_by_month_by_role?: object | null;
339 | employee_count_by_role?: {
340 | advisory?: number | null;
341 | analyst?: number | null;
342 | creative?: number | null;
343 | education?: number | null;
344 | engineering?: number | null;
345 | finance?: number | null;
346 | fulfillment?: number | null;
347 | health?: number | null;
348 | hospitality?: number | null;
349 | human_resources?: number | null;
350 | legal?: number | null;
351 | manufacturing?: number | null;
352 | marketing?: number | null;
353 | operations?: number | null;
354 | partnerships?: number | null;
355 | product?: number | null;
356 | professional_service?: number | null;
357 | public_service?: number | null;
358 | research?: number | null;
359 | sales?: number | null;
360 | sales_engineering?: number | null;
361 | support?: number | null;
362 | trade?: number | null;
363 | unemployed?: number | null;
364 | } | null;
365 | employee_growth_rate?: {
366 | '3_month'?: number | null;
367 | '6_month'?: number | null;
368 | '12_month'?: number | null;
369 | '24_month'?: number | null;
370 | } | null;
371 | employee_growth_rate_12_month_by_role?: {
372 | advisory?: number | null;
373 | analyst?: number | null;
374 | creative?: number | null;
375 | education?: number | null;
376 | engineering?: number | null;
377 | finance?: number | null;
378 | fulfillment?: number | null;
379 | health?: number | null;
380 | hospitality?: number | null;
381 | human_resources?: number | null;
382 | legal?: number | null;
383 | manufacturing?: number | null;
384 | marketing?: number | null;
385 | operations?: number | null;
386 | partnerships?: number | null;
387 | product?: number | null;
388 | professional_service?: number | null;
389 | public_service?: number | null;
390 | research?: number | null;
391 | sales?: number | null;
392 | sales_engineering?: number | null;
393 | support?: number | null;
394 | trade?: number | null;
395 | unemployed?: number | null;
396 | } | null;
397 | facebook_url?: string | null;
398 | founded?: number | null;
399 | funding_details?: Array<{
400 | funding_currency?: Currencies | null;
401 | funding_raised?: number | null;
402 | funding_round_date?: string | null;
403 | funding_type?: FundingRoundType | null;
404 | investing_companies?: Array | null;
405 | investing_individuals?: Array | null;
406 | }> | null;
407 | funding_stages?: Array | null;
408 | gics_sector?: string | null;
409 | gross_additions_by_month?: object | null;
410 | gross_departures_by_month?: object | null;
411 | headline?: string | null;
412 | id?: string | null;
413 | immediate_parent?: string | null;
414 | industry?: IndustryType | null;
415 | inferred_revenue?: InferredRevenue | null;
416 | last_funding_date?: string | null;
417 | latest_funding_stage?: string | null;
418 | likelihood?: number | null;
419 | linkedin_employee_count?: number | null;
420 | linkedin_follower_count?: number | null;
421 | linkedin_id?: string | null;
422 | linkedin_slug?: string | null;
423 | linkedin_url?: string | null;
424 | location?: LocationResponse | null;
425 | matched?: Array | null;
426 | mic_exchange?: MICCode | null;
427 | naics?: Array | null;
428 | name?: string | null;
429 | number_funding_rounds?: number | null;
430 | profiles?: Array | null;
431 | recent_exec_departures?: Array<{
432 | departed_date?: string | null;
433 | job_title?: string | null;
434 | job_title_class?: JobTitleClass | null;
435 | job_title_levels?: Array | null;
436 | job_title_role?: JobTitleRole | null;
437 | job_title_sub_role?: JobTitleSubRole | null;
438 | new_company_id?: string | null;
439 | new_company_job_title?: string | null;
440 | new_company_job_title_class?: JobTitleClass | null;
441 | new_company_job_title_levels?: Array | null;
442 | new_company_job_title_role?: JobTitleRole | null;
443 | new_company_job_title_sub_role?: JobTitleSubRole | null;
444 | pdl_id?: string | null;
445 | }> | null;
446 | recent_exec_hires?: Array<{
447 | job_title?: string | null;
448 | job_title_class?: JobTitleClass | null;
449 | job_title_levels?: Array | null;
450 | job_title_role?: JobTitleRole | null;
451 | job_title_sub_role?: JobTitleSubRole | null;
452 | joined_date?: string | null;
453 | pdl_id?: string | null;
454 | previous_company_id?: string | null;
455 | previous_company_job_title?: string | null;
456 | previous_company_job_title_class?: JobTitleClass | null;
457 | previous_company_job_title_levels?: Array | null;
458 | previous_company_job_title_role?: JobTitleRole | null;
459 | previous_company_job_title_sub_role?: JobTitleSubRole | null;
460 | }> | null;
461 | sic?: Array | null;
462 | size?: CompanySize | null;
463 | summary?: string | null;
464 | tags?: Array | null;
465 | ticker?: string | null;
466 | top_next_employers_by_role?: {
467 | advisory?: number | null;
468 | all?: object | null;
469 | analyst?: number | null;
470 | creative?: number | null;
471 | education?: number | null;
472 | engineering?: number | null;
473 | finance?: number | null;
474 | fulfillment?: number | null;
475 | health?: number | null;
476 | hospitality?: number | null;
477 | human_resources?: number | null;
478 | legal?: number | null;
479 | manufacturing?: number | null;
480 | marketing?: number | null;
481 | operations?: number | null;
482 | partnerships?: number | null;
483 | product?: number | null;
484 | professional_service?: number | null;
485 | public_service?: number | null;
486 | research?: number | null;
487 | sales?: number | null;
488 | sales_engineering?: number | null;
489 | support?: number | null;
490 | trade?: number | null;
491 | unemployed?: number | null;
492 | } | null;
493 | top_previous_employers_by_role?: {
494 | advisory?: number | null;
495 | all?: object | null;
496 | analyst?: number | null;
497 | creative?: number | null;
498 | education?: number | null;
499 | engineering?: number | null;
500 | finance?: number | null;
501 | fulfillment?: number | null;
502 | health?: number | null;
503 | hospitality?: number | null;
504 | human_resources?: number | null;
505 | legal?: number | null;
506 | manufacturing?: number | null;
507 | marketing?: number | null;
508 | operations?: number | null;
509 | partnerships?: number | null;
510 | product?: number | null;
511 | professional_service?: number | null;
512 | public_service?: number | null;
513 | research?: number | null;
514 | sales?: number | null;
515 | sales_engineering?: number | null;
516 | support?: number | null;
517 | trade?: number | null;
518 | unemployed?: number | null;
519 | } | null;
520 | top_us_employee_metros: object | null;
521 | total_funding_raised?: number | null;
522 | twitter_url?: string | null;
523 | type?: CompanyType | null;
524 | ultimate_parent?: string | null;
525 | ultimate_parent_mic_exchange?: MICCode | null;
526 | ultimate_parent_ticker?: string | null;
527 | website?: string | null;
528 | }
529 |
530 | export interface ErrorResponse {
531 | message: string | null;
532 | status?: number | null;
533 | }
534 |
--------------------------------------------------------------------------------
/src/types/enrichment-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse } from './api-types.js';
2 | import { CompanyResponse, PersonResponse } from './common-types.js';
3 | import { RequireAtLeastOne } from './utility-types.js';
4 |
5 | export type EnrichmentType = 'company' | 'person';
6 |
7 | export interface EnrichmentAdditionalParams {
8 | include_if_matched?: boolean;
9 | min_likelihood?: number;
10 | pretty?: boolean;
11 | required?: string;
12 | sandbox?: boolean;
13 | size?: number;
14 | titlecase?: boolean;
15 | }
16 |
17 | /* ---------------------------------------------------------- */
18 | /* ------------------------- Person ------------------------- */
19 | /* ---------------------------------------------------------- */
20 |
21 | export type PersonEnrichmentParams = EnrichmentAdditionalParams & Partial<{
22 | birth_date: Array | string;
23 | company: Array | string;
24 | country: string;
25 | data_include: string;
26 | email: Array | string;
27 | email_hash: Array | string;
28 | first_name: Array | string;
29 | last_name: Array | string;
30 | lid: number;
31 | locality: string;
32 | location: Array | string;
33 | middle_name: Array | string;
34 | name: Array | string;
35 | pdl_id: string;
36 | phone: Array | string;
37 | postal_code: string;
38 | profile: Array | string;
39 | region: string;
40 | school: Array | string;
41 | street_address: string;
42 | }>;
43 |
44 | export interface PersonEnrichmentResponse extends BaseResponse {
45 | data: PersonResponse;
46 | likelihood: number;
47 | matched?: Array;
48 | }
49 |
50 | export type PersonEnrichmentPreviewParams = PersonEnrichmentParams;
51 |
52 | type PersonPreviewResponseVisibleKeys = 'id' | 'full_name' | 'sex' | 'linkedin_url' | 'industry' | 'job_title' | 'job_title_class' | 'job_title_role' | 'job_title_sub_role' | 'job_title_levels' | 'job_company_name' | 'job_company_website' | 'location_name';
53 |
54 | type PersonPreviewResponseType = {
55 | [K in keyof PersonResponse]: K extends PersonPreviewResponseVisibleKeys ? PersonResponse[K] : boolean;
56 | };
57 |
58 | export interface PersonPreviewResponse extends PersonPreviewResponseType {}
59 |
60 | export interface PersonEnrichmentPreviewResponse extends BaseResponse {
61 | data: PersonPreviewResponse;
62 | likelihood: number;
63 | matched?: Array;
64 | }
65 |
66 | /* ---------------------------------------------------------- */
67 | /* ------------------------- Company ------------------------ */
68 | /* ---------------------------------------------------------- */
69 |
70 | export interface CompanyEnrichmentRequiredParams {
71 | name: string;
72 | pdl_id: string;
73 | profile: string;
74 | ticker: string;
75 | website: string;
76 | }
77 |
78 | // eslint-disable-next-line max-len
79 | export type CompanyEnrichmentParams = RequireAtLeastOne & EnrichmentAdditionalParams & {
80 | country?: string;
81 | locality?: string;
82 | location?: string;
83 | postal_code?: string;
84 | region?: string;
85 | street_address?: string;
86 | };
87 |
88 | export interface CompanyEnrichmentResponse extends BaseResponse, CompanyResponse {}
89 |
--------------------------------------------------------------------------------
/src/types/error-types.ts:
--------------------------------------------------------------------------------
1 | import { RateLimit } from './api-types.js';
2 |
3 | export type ErrorEndpoint = 'enrichment' | 'autocomplete' | 'search' | 'identify' | 'bulk' | 'cleaner' | 'retrieve' | 'jobTitle' | 'ip';
4 |
5 | export type PdlError = {
6 | message: string;
7 | rateLimit?: RateLimit;
8 | status: number;
9 | };
10 |
--------------------------------------------------------------------------------
/src/types/identify-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse } from './api-types.js';
2 | import { PersonResponse } from './common-types.js';
3 | import { RequireAtLeastOne } from './utility-types.js';
4 |
5 | export type IdentifyRequiredParams = RequireAtLeastOne<{
6 | company: string;
7 | email: string;
8 | email_hash: string;
9 | first_name: string;
10 | last_name: string;
11 | lid: number;
12 | locality: string;
13 | location: string;
14 | name: string;
15 | phone: string;
16 | postal_code: string;
17 | profile: string;
18 | region: string;
19 | school: string;
20 | street_address: string;
21 | }>;
22 |
23 | export type IdentifyParams = IdentifyRequiredParams & Partial<{
24 | birth_date: string;
25 | country: string;
26 | data_include: string;
27 | include_if_matched: boolean;
28 | middle_name: string;
29 | pretty: boolean;
30 | required: string;
31 | sandbox: boolean;
32 | titlecase: boolean;
33 | }>;
34 |
35 | export interface IdentifyResponse extends BaseResponse {
36 | matches: Array<{
37 | data: PersonResponse;
38 | match_score: number;
39 | matched_on: Array;
40 | }>;
41 | }
42 |
--------------------------------------------------------------------------------
/src/types/ip-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse } from './api-types.js';
2 | import type { CompanySize, IndustryType, InferredRevenue, JobTitleClass, JobTitleLevel, JobTitleRole, JobTitleSubRole } from './canonical-types.js';
3 |
4 | export interface IPParams {
5 | ip: string;
6 | min_confidence?: 'very high' | 'high' | 'moderate' | 'low' | 'very low';
7 | pretty?: boolean;
8 | return_if_unmatched?: boolean;
9 | return_ip_location?: boolean;
10 | return_ip_metadata?: boolean;
11 | return_person?: boolean;
12 | titlecase?: boolean;
13 | }
14 |
15 | export interface IPResponse extends BaseResponse {
16 | data?: {
17 | company?: {
18 | confidence?: 'very high' | 'high' | 'moderate' | 'low' | 'very low';
19 | display_name?: string | null;
20 | employee_count?: number | null;
21 | id?: string | null;
22 | industry?: IndustryType | null;
23 | inferred_revenue?: InferredRevenue | null;
24 | location?: {
25 | address_line_2?: string | null;
26 | continent?: string | null;
27 | country?: string | null;
28 | geo?: string | null;
29 | locality?: string | null;
30 | metro?: string | null;
31 | name?: string | null;
32 | postal_code?: string | null;
33 | region?: string | null;
34 | street_address?: string;
35 | } | null;
36 | name?: string | null;
37 | size?: CompanySize | null;
38 | tags?: Array | null;
39 | website?: string | null;
40 | } | null;
41 | dataset_version?: string | null;
42 | ip?: {
43 | address?: string | null;
44 | location?: {
45 | continent?: string | null;
46 | country?: string | null;
47 | geo?: string | null;
48 | locality?: string | null;
49 | metro?: string | null;
50 | name?: string | null;
51 | postal_code?: string | null;
52 | region?: string | null;
53 | timezone?: string | null;
54 | } | null;
55 | metadata?: {
56 | asn_domain?: string | null;
57 | hosting?: boolean | null;
58 | mobile?: boolean | null;
59 | proxy?: boolean | null;
60 | relay?: boolean | null;
61 | service?: string | null;
62 | tor?: boolean | null;
63 | version?: 4 | 6 | null;
64 | vpn?: boolean | null;
65 | };
66 | } | null;
67 | person?: {
68 | confidence?: 'very high' | 'high' | 'moderate' | 'low' | 'very low';
69 | job_title_class?: JobTitleClass | null;
70 | job_title_levels?: Array | null;
71 | job_title_role?: JobTitleRole | null;
72 | job_title_sub_role?: JobTitleSubRole | null;
73 | } | null;
74 | } | null;
75 | }
76 |
--------------------------------------------------------------------------------
/src/types/jobTitle-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse } from './api-types.js';
2 |
3 | export interface JobTitleParams {
4 | jobTitle: string;
5 | pretty?: boolean;
6 | titlecase?: boolean;
7 | }
8 |
9 | export interface JobTitleResponse extends BaseResponse {
10 | data?: {
11 | cleaned_job_title?: string | null;
12 | relevant_skills?: Array | null;
13 | similar_job_titles?: Array | null;
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/src/types/retrieve-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse } from './api-types.js';
2 | import { PersonResponse } from './common-types.js';
3 |
4 | export type RetrieveFilter = 'job_change' | 'education' | 'location' | 'personal_emails' | 'phone_number' | 'social_profile' | 'work_email';
5 |
6 | export type RetrieveMetaParams = {
7 | filter_updated?: RetrieveFilter | RetrieveFilter[];
8 | pretty?: boolean;
9 | titlecase?: boolean;
10 | };
11 |
12 | export type ApiRetrieveMetaParams = {
13 | filter_updated?: string;
14 | pretty?: boolean;
15 | titlecase?: boolean;
16 | };
17 |
18 | export type RetrieveParams = {
19 | id: string;
20 | } & RetrieveMetaParams;
21 |
22 | export type ApiRetrieveParams = {
23 | id: string;
24 | } & ApiRetrieveMetaParams;
25 |
26 | export interface RetrieveResponse extends BaseResponse {
27 | billed: boolean;
28 | data: PersonResponse;
29 | }
30 |
--------------------------------------------------------------------------------
/src/types/search-types.ts:
--------------------------------------------------------------------------------
1 | import { BaseResponse } from './api-types.js';
2 | import { CompanyResponse, PersonResponse } from './common-types.js';
3 |
4 | export interface BaseSearchParams {
5 | data_include?: string;
6 | dataset?: string;
7 | from?: number;
8 | pretty?: boolean;
9 | sandbox?: boolean;
10 | scroll_token?: string;
11 | searchQuery?: string | object;
12 | size?: number;
13 | titlecase?: boolean;
14 | }
15 |
16 | export interface BaseSearchResponse extends BaseResponse {
17 | data: Array;
18 | scroll_token: string;
19 | total: number;
20 | }
21 |
22 | export type SearchType = 'sql' | 'elastic';
23 |
24 | /* ---------------------------------------------------------- */
25 | /* ------------------------- Person ------------------------- */
26 | /* ---------------------------------------------------------- */
27 |
28 | export interface PersonSearchParams extends BaseSearchParams {
29 | }
30 |
31 | export interface PersonSearchResponse extends BaseSearchResponse {}
32 |
33 | /* ---------------------------------------------------------- */
34 | /* ------------------------- Company ------------------------ */
35 | /* ---------------------------------------------------------- */
36 |
37 | export interface CompanySearchParams extends BaseSearchParams {}
38 |
39 | export interface CompanySearchResponse extends BaseSearchResponse {}
40 |
--------------------------------------------------------------------------------
/src/types/utility-types.ts:
--------------------------------------------------------------------------------
1 | // Marks all the properties of a type as optional except for one
2 | // See https://docs.microsoft.com/en-us/javascript/api/@azure/keyvault-certificates/requireatleastone?view=azure-node-latest
3 | export type RequireAtLeastOne = {
4 | [K in keyof T]-?: Required> & Partial>>;
5 | }[keyof T];
6 |
--------------------------------------------------------------------------------
/src/utils/api-utils.ts:
--------------------------------------------------------------------------------
1 | import { AxiosResponse } from 'axios';
2 |
3 | import { RateLimit } from '../types/api-types.js';
4 |
5 | // eslint-disable-next-line import/prefer-default-export
6 | export const parseRateLimitingResponse = (response: AxiosResponse) => {
7 | const rateLimit = {
8 | rateLimitRemaining: response.headers['x-ratelimit-remaining'] ? JSON.parse(response.headers['x-ratelimit-remaining'].replace(/'/g, '"')) : undefined,
9 | rateLimitReset: response.headers['x-ratelimit-reset'] || undefined,
10 | rateLimitLimit: response.headers['x-ratelimit-limit'] ? JSON.parse(response.headers['x-ratelimit-limit'].replace(/'/g, '"')) : undefined,
11 | totalLimitOveragesRemaining: response.headers['x-totallimit-overages-remaining'] ? Number(response.headers['x-totallimit-overages-remaining']) : undefined,
12 | totalLimitPurchasedRemaining: response.headers['x-totallimit-purchased-remaining'] ? Number(response.headers['x-totallimit-purchased-remaining']) : undefined,
13 | totalLimitRemaining: response.headers['x-totallimit-remaining'] ? Number(response.headers['x-totallimit-remaining']) : undefined,
14 | callCreditsType: response.headers['x-call-credits-type'] || undefined,
15 | callCreditsSpent: response.headers['x-call-credits-spent'] ? Number(response.headers['x-call-credits-spent']) : undefined,
16 | lifetimeUsed: response.headers['x-lifetime-used'] ? Number(response.headers['x-lifetime-used']) : undefined,
17 | } as RateLimit;
18 |
19 | if (Array.isArray(response.data)) {
20 | return {
21 | items: response.data,
22 | rateLimit,
23 | };
24 | }
25 |
26 | return {
27 | ...response.data,
28 | rateLimit,
29 | };
30 | };
31 |
--------------------------------------------------------------------------------
/tests/index.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 |
3 | import { expect } from 'chai';
4 | import dotenv from 'dotenv';
5 |
6 | // eslint-disable-next-line import/extensions
7 | import PDLJS from '../dist/index.m.js';
8 |
9 | dotenv.config({ path: './.env.local' });
10 |
11 | const PDLJSClient = new PDLJS({ apiKey: process.env.PDL_API_KEY });
12 |
13 | const email = 'varun@peopledatalabs.com';
14 |
15 | const records = {
16 | requests: [
17 | {
18 | params: {
19 | profile: ['linkedin.com/in/seanthorne'],
20 | },
21 | },
22 | {
23 | params: {
24 | profile: ['linkedin.com/in/randrewn'],
25 | },
26 | },
27 | ],
28 | };
29 |
30 | const personSQL = "SELECT * FROM person WHERE location_country='mexico' AND job_title_role='health'AND phone_numbers IS NOT NULL;";
31 |
32 | const personElastic = {
33 | query: {
34 | bool: {
35 | must: [
36 | { term: { location_country: 'mexico' } },
37 | { term: { job_title_role: 'health' } },
38 | { exists: { field: 'phone_numbers' } },
39 | ],
40 | },
41 | },
42 | };
43 |
44 | const personID = 'qEnOZ5Oh0poWnQ1luFBfVw_0000';
45 |
46 | const bulkRecords = {
47 | requests: [
48 | { id: 'qEnOZ5Oh0poWnQ1luFBfVw_0000' },
49 | { id: 'PzFD15NINdBWNULBBkwlig_0000' },
50 | ],
51 | };
52 |
53 | const website = 'peopledatalabs.com';
54 |
55 | const companySQL = "SELECT * FROM company WHERE tags='big data' AND industry='financial services' AND location.country='united states';";
56 |
57 | const companyElastic = {
58 | query: {
59 | bool: {
60 | must: [
61 | { term: { website: 'peopledatalabs.com' } },
62 | ],
63 | },
64 | },
65 | };
66 |
67 | const autocomplete = {
68 | field: 'company',
69 | text: 'facebook',
70 | size: 10,
71 | };
72 |
73 | const company = { name: 'peopledatalabs' };
74 |
75 | const companyRecords = {
76 | requests: [
77 | {
78 | params: {
79 | profile: ['linkedin.com/company/peopledatalabs'],
80 | },
81 | },
82 | {
83 | params: {
84 | profile: ['linkedin.com/company/apple'],
85 | },
86 | },
87 | ],
88 | };
89 |
90 | const location = { location: '455 Market Street, San Francisco, California 94105, US' };
91 |
92 | const school = { name: 'university of oregon' };
93 |
94 | const jobTitle = { jobTitle: 'software engineer' };
95 |
96 | const ip = { ip: '72.212.42.228' };
97 |
98 | describe('Person Enrichment', () => {
99 | it(`Should Return Person Record for ${email}`, async () => {
100 | try {
101 | const response = await PDLJSClient.person.enrichment({ email });
102 |
103 | expect(response.status).to.equal(200);
104 | expect(response).to.be.a('object');
105 | expect(response.data.job_title_class).to.be.a('string');
106 | } catch (error) {
107 | expect(error).to.be.null();
108 | }
109 | });
110 |
111 | it('Should Error for Person Enrichment', async () => {
112 | try {
113 | const response = await PDLJSClient.person.enrichment();
114 |
115 | expect(response).to.be.null();
116 | } catch (error) {
117 | expect(error).to.be.a('object');
118 | }
119 | });
120 | });
121 |
122 | describe('Person Preview Enrichment', () => {
123 | it(`Should Return Person Preview Record for ${email}`, async () => {
124 | try {
125 | const response = await PDLJSClient.person.enrichmentPreview({ email });
126 |
127 | expect(response.status).to.equal(200);
128 | expect(response).to.be.a('object');
129 | } catch (error) {
130 | expect(error).to.be.null();
131 | }
132 | });
133 |
134 | it('Should Error for Person Preview Enrichment', async () => {
135 | try {
136 | const response = await PDLJSClient.person.enrichmentPreview();
137 |
138 | expect(response).to.be.null();
139 | } catch (error) {
140 | expect(error).to.be.a('object');
141 | }
142 | });
143 | });
144 |
145 | describe('Person Bulk Enrichment', () => {
146 | it(`Should Return Person Records for ${JSON.stringify(records)}`, async () => {
147 | try {
148 | const response = await PDLJSClient.person.bulk.enrichment(records);
149 |
150 | expect(response.items.length).to.equal(2);
151 | expect(response.items).to.be.a('array');
152 | } catch (error) {
153 | expect(error).to.be.null();
154 | }
155 | });
156 |
157 | it('Should Error for Person Bulk Enrichment', async () => {
158 | try {
159 | const response = await PDLJSClient.person.bulk.enrichment();
160 |
161 | expect(response).to.be.null();
162 | } catch (error) {
163 | expect(error).to.be.a('object');
164 | }
165 | });
166 | });
167 |
168 | describe('Person Identify', () => {
169 | it(`Should Return Person Record for ${email}`, async () => {
170 | try {
171 | const response = await PDLJSClient.person.identify({ email });
172 |
173 | expect(response.status).to.equal(200);
174 | expect(response).to.be.a('object');
175 | } catch (error) {
176 | expect(error).to.be.null();
177 | }
178 | });
179 |
180 | it('Should Error for Person Identify', async () => {
181 | try {
182 | const response = await PDLJSClient.person.identify();
183 |
184 | expect(response).to.be.null();
185 | } catch (error) {
186 | expect(error).to.be.a('object');
187 | }
188 | });
189 | });
190 |
191 | describe('Person Search', () => {
192 | it(`Should Return Person Records for ${personSQL}`, async () => {
193 | try {
194 | const response = await PDLJSClient.person.search.sql({ searchQuery: personSQL, size: 10 });
195 |
196 | expect(response.status).to.equal(200);
197 | expect(response).to.be.a('object');
198 | } catch (error) {
199 | expect(error).to.be.null();
200 | }
201 | });
202 |
203 | it('Should Error for Person Search (sql)', async () => {
204 | try {
205 | const response = await PDLJSClient.person.search.sql();
206 |
207 | expect(response).to.be.null();
208 | } catch (error) {
209 | expect(error).to.be.a('object');
210 | }
211 | });
212 |
213 | it(`Should Return Person Records for ${JSON.stringify(personElastic)}`, async () => {
214 | try {
215 | const response = await PDLJSClient.person.search.elastic({ searchQuery: personElastic, size: 10 });
216 |
217 | expect(response.status).to.equal(200);
218 | expect(response).to.be.a('object');
219 | } catch (error) {
220 | expect(error).to.be.null();
221 | }
222 | });
223 |
224 | it('Should Error for Person Search (elastic)', async () => {
225 | try {
226 | const response = await PDLJSClient.person.search.elastic();
227 |
228 | expect(response).to.be.null();
229 | } catch (error) {
230 | expect(error).to.be.a('object');
231 | }
232 | });
233 | });
234 |
235 | describe('Person Retrieve', () => {
236 | it(`Should Return Person Record for ${personID}`, async () => {
237 | try {
238 | const response = await PDLJSClient.person.retrieve({ id: personID });
239 |
240 | expect(response.status).to.equal(200);
241 | expect(response).to.be.a('object');
242 | } catch (error) {
243 | expect(error).to.be.null();
244 | }
245 | });
246 |
247 | it('Should Error for Person Retrieve', async () => {
248 | try {
249 | const response = await PDLJSClient.person.retrieve();
250 |
251 | expect(response).to.be.null();
252 | } catch (error) {
253 | expect(error).to.be.a('object');
254 | }
255 | });
256 | });
257 |
258 | describe('Bulk Person Retrieve', () => {
259 | it(`Should Return Person Records for ${JSON.stringify(bulkRecords)}`, async () => {
260 | try {
261 | const response = await PDLJSClient.person.bulk.retrieve(bulkRecords);
262 |
263 | expect(response).to.be.a('object');
264 | } catch (error) {
265 | expect(error).to.be.null();
266 | }
267 | });
268 |
269 | it('Should Error for Bulk Person Retrieve', async () => {
270 | try {
271 | const response = await PDLJSClient.person.bulk.retrieve();
272 |
273 | expect(response).to.be.null();
274 | } catch (error) {
275 | expect(error).to.be.a('object');
276 | }
277 | });
278 | });
279 |
280 | describe('Company Enrichment', () => {
281 | it(`Should Return Company Record for ${website}`, async () => {
282 | try {
283 | const response = await PDLJSClient.company.enrichment({ website });
284 |
285 | expect(response.status).to.equal(200);
286 | expect(response).to.be.a('object');
287 | } catch (error) {
288 | expect(error).to.be.null();
289 | }
290 | });
291 |
292 | it('Should Return Multiple Company Records for MRI', async () => {
293 | try {
294 | const response = await PDLJSClient.company.enrichment({ name: 'MRI', size: 2 });
295 |
296 | expect(response.status).to.equal(200);
297 | expect(response).to.be.a('object');
298 | } catch (error) {
299 | expect(error).to.be.null();
300 | }
301 | });
302 |
303 | it('Should Error for Company Enrichment', async () => {
304 | try {
305 | const response = await PDLJSClient.company.enrichment();
306 |
307 | expect(response).to.be.null();
308 | } catch (error) {
309 | expect(error).to.be.a('object');
310 | }
311 | });
312 | });
313 |
314 | describe('Company Bulk Enrichment', () => {
315 | it(`Should Return Company Records for ${JSON.stringify(companyRecords)}`, async () => {
316 | try {
317 | const response = await PDLJSClient.company.bulk.enrichment(companyRecords);
318 |
319 | expect(response.items.length).to.equal(2);
320 | expect(response.items).to.be.a('array');
321 | } catch (error) {
322 | expect(error).to.be.null();
323 | }
324 | });
325 |
326 | it('Should Error for Company Bulk Enrichment', async () => {
327 | try {
328 | const response = await PDLJSClient.company.bulk.enrichment();
329 |
330 | expect(response).to.be.null();
331 | } catch (error) {
332 | expect(error).to.be.a('object');
333 | }
334 | });
335 | });
336 |
337 | describe('Company Search', () => {
338 | it(`Should Return Company Records for ${companySQL}`, async () => {
339 | try {
340 | const response = await PDLJSClient.company.search.sql({ searchQuery: companySQL, size: 10 });
341 |
342 | expect(response.status).to.equal(200);
343 | expect(response).to.be.a('object');
344 | } catch (error) {
345 | expect(error).to.be.null();
346 | }
347 | });
348 |
349 | it('Should Error for Company Search (sql)', async () => {
350 | try {
351 | const response = await PDLJSClient.company.search.sql();
352 |
353 | expect(response).to.be.null();
354 | } catch (error) {
355 | expect(error).to.be.a('object');
356 | }
357 | });
358 |
359 | it(`Should Return Company Records for ${JSON.stringify(companyElastic)}`, async () => {
360 | try {
361 | const response = await PDLJSClient.company.search.elastic({ searchQuery: companyElastic, size: 10 });
362 |
363 | expect(response.status).to.equal(200);
364 | expect(response).to.be.a('object');
365 | } catch (error) {
366 | expect(error).to.be.null();
367 | }
368 | });
369 |
370 | it('Should Error for Company Search (elastic)', async () => {
371 | try {
372 | const response = await PDLJSClient.company.search.elastic();
373 |
374 | expect(response).to.be.null();
375 | } catch (error) {
376 | expect(error).to.be.a('object');
377 | }
378 | });
379 | });
380 |
381 | describe('Autocomplete', () => {
382 | it(`Should Return Autocomplete Records for ${JSON.stringify(autocomplete)}`, async () => {
383 | try {
384 | const response = await PDLJSClient.autocomplete(autocomplete);
385 |
386 | expect(response.status).to.equal(200);
387 | expect(response).to.be.a('object');
388 | } catch (error) {
389 | expect(error).to.be.null();
390 | }
391 | });
392 |
393 | it('Should Return Autocomplete for `class` field', async () => {
394 | const autocompleteClassParams = {
395 | field: 'class',
396 | text: 'sales',
397 | };
398 |
399 | try {
400 | const response = await PDLJSClient.autocomplete(autocompleteClassParams);
401 |
402 | expect(response.status).to.equal(200);
403 | expect(response).to.be.a('object');
404 | } catch (error) {
405 | expect(error).to.be.null();
406 | }
407 | });
408 |
409 | it('Should Return Autocomplete for `all_location` field', async () => {
410 | const autocompleteClassParams = {
411 | field: 'all_location',
412 | text: 'miami',
413 | };
414 |
415 | try {
416 | const response = await PDLJSClient.autocomplete(autocompleteClassParams);
417 |
418 | expect(response.status).to.equal(200);
419 | expect(response).to.be.a('object');
420 | } catch (error) {
421 | expect(error).to.be.null();
422 | }
423 | });
424 |
425 | it('Should Error for Autocomplete', async () => {
426 | try {
427 | const response = await PDLJSClient.autocomplete();
428 |
429 | expect(response).to.be.null();
430 | } catch (error) {
431 | expect(error).to.be.a('object');
432 | }
433 | });
434 | });
435 |
436 | describe('Cleaner APIs', () => {
437 | it(`Should Return Company Cleaner Records for ${JSON.stringify(company)}`, async () => {
438 | try {
439 | const response = await PDLJSClient.company.cleaner(company);
440 |
441 | expect(response.status).to.equal(200);
442 | expect(response).to.be.a('object');
443 | } catch (error) {
444 | expect(error).to.be.null();
445 | }
446 | });
447 |
448 | it('Should Error for Company Cleaner', async () => {
449 | try {
450 | const response = await PDLJSClient.company.cleaner();
451 |
452 | expect(response).to.be.null();
453 | } catch (error) {
454 | expect(error).to.be.a('object');
455 | }
456 | });
457 |
458 | it(`Should Return Location Cleaner Records for ${JSON.stringify(location)}`, async () => {
459 | try {
460 | const response = await PDLJSClient.location.cleaner(location);
461 |
462 | expect(response.status).to.equal(200);
463 | expect(response).to.be.a('object');
464 | } catch (error) {
465 | expect(error).to.be.null();
466 | }
467 | });
468 |
469 | it('Should Error for Location Cleaner', async () => {
470 | try {
471 | const response = await PDLJSClient.location.cleaner();
472 |
473 | expect(response).to.be.null();
474 | } catch (error) {
475 | expect(error).to.be.a('object');
476 | }
477 | });
478 |
479 | it(`Should Return School Cleaner Records for ${JSON.stringify(school)}`, async () => {
480 | try {
481 | const response = await PDLJSClient.school.cleaner(school);
482 |
483 | expect(response.status).to.equal(200);
484 | expect(response).to.be.a('object');
485 | } catch (error) {
486 | expect(error).to.be.null();
487 | }
488 | });
489 |
490 | it('Should Error for School Cleaner', async () => {
491 | try {
492 | const response = await PDLJSClient.school.cleaner();
493 |
494 | expect(response).to.be.null();
495 | } catch (error) {
496 | expect(error).to.be.a('object');
497 | }
498 | });
499 | });
500 |
501 | describe('Job Title API', () => {
502 | it(`Should Return Job Title Records for ${JSON.stringify(jobTitle)}`, async () => {
503 | try {
504 | const response = await PDLJSClient.jobTitle(jobTitle);
505 |
506 | expect(response.status).to.equal(200);
507 | expect(response).to.be.a('object');
508 | } catch (error) {
509 | expect(error).to.be.null();
510 | }
511 | });
512 |
513 | it('Should Error for Job Title', async () => {
514 | try {
515 | const response = await PDLJSClient.jobTitle();
516 |
517 | expect(response).to.be.null();
518 | } catch (error) {
519 | expect(error).to.be.a('object');
520 | }
521 | });
522 | });
523 |
524 | describe('IP Enrichment API', () => {
525 | it(`Should Return IP Records for ${JSON.stringify(ip)}`, async () => {
526 | try {
527 | const response = await PDLJSClient.ip(ip);
528 |
529 | expect(response.status).to.equal(200);
530 | expect(response).to.be.a('object');
531 | } catch (error) {
532 | expect(error).to.be.null();
533 | }
534 | });
535 |
536 | it(`Should Return IP Records for ${JSON.stringify(ip)} with very high confidence`, async () => {
537 | try {
538 | const object = {
539 | ...ip,
540 | min_confidence: 'very high',
541 | };
542 |
543 | const response = await PDLJSClient.ip(object);
544 |
545 | expect(response.status).to.equal(200);
546 | expect(response).to.be.a('object');
547 | } catch (error) {
548 | expect(error).to.be.null();
549 | }
550 | });
551 |
552 | it('Should Error for IP Enrichment', async () => {
553 | try {
554 | const response = await PDLJSClient.ip();
555 |
556 | expect(response).to.be.null();
557 | } catch (error) {
558 | expect(error).to.be.a('object');
559 | }
560 | });
561 | });
562 |
563 | describe('Sandbox APIs', () => {
564 | it('Should Return Sandbox Person Record for { email: \'reneewillis74@aol.com\' }', async () => {
565 | try {
566 | const response = await PDLJSClient.person.enrichment({ email: 'reneewillis74@aol.com', sandbox: true });
567 |
568 | expect(response.status).to.equal(200);
569 | expect(response).to.be.a('object');
570 | } catch (error) {
571 | expect(error).to.be.null();
572 | }
573 | });
574 |
575 | it('Should Error for Sandbox Person Enrichment', async () => {
576 | try {
577 | const response = await PDLJSClient.person.enrichment();
578 |
579 | expect(response).to.be.null();
580 | } catch (error) {
581 | expect(error).to.be.a('object');
582 | }
583 | });
584 |
585 | it('Should Return Sandbox Person Records for "SELECT * FROM person WHERE location_country=\'united states\';"', async () => {
586 | try {
587 | const response = await PDLJSClient.person.search.sql({ searchQuery: 'SELECT * FROM person WHERE location_country=\'united states\';', size: 10, sandbox: true });
588 |
589 | expect(response.status).to.equal(200);
590 | expect(response).to.be.a('object');
591 | } catch (error) {
592 | expect(error).to.be.null();
593 | }
594 | });
595 |
596 | it('Should Error for Sandbox Person Search (sql)', async () => {
597 | try {
598 | const response = await PDLJSClient.person.search.sql({ sandbox: true });
599 |
600 | expect(response).to.be.null();
601 | } catch (error) {
602 | expect(error).to.be.a('object');
603 | }
604 | });
605 |
606 | it('Should Return Sandbox Person Records for { query: { bool: { must: [{term: {location_country: "united states"}}] } } }', async () => {
607 | try {
608 | const response = await PDLJSClient.person.search.elastic({ searchQuery: { query: { bool: { must: [{ term: { location_country: 'united states' } }] } } }, size: 10, sandbox: true });
609 |
610 | expect(response.status).to.equal(200);
611 | expect(response).to.be.a('object');
612 | } catch (error) {
613 | expect(error).to.be.null();
614 | }
615 | });
616 |
617 | it('Should Error for Sandbox Person Search (elastic)', async () => {
618 | try {
619 | const response = await PDLJSClient.person.search.elastic({ sandbox: true });
620 |
621 | expect(response).to.be.null();
622 | } catch (error) {
623 | expect(error).to.be.a('object');
624 | }
625 | });
626 |
627 | it('Should Return Sandbox Identify Person Records for { email: \'reneewillis74@aol.com\' }', async () => {
628 | try {
629 | const response = await PDLJSClient.person.identify({ email: 'reneewillis74@aol.com', sandbox: true });
630 |
631 | expect(response.status).to.equal(200);
632 | expect(response).to.be.a('object');
633 | } catch (error) {
634 | expect(error).to.be.null();
635 | }
636 | });
637 |
638 | it('Should Error for Sandbox Person Identify', async () => {
639 | try {
640 | const response = await PDLJSClient.person.identify({ sandbox: true });
641 |
642 | expect(response).to.be.null();
643 | } catch (error) {
644 | expect(error).to.be.a('object');
645 | }
646 | });
647 | });
648 |
--------------------------------------------------------------------------------
/tsconfig.eslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["src/**/*", "tests", "example", ".eslintrc.cjs"],
4 | "exclude": ["node_modules", "dist",]
5 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "composite": false,
6 | "declaration": true,
7 | "declarationMap": true,
8 | "esModuleInterop": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "inlineSources": false,
11 | "isolatedModules": true,
12 | "moduleResolution": "Node16",
13 | "noUnusedLocals": false,
14 | "noUnusedParameters": false,
15 | "preserveWatchOutput": true,
16 | "skipLibCheck": true,
17 | "strict": true,
18 | "lib": ["dom", "ES2017"],
19 | "module": "Node16",
20 | "target": "ESNext"
21 | },
22 | "include": ["src/**/*"],
23 | "exclude": ["dist", "node_modules", "tests", "example"]
24 | }
25 |
--------------------------------------------------------------------------------