Contact Management
Create, organize, and search your contacts effectively
This guide covers common patterns for managing contacts — from creation and enrichment to searching and bulk operations.
Creating Contacts
Basic Contact
curl -X POST https://api.nodestash.io/v1/contacts \
-H "Authorization: Bearer $NODESTASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "alex@startup.io",
"first_name": "Alex",
"last_name": "Rivera"
}'const contact = await client.contacts.create({
email: 'alex@startup.io',
first_name: 'Alex',
last_name: 'Rivera',
})Fully Enriched Contact
curl -X POST https://api.nodestash.io/v1/contacts \
-H "Authorization: Bearer $NODESTASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "alex@startup.io",
"first_name": "Alex",
"last_name": "Rivera",
"phone": "+1-555-0200",
"title": "CTO",
"company_id": "co_abc123",
"source": "conference",
"tags": ["decision-maker", "technical"],
"custom_fields": {
"linkedin": "https://linkedin.com/in/alexrivera"
}
}'const contact = await client.contacts.create({
email: 'alex@startup.io',
first_name: 'Alex',
last_name: 'Rivera',
phone: '+1-555-0200',
title: 'CTO',
company_id: 'co_abc123',
source: 'conference',
tags: ['decision-maker', 'technical'],
custom_fields: {
linkedin: 'https://linkedin.com/in/alexrivera',
},
})Using Tags for Organization
Tags let you categorize contacts without rigid hierarchies. A contact can have up to 20 tags.
# Add tags when creating
curl -X POST https://api.nodestash.io/v1/contacts \
-H "Authorization: Bearer $NODESTASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "buyer@corp.com",
"first_name": "Jordan",
"tags": ["lead", "inbound", "enterprise"]
}'
# Update tags on existing contact
curl -X PATCH https://api.nodestash.io/v1/contacts/ct_abc123 \
-H "Authorization: Bearer $NODESTASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tags": ["customer", "enterprise", "champion"]
}'// Add tags when creating
const contact = await client.contacts.create({
email: 'buyer@corp.com',
first_name: 'Jordan',
tags: ['lead', 'inbound', 'enterprise'],
})
// Update tags on existing contact
await client.contacts.update('ct_abc123', {
tags: ['customer', 'enterprise', 'champion'],
})Updating tags replaces the entire tag array — include all desired tags in the update.
Adding Custom Fields
Define structured fields and attach values to contacts:
# 1. Define a custom field
curl -X POST https://api.nodestash.io/v1/custom-fields \
-H "Authorization: Bearer $NODESTASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "contact",
"name": "Lead Score",
"slug": "lead_score",
"field_type": "number",
"description": "Computed lead score from 0-100"
}'
# 2. Set the value on a contact
curl -X PUT https://api.nodestash.io/v1/contacts/ct_abc123/custom-fields \
-H "Authorization: Bearer $NODESTASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"lead_score": 85
}
}'// 1. Define a custom field
await client.customFields.definitions.create({
entity_type: 'contact',
name: 'Lead Score',
slug: 'lead_score',
field_type: 'number',
description: 'Computed lead score from 0-100',
})
// 2. Set the value on a contact
await client.customFields.values.set('contacts', 'ct_abc123', {
fields: {
lead_score: 85,
},
})Searching Contacts
Filter by Multiple Criteria
# Enterprise contacts from the website source
curl "https://api.nodestash.io/v1/contacts?tags=enterprise&source=website&sort=-created_at" \
-H "Authorization: Bearer $NODESTASH_API_KEY"const { data } = await client.contacts.list({
tags: 'enterprise',
source: 'website',
sort: '-created_at',
})Search by Name or Email
# Search by email domain (substring match)
curl "https://api.nodestash.io/v1/contacts?email=acme.com" \
-H "Authorization: Bearer $NODESTASH_API_KEY"
# Search by name
curl "https://api.nodestash.io/v1/contacts?first_name=alex" \
-H "Authorization: Bearer $NODESTASH_API_KEY"// Search by email domain
const { data: acmeContacts } = await client.contacts.list({
email: 'acme.com',
})
// Search by name
const { data: alexes } = await client.contacts.list({
first_name: 'alex',
})Iterating All Contacts
For bulk operations, use the SDK's auto-pagination:
// Export all contacts
const allContacts = []
for await (const contact of client.contacts.listAll({
sort: 'created_at',
limit: 100,
})) {
allContacts.push(contact)
}
console.log(`Total contacts: ${allContacts.length}`)Idempotent Creation
Use idempotency keys to safely retry contact creation:
curl -X POST https://api.nodestash.io/v1/contacts \
-H "Authorization: Bearer $NODESTASH_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: import-contact-alex-rivera" \
-d '{
"email": "alex@startup.io",
"first_name": "Alex",
"last_name": "Rivera"
}'const contact = await client.contacts.create(
{
email: 'alex@startup.io',
first_name: 'Alex',
last_name: 'Rivera',
},
'import-contact-alex-rivera', // idempotency key
)If the same idempotency key is used again, the API returns the original contact instead of creating a duplicate.
Next Steps
- Link contacts to Companies for organizational hierarchy
- Track interactions with Activities
- Attach contacts to Deals in your sales pipeline