Contacts API

CRM-like contact and relationship management. Create and manage contacts, track interaction history, build relationship graphs stored in Neo4j, auto-extract contacts from meetings and messages, and merge duplicates. All endpoints require JWT authentication and are rate-limited to 100 requests per minute.

Base path: /api/v2/contacts

Contact CRUD

Create, list, retrieve, update, and delete contacts. Contacts are scoped to the authenticated user and stored in both PostgreSQL and the Neo4j knowledge graph.

POST/api/v2/contactsAuthenticated

Create a new contact. Checks for duplicate emails and stores in both PostgreSQL and the Neo4j knowledge graph.

Body Parameters

namestringrequired

Full name of the contact.

emailstring

Email address (must be unique per user).

phonestring

Phone number.

companystring

Company or organization.

titlestring

Job title or role.

tagsstring[]

Tags for categorization.

notesstring

Free-form notes.

sourcestring

How the contact was added: "meeting", "message", or "manual". Defaults to "manual".

Request

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Jane Smith",
    400">class="text-emerald-400">"email": 400">class="text-emerald-400">"jane@acme.com",
    400">class="text-emerald-400">"company": 400">class="text-emerald-400">"Acme Corp",
    400">class="text-emerald-400">"title": 400">class="text-emerald-400">"VP Engineering",
    400">class="text-emerald-400">"tags": [400">class="text-emerald-400">"client", 400">class="text-emerald-400">"engineering"],
    400">class="text-emerald-400">"source": 400">class="text-emerald-400">"meeting"
  }'

Response 201

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"contact": {
    400">class="text-emerald-400">"id": 400">class="text-emerald-400">"550e8400-e29b-41d4-a716-446655440000",
    400">class="text-emerald-400">"user_id": 400">class="text-emerald-400">"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11",
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Jane Smith",
    400">class="text-emerald-400">"email": 400">class="text-emerald-400">"jane@acme.com",
    400">class="text-emerald-400">"phone": null,
    400">class="text-emerald-400">"company": 400">class="text-emerald-400">"Acme Corp",
    400">class="text-emerald-400">"title": 400">class="text-emerald-400">"VP Engineering",
    400">class="text-emerald-400">"tags": [400">class="text-emerald-400">"client", 400">class="text-emerald-400">"engineering"],
    400">class="text-emerald-400">"notes": 400">class="text-emerald-400">"",
    400">class="text-emerald-400">"source": 400">class="text-emerald-400">"meeting",
    400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-04-01T12:00:00.000Z",
    400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-04-01T12:00:00.000Z"
  }
}
GET/api/v2/contactsAuthenticated

List contacts with search, filtering, and pagination. Ordered alphabetically by name.

Query Parameters

searchstring

Search by name, email, or company (case-insensitive).

companystring

Filter by exact company name.

tagsstring

Comma-separated tags to filter by (uses contains).

sourcestring

Filter by source: meeting, message, manual.

limitinteger

Maximum contacts to return. Defaults to 50.

offsetinteger

Number of contacts to skip.

Request

cURL
400">curl -X 400">GET 400">class="text-emerald-400">"https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts?search=acme&tags=client&limit=25" \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"

Response 200

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"contacts": [
    {
      400">class="text-emerald-400">"id": 400">class="text-emerald-400">"550e8400-e29b-41d4-a716-446655440000",
      400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Jane Smith",
      400">class="text-emerald-400">"email": 400">class="text-emerald-400">"jane@acme.com",
      400">class="text-emerald-400">"company": 400">class="text-emerald-400">"Acme Corp",
      400">class="text-emerald-400">"title": 400">class="text-emerald-400">"VP Engineering",
      400">class="text-emerald-400">"tags": [400">class="text-emerald-400">"client", 400">class="text-emerald-400">"engineering"],
      400">class="text-emerald-400">"source": 400">class="text-emerald-400">"meeting",
      400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-04-01T12:00:00.000Z"
    }
  ],
  400">class="text-emerald-400">"total": 1,
  400">class="text-emerald-400">"limit": 25,
  400">class="text-emerald-400">"offset": 0
}
GET/api/v2/contacts/:idAuthenticated

Get full contact details.

Path Parameters

idstringrequired

UUID of the contact.

Request

cURL
400">curl -X 400">GET https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts/550e8400-e29b-41d4-a716-446655440000 \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"

