lighthouse-private-markets-sdk
v3.0.2
Published
Official Lighthouse SDK — thin REST client for the Lighthouse API (CRM, Discovery, Reports, Documents).
Downloads
1,164
Maintainers
Readme
Lighthouse JS SDK
Official JavaScript/TypeScript client for the Lighthouse REST API. Wraps the CRM, Discovery, Reports, and Documents endpoints behind a single typed Lighthouse class. Zero runtime dependencies — uses the global fetch.
Installation
npm i lighthouse-private-markets-sdk
# or
yarn add lighthouse-private-markets-sdkWorks in Node 18+, modern browsers, Deno, Bun, and edge runtimes.
Quick Start
Generate an API key at Settings → API Keys in your Lighthouse workspace.
import { Lighthouse } from 'lighthouse-private-markets-sdk'
const client = new Lighthouse('lgt_live_...')
// Who am I?
const me = await client.users.me()
console.log(me.data)
// Search your CRM
const res = await client.records.search('company', {
filters: {
operator: 'AND',
conditions: [
{ field: 'domain', operator: 'contains_any', value: ['acme.com'] },
],
},
limit: 10,
})
console.log(res.data, res.meta)Every method resolves to an APIResponse:
interface APIResponse<T = unknown> {
data: T | null
error: unknown | null
meta?: Record<string, unknown>
status: number
}Authentication
The client sends Authorization: Bearer <api_key> on every request. Keep API keys secret — never ship them in client-side code.
Resources
| Namespace | Endpoints |
|-----------------------|-----------|
| client.records | search / get / create / update / delete records (company, person, deal, custom objects) |
| client.lists | list / get / create / update / delete, getRecords, addRecord, removeRecord, shareWithTeams, revokeTeams, updateSharing |
| client.notes | list / get / create / delete, linkRecord, unlinkRecord |
| client.tasks | list / get / create / update / delete |
| client.attributes | list / get / create / update / delete, colors |
| client.options | list / create / delete select-field options |
| client.views | list / get / update / delete, shareWithTeams, revokeTeams, updateSharing |
| client.users | me, list, get |
| client.teams | list, get |
| client.dashboards | list / get / create / update / delete, listWidgets, createWidget, updateWidget, deleteWidget, widgetData, shareWithTeams, revokeTeams |
| client.discovery | getAttributes, searchCompanies, searchPeople, lookupCompaniesByDomain, lookupCompaniesByLinkedin, lookupPeopleByLinkedin, getSavedSearches, getSearchResults, getLocations, getIndustries, getTags, searchInvestors, searchOrganizations, searchSchools |
| client.documents | folders + files (v2): listFolders, createFolder, updateFolder, deleteFolder, link/unlinkFolder, uploadUrl, finalizeFile, getFile, updateFile, deleteFile, link/unlinkFile, listRecordDocuments, upload() one-shot helper |
Examples
Records
// Create
const { data: created } = await client.records.create('company', {
name: 'Acme',
domain: ['acme.com'],
})
const recordId = (created as any).id
// Update — relation fields are replaced entirely; pass the full desired array
await client.records.update('company', recordId, {
domain: ['acme.com', 'acme.io'],
})
// Get
await client.records.get('company', recordId)
// Delete
await client.records.delete('company', recordId)Filtering with attributes
const attrs = await client.attributes.list({ record_type: 'company' })
// pick a field permalink from attrs.data, then:
await client.records.search('company', {
filters: {
operator: 'AND',
conditions: [{ field: 'headcount', operator: 'gte', value: 50 }],
},
sort: [{ field: 'name', direction: 'asc' }],
limit: 25,
})Lists
const { data: newList } = await client.lists.create({
name: 'Hot leads',
record_type: 'company',
})
const listId = (newList as any).id
await client.lists.addRecord(listId, '…record_uuid…')
await client.lists.getRecords(listId, { limit: 50 })Notes
await client.notes.create({
title: 'Intro call',
content: '<p>Met the founder, looking strong.</p>',
records: { company: ['…uuid…'], person: ['…uuid…'] },
})Tasks
await client.tasks.create({
title: 'Send follow-up',
due_date: '2026-06-01',
assigned_to: ['…user_uuid…'],
records: { company: ['…uuid…'] },
})Discovery
// Always inspect attributes first to discover valid field keys
await client.discovery.getAttributes({ type: 'company' })
// Search Lighthouse's global database
const companies = await client.discovery.searchCompanies({
filters: {
operator: 'AND',
conditions: [
{ field: 'company_hq_country', operator: 'contains_any', value: ['US'] },
{
field: 'company_headcount',
operator: 'between',
value: { min: 10, max: 200 },
},
],
},
limit: 25,
})
// Enrich by domain / LinkedIn
await client.discovery.lookupCompaniesByDomain(['stripe.com', 'openai.com'])Documents
// One-shot helper handles uploadUrl + PUT + finalize
const file = await client.documents.upload({
name: 'pitch.pdf',
content: pitchBlob, // Blob | ArrayBuffer | Uint8Array
content_type: 'application/pdf',
sharing_status: 'WORKSPACE',
})
const fileId = (file.data as any).id
await client.documents.linkFileToRecord(fileId, 'company', '…uuid…')Error handling
import { Lighthouse, LighthouseError } from 'lighthouse-private-markets-sdk'
const client = new Lighthouse('lgt_live_…')
const res = await client.records.search('company')
if (res.error) {
console.error('API error:', res.status, res.error)
} else {
console.log(res.data)
}Network failures and malformed JSON responses throw LighthouseError.
Low-level escape hatch
For endpoints not yet wrapped by a namespace:
await client.request('GET', '/v1/some/new/endpoint', {
params: { foo: 'bar' },
})
await client.request('POST', '/v1/some/other', {
body: { hello: 'world' },
})License
MIT
