nodestash

Resources

Complete reference for all SDK resource classes and their methods

Every resource class provides a consistent set of CRUD methods. Below is the full reference for each resource.

Common Methods

All standard resources share these methods:

MethodSignatureDescription
createcreate(params, idempotencyKey?): Promise<T>Create a new resource
getget(id): Promise<T>Retrieve by ID
listlist(params?): Promise<ListResponse<T>>List with pagination
updateupdate(id, params, idempotencyKey?): Promise<T>Partial update
deletedelete(id): Promise<void>Delete by ID
listAlllistAll(params?): AsyncGenerator<T>Auto-paginating iterator

Contacts

// Create
const contact = await client.contacts.create({
  email: 'jane@acme.com',       // unique per workspace
  first_name: 'Jane',
  last_name: 'Doe',
  phone: '+1-555-0100',
  company_id: 'co_abc123',
  title: 'VP of Engineering',
  source: 'website',
  custom_fields: { plan: 'enterprise' },
  tags: ['vip', 'prospect'],
})

// List with filters
const { data, pagination } = await client.contacts.list({
  email: 'acme.com',            // substring match
  first_name: 'jane',           // substring match
  last_name: 'doe',             // substring match
  company_id: 'co_abc123',      // exact match
  source: 'website',            // exact match
  tags: 'vip,enterprise',       // must have ALL tags
  sort: '-created_at',          // prefix - for descending
  limit: 50,
  cursor: 'eyJjcmVh...',
})

// Get, update, delete
const contact = await client.contacts.get('ct_abc123')
await client.contacts.update('ct_abc123', { title: 'CTO' })
await client.contacts.delete('ct_abc123')

Companies

// Create
const company = await client.companies.create({
  name: 'Acme Corp',            // required
  domain: 'acme.com',           // unique per workspace
  industry: 'Technology',
  size: '51-200',
  custom_fields: {},
  tags: ['enterprise'],
})

// List with filters
const { data } = await client.companies.list({
  name: 'acme',                 // substring match
  domain: 'acme.com',           // substring match
  industry: 'Technology',       // substring match
  size: '51-200',               // substring match
  tags: 'enterprise',
  sort: 'name',
  limit: 25,
})

// Get, update, delete
const company = await client.companies.get('co_abc123')
await client.companies.update('co_abc123', { industry: 'SaaS' })
await client.companies.delete('co_abc123')

Deals

// Create
const deal = await client.deals.create({
  title: 'Enterprise License',  // required
  value: 50000,
  currency: 'EUR',              // 3-letter code, default: EUR
  pipeline_id: 'pp_abc123',
  stage_id: 'ps_def456',
  contact_id: 'ct_ghi789',
  company_id: 'co_jkl012',
  expected_close_date: '2026-06-30',
  custom_fields: {},
  tags: ['enterprise'],
})

// List with filters
const { data } = await client.deals.list({
  pipeline_id: 'pp_abc123',     // exact match
  stage_id: 'ps_def456',        // exact match
  contact_id: 'ct_ghi789',      // exact match
  company_id: 'co_jkl012',      // exact match
  tags: 'enterprise',
  min_value: '10000',           // range filter
  max_value: '100000',          // range filter
  sort: '-value',
  limit: 25,
})

// Move deal to a new stage
await client.deals.update('dl_abc123', {
  stage_id: 'ps_won_stage',     // closed_at auto-set for won/lost
})

Pipelines

// Create with stages
const pipeline = await client.pipelines.create({
  name: 'Sales Pipeline',       // required
  description: 'Main sales process',
  stages: [                     // required, min 1 stage
    { name: 'Lead', position: 0, type: 'open' },
    { name: 'Qualified', position: 1, type: 'open' },
    { name: 'Won', position: 2, type: 'won' },
    { name: 'Lost', position: 3, type: 'lost' },
  ],
})

// List, get, update, delete
const { data } = await client.pipelines.list({ limit: 10 })
const pipeline = await client.pipelines.get('pp_abc123')
await client.pipelines.update('pp_abc123', { name: 'Updated Pipeline' })
await client.pipelines.delete('pp_abc123')

Pipeline Stages

Stages are accessed through client.pipelines.stages and require a pipelineId:

// Add a stage
const stage = await client.pipelines.stages.create('pp_abc123', {
  name: 'Negotiation',          // required
  position: 2,                  // required
  type: 'open',                 // required: 'open' | 'won' | 'lost'
})

// Get a stage
const stage = await client.pipelines.stages.get('pp_abc123', 'ps_def456')

// Update a stage
await client.pipelines.stages.update('pp_abc123', 'ps_def456', {
  name: 'Contract Review',
})

// Delete a stage
await client.pipelines.stages.delete('pp_abc123', 'ps_def456')

Activities

// Create
const activity = await client.activities.create({
  type: 'task',                 // required: note|task|email|call|meeting|custom
  subject: 'Follow up call',
  body: 'Discuss pricing options',
  contact_id: 'ct_abc123',
  company_id: 'co_def456',
  deal_id: 'dl_ghi789',
  owner_id: 'user_abc',
  is_done: false,
  due_date: '2026-03-01T09:00:00Z',
  metadata: { duration_seconds: 1800 },
  tags: ['follow-up'],
})

// List with filters
const { data } = await client.activities.list({
  type: 'task',                 // exact match
  contact_id: 'ct_abc123',     // exact match
  company_id: 'co_def456',     // exact match
  deal_id: 'dl_ghi789',        // exact match
  is_done: 'false',            // string 'true' or 'false'
  sort: '-due_date',
  limit: 50,
})

// Mark as done
await client.activities.update('act_abc123', { is_done: true })

Custom Field Definitions

// Create
const definition = await client.customFields.definitions.create({
  entity_type: 'contact',       // required: contact|company|deal|activity
  name: 'VIP Level',            // required
  slug: 'vip_level',            // auto-generated if omitted
  field_type: 'select',         // required
  description: 'Customer tier',
  is_required: false,
  options: ['Platinum', 'Gold', 'Silver'],  // required for select/multi_select
  display_order: 0,
})

// List with filters
const { data } = await client.customFields.definitions.list({
  entity_type: 'contact',
})

// Get, update, delete
const def = await client.customFields.definitions.get('cf_abc123')
await client.customFields.definitions.update('cf_abc123', {
  name: 'Customer Tier',
  options: ['Platinum', 'Gold', 'Silver', 'Bronze'],
})
await client.customFields.definitions.delete('cf_abc123')

Custom Field Values

// Set values (merge operation — existing values preserved)
const values = await client.customFields.values.set('contacts', 'ct_abc123', {
  fields: {
    vip_level: 'Gold',
    annual_revenue: 500000,
  },
})

// Get all values for an entity
const values = await client.customFields.values.get('contacts', 'ct_abc123')
for (const field of values) {
  console.log(`${field.name}: ${field.value}`)
}

Entity types in value methods use plural form: 'contacts', 'companies', 'deals', 'activities'.

API Keys

// Create (returns full secret only once)
const keyWithSecret = await client.apiKeys.create({
  name: 'Mobile App Key',       // required
  scopes: ['contacts:read', 'deals:read'],
  expires_at: '2027-01-01T00:00:00Z',
})
console.log(keyWithSecret.key)  // nds_live_... (store securely!)

// List (secret not included)
const { data } = await client.apiKeys.list({ limit: 100 })

// Get, update, delete
const key = await client.apiKeys.get('key_abc123')
await client.apiKeys.update('key_abc123', {
  name: 'Updated Name',
  scopes: ['contacts:read'],
})
await client.apiKeys.delete('key_abc123')

On this page