Response 200

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"contact": {
    400">class="text-emerald-400">"id": 400">class="text-emerald-400">"550e8400-e29b-41d4-a716-446655440000",
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Jane Smith",
    400">class="text-emerald-400">"email": 400">class="text-emerald-400">"jane@acme.com",
    400">class="text-emerald-400">"phone": null,
    400">class="text-emerald-400">"company": 400">class="text-emerald-400">"Acme Corp",
    400">class="text-emerald-400">"title": 400">class="text-emerald-400">"VP Engineering",
    400">class="text-emerald-400">"tags": [400">class="text-emerald-400">"client", 400">class="text-emerald-400">"engineering"],
    400">class="text-emerald-400">"notes": 400">class="text-emerald-400">"",
    400">class="text-emerald-400">"source": 400">class="text-emerald-400">"meeting",
    400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-04-01T12:00:00.000Z",
    400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-04-01T12:00:00.000Z"
  }
}
PUT/api/v2/contacts/:idAuthenticated

Update contact fields. Only provided fields are updated. Also syncs changes to the Neo4j knowledge graph.

Path Parameters

idstringrequired

UUID of the contact.

Body Parameters

namestring

Updated name.

emailstring

Updated email.

phonestring

Updated phone.

companystring

Updated company.

titlestring

Updated title.

tagsstring[]

Updated tags.

notesstring

Updated notes.

Request

cURL
400">curl -X 400">PUT https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts/550e8400-e29b-41d4-a716-446655440000 \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"title": 400">class="text-emerald-400">"CTO",
    400">class="text-emerald-400">"tags": [400">class="text-emerald-400">"client", 400">class="text-emerald-400">"engineering", 400">class="text-emerald-400">"leadership"]
  }'

Response 200

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"contact": {
    400">class="text-emerald-400">"id": 400">class="text-emerald-400">"550e8400-e29b-41d4-a716-446655440000",
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Jane Smith",
    400">class="text-emerald-400">"email": 400">class="text-emerald-400">"jane@acme.com",
    400">class="text-emerald-400">"company": 400">class="text-emerald-400">"Acme Corp",
    400">class="text-emerald-400">"title": 400">class="text-emerald-400">"CTO",
    400">class="text-emerald-400">"tags": [400">class="text-emerald-400">"client", 400">class="text-emerald-400">"engineering", 400">class="text-emerald-400">"leadership"],
    400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-04-01T14:00:00.000Z"
  }
}
DELETE/api/v2/contacts/:idAuthenticated

Delete a contact from both PostgreSQL and the Neo4j knowledge graph.

Path Parameters

idstringrequired

UUID of the contact to delete.

Request

cURL
400">curl -X 400">DELETE https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts/550e8400-e29b-41d4-a716-446655440000 \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"

Response 200

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"message": 400">class="text-emerald-400">"Contact deleted"
}

Interactions & Relationships

Track interaction history and manage relationship graphs between contacts. Relationship data is stored in Neo4j for graph-based querying.

GET/api/v2/contacts/:id/interactionsAuthenticated

Get interaction history for a contact from the knowledge graph.

Path Parameters

idstringrequired

UUID of the contact.

Query Parameters

typestring

Filter by type: call, message, meeting, email.

limitinteger

Maximum interactions to return. Defaults to 50.

Request

cURL
400">curl -X 400">GET 400">class="text-emerald-400">"https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts/550e8400-e29b-41d4-a716-446655440000/interactions?400">type=meeting&limit=10" \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"

Response 200

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"interactions": [
    {
      400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"meeting",
      400">class="text-emerald-400">"date": 400">class="text-emerald-400">"2026-03-28T14:00:00.000Z",
      400">class="text-emerald-400">"summary": 400">class="text-emerald-400">"Discussed Q2 roadmap and integration timeline",
      400">class="text-emerald-400">"metadata": { 400">class="text-emerald-400">"duration_minutes": 45 }
    }
  ],
  400">class="text-emerald-400">"total": 1
}
POST/api/v2/contacts/:id/relationshipsAuthenticated

Create a relationship between two contacts in the Neo4j knowledge graph.

Path Parameters

idstringrequired

UUID of the source contact.

Body Parameters

relatedContactIdstringrequired

UUID of the related contact.

typestringrequired

Relationship type: colleague, client, friend, family, vendor, other.

strengthnumber

Relationship strength (0.0 to 1.0). Defaults to 0.5.

notesstring

Notes about the relationship.

Request

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts/550e8400-e29b-41d4-a716-446655440000/relationships \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"relatedContactId": 400">class="text-emerald-400">"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
    400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"colleague",
    400">class="text-emerald-400">"strength": 0.8,
    400">class="text-emerald-400">"notes": 400">class="text-emerald-400">"Same engineering team at Acme"
  }'

Response 201

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"relationship": {
    400">class="text-emerald-400">"400">from": 400">class="text-emerald-400">"550e8400-e29b-41d4-a716-446655440000",
    400">class="text-emerald-400">"to": 400">class="text-emerald-400">"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
    400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"colleague",
    400">class="text-emerald-400">"strength": 0.8,
    400">class="text-emerald-400">"notes": 400">class="text-emerald-400">"Same engineering team at Acme"
  }
}
GET/api/v2/contacts/:id/relationshipsAuthenticated

Get all relationships for a contact, enriched with contact details from PostgreSQL.

Path Parameters

idstringrequired

UUID of the contact.

Query Parameters

typestring

Filter by relationship type.

Request

cURL
400">curl -X 400">GET 400">class="text-emerald-400">"https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts/550e8400-e29b-41d4-a716-446655440000/relationships?400">type=colleague" \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"

Response 200

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"relationships": [
    {
      400">class="text-emerald-400">"contactId": 400">class="text-emerald-400">"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
      400">class="text-emerald-400">"contact": {
        400">class="text-emerald-400">"id": 400">class="text-emerald-400">"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
        400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Bob Johnson",
        400">class="text-emerald-400">"email": 400">class="text-emerald-400">"bob@acme.com",
        400">class="text-emerald-400">"company": 400">class="text-emerald-400">"Acme Corp",
        400">class="text-emerald-400">"title": 400">class="text-emerald-400">"Senior Engineer"
      },
      400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"colleague",
      400">class="text-emerald-400">"strength": 0.8
    }
  ]
}

Auto-Extraction & Merge

Automatically extract contacts from meetings, messages, and emails. Merge duplicate contacts into a single record.

POST/api/v2/contacts/extractAuthenticated

Auto-extract contacts from a data source (meeting participants, message mentions, email headers).

Body Parameters

sourcestringrequired

Source type: "meeting", "message", or "email".

dataobjectrequired

Source data object (meeting participants, message content, email headers, etc.).

Request

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts/extract \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"source": 400">class="text-emerald-400">"meeting",
    400">class="text-emerald-400">"data": {
      400">class="text-emerald-400">"participants": [
        { 400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Jane Smith", 400">class="text-emerald-400">"email": 400">class="text-emerald-400">"jane@acme.com" },
        { 400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Bob Johnson", 400">class="text-emerald-400">"email": 400">class="text-emerald-400">"bob@acme.com" }
      ]
    }
  }'

Response 200

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"extracted": 2,
  400">class="text-emerald-400">"contacts": [
    { 400">class="text-emerald-400">"id": 400">class="text-emerald-400">"new_contact_1", 400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Jane Smith", 400">class="text-emerald-400">"email": 400">class="text-emerald-400">"jane@acme.com", 400">class="text-emerald-400">"source": 400">class="text-emerald-400">"meeting" },
    { 400">class="text-emerald-400">"id": 400">class="text-emerald-400">"new_contact_2", 400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Bob Johnson", 400">class="text-emerald-400">"email": 400">class="text-emerald-400">"bob@acme.com", 400">class="text-emerald-400">"source": 400">class="text-emerald-400">"meeting" }
  ]
}
POST/api/v2/contacts/mergeAuthenticated

Merge a duplicate contact into a primary contact. Non-null fields from the duplicate fill in missing fields on the primary. Tags are combined. The duplicate is deleted after merge.

Body Parameters

primaryIdstringrequired

UUID of the primary contact to keep.

duplicateIdstringrequired

UUID of the duplicate contact to merge and delete.

Request

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/contacts/merge \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"primaryId": 400">class="text-emerald-400">"550e8400-e29b-41d4-a716-446655440000",
    400">class="text-emerald-400">"duplicateId": 400">class="text-emerald-400">"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
  }'

Response 200

{
  400">class="text-emerald-400">"success": true,
  400">class="text-emerald-400">"contact": {
    400">class="text-emerald-400">"id": 400">class="text-emerald-400">"550e8400-e29b-41d4-a716-446655440000",
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Jane Smith",
    400">class="text-emerald-400">"email": 400">class="text-emerald-400">"jane@acme.com",
    400">class="text-emerald-400">"phone": 400">class="text-emerald-400">"+1-555-0100",
    400">class="text-emerald-400">"company": 400">class="text-emerald-400">"Acme Corp",
    400">class="text-emerald-400">"title": 400">class="text-emerald-400">"VP Engineering",
    400">class="text-emerald-400">"tags": [400">class="text-emerald-400">"client", 400">class="text-emerald-400">"engineering", 400">class="text-emerald-400">"meeting-2026-03"],
    400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-04-01T14:30:00.000Z"
  }
}