Skip to main content

Lead Import API

Bulk import leads from CSV files with field mapping and deduplication.

POST /leads/import/preview

Upload a CSV file to preview headers and sample rows before importing.

Request

Multipart form data with CSV file.

ParameterTypeRequiredDescription
filefileYesCSV file with header row

Request Example

curl -X POST "https://api.leadvibe.com/leads/import/preview" \
-H "Authorization: Bearer <token>" \
-F "file=@leads.csv"

Response

200 OK

{
"file_id": "preview_abc123",
"file_name": "leads.csv",
"headers": ["Email", "First Name", "Last Name", "Company", "Phone"],
"sample_rows": [
["jane@example.com", "Jane", "Doe", "Example Inc", "+1-555-0100"],
["john@example.com", "John", "Smith", "Acme Corp", "+1-555-0101"]
],
"row_count": 1000,
"auto_detected_identifiers": {
"email_columns": ["Email"],
"phone_columns": ["Phone"]
},
"expires_at": "2025-01-15T11:00:00Z"
}

Response Fields

FieldTypeDescription
file_idstringUnique identifier for cached file (valid for 1 hour)
file_namestringOriginal filename
headersarrayColumn names from CSV header row
sample_rowsarrayFirst 5 rows of data for preview
row_countintegerTotal number of rows (excluding header)
auto_detected_identifiersobjectColumns that look like identifiers
expires_attimestampWhen the cached file expires

Common Errors

StatusMeaningSolution
400Bad RequestFile missing or invalid CSV format
413Payload Too LargeFile exceeds 10 MB limit
415Unsupported Media TypeFile must be CSV

POST /leads/import/start

Start an import job with field mappings.

Request

ParameterTypeRequiredDescription
file_idstringYesFile ID from preview response
primary_identifierobjectYesPrimary identifier configuration
primary_identifier.columnstringYesCSV column name for identifier
primary_identifier.kindstringYesIdentifier type: "email", "phone", "cookie", "external_id", "social"
field_mappingsobjectNoMap CSV columns to profile fields
alias_mappingsobjectNoMap CSV columns to additional aliases

Request Body Example

{
"file_id": "preview_abc123",
"primary_identifier": {
"column": "Email",
"kind": "email"
},
"field_mappings": {
"First Name": "first_name",
"Last Name": "last_name",
"Company": "company",
"Job Title": "title"
},
"alias_mappings": {
"Phone": "_alias_phone",
"LinkedIn": "_alias_social"
}
}

Alias Mapping Keys

Additional identifiers use _alias_ prefix:

  • _alias_email - Additional email address
  • _alias_phone - Additional phone number
  • _alias_cookie - Additional cookie ID
  • _alias_external_id - Additional external ID
  • _alias_social - Additional social handle

Response

202 Accepted

{
"job_id": "job_abc123",
"status": "queued",
"message": "Import job started",
"file_name": "leads.csv",
"total_rows": 1000
}

Request Example

curl -X POST "https://api.leadvibe.com/leads/import/start" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"file_id": "preview_abc123",
"primary_identifier": {
"column": "Email",
"kind": "email"
},
"field_mappings": {
"First Name": "first_name",
"Last Name": "last_name",
"Company": "company"
},
"alias_mappings": {
"Phone": "_alias_phone"
}
}'

Common Errors

StatusMeaningSolution
400Bad RequestMissing required fields or invalid mappings
404Not FoundFile ID expired or not found (previews expire after 1 hour)

GET /leads/import/jobs

List all import jobs for the current OU.

Request

ParameterTypeRequiredDescription
pageintegerNoPage number (default: 1)
limitintegerNoResults per page (default: 25, max: 100)

Response

200 OK

{
"jobs": [
{
"job_id": "job_abc123",
"status": "completed",
"file_name": "leads.csv",
"created_at": "2025-01-15T10:00:00Z",
"completed_at": "2025-01-15T10:05:00Z",
"total_rows": 1000,
"created_count": 750,
"updated_count": 230,
"failed_count": 20
},
{
"job_id": "job_def456",
"status": "in_progress",
"file_name": "contacts.csv",
"created_at": "2025-01-15T11:00:00Z",
"completed_at": null,
"total_rows": 500,
"created_count": 250,
"updated_count": 100,
"failed_count": 5
}
],
"total": 2,
"page": 1,
"limit": 25
}

Job Status Values

StatusDescription
queuedJob is waiting to start
in_progressCurrently processing rows
completedAll rows processed
failedJob failed to complete
cancelledUser cancelled the job

Request Example

curl -X GET "https://api.leadvibe.com/leads/import/jobs?page=1&limit=25" \
-H "Authorization: Bearer <token>"

GET /leads/import/jobs/{jobId}

Get detailed results for a specific import job.

Request

ParameterTypeRequiredDescription
jobIdstringYesImport job ID (path parameter)

Response

200 OK

{
"job_id": "job_abc123",
"status": "completed",
"created_at": "2025-01-15T10:00:00Z",
"started_at": "2025-01-15T10:00:05Z",
"completed_at": "2025-01-15T10:05:00Z",
"file_name": "leads.csv",
"total_rows": 1000,
"created_count": 750,
"updated_count": 230,
"failed_count": 20,
"primary_identifier": {
"column": "Email",
"kind": "email"
},
"field_mappings": {
"First Name": "first_name",
"Last Name": "last_name",
"Company": "company"
},
"errors": [
{
"row": 45,
"error": "Invalid email format",
"value": "not-an-email"
},
{
"row": 102,
"error": "Missing required identifier",
"value": ""
}
]
}

Response Fields

FieldTypeDescription
job_idstringJob identifier
statusstringCurrent status
created_attimestampWhen job was created
started_attimestampWhen processing began
completed_attimestampWhen processing finished (null if in progress)
file_namestringOriginal filename
total_rowsintegerTotal rows in CSV (excluding header)
created_countintegerNumber of new leads created
updated_countintegerNumber of existing leads updated
failed_countintegerNumber of rows that failed
primary_identifierobjectIdentifier configuration used
field_mappingsobjectField mappings used
errorsarrayDetails for failed rows

Request Example

curl -X GET "https://api.leadvibe.com/leads/import/jobs/job_abc123" \
-H "Authorization: Bearer <token>"

Common Errors

StatusMeaningSolution
404Not FoundJob ID does not exist or not accessible

Import Behavior Details

Deduplication

LeadVibe automatically prevents duplicate leads:

  1. Identifier Lookup: For each row, looks up lead by primary identifier
  2. Create or Update:
    • If no matching lead exists: Creates new lead
    • If matching lead exists: Updates profile with new values
  3. Alias Addition: Additional aliases are added to existing leads (not replaced)

Example:

Field Mapping Rules

Profile Fields:

  • Empty CSV cells are skipped (won't overwrite existing data)
  • Non-empty values update the profile field
  • Unknown field names are ignored

Alias Mappings:

  • Aliases are added (not replaced)
  • Duplicate aliases are ignored
  • Empty alias values are skipped

Data Types:

  • All profile fields stored as strings
  • No automatic type conversion
  • Validation performed on identifiers (e.g., email format)

Error Handling

Row-Level Errors:

  • Failed rows don't stop the import
  • Other rows continue processing
  • Errors recorded with row number and reason

Common Error Types:

ErrorCause
Invalid email formatEmail doesn't match pattern
Invalid phone formatPhone contains invalid characters
Missing required identifierIdentifier column is empty
Database errorUnexpected storage failure

Use Cases

Migrate Contacts from Another System

Import your existing contact database into LeadVibe.

# Step 1: Preview the CSV
curl -X POST "https://api.leadvibe.com/leads/import/preview" \
-H "Authorization: Bearer <token>" \
-F "file=@contacts.csv"

# Response includes file_id: "preview_abc123"

# Step 2: Start import with mappings
curl -X POST "https://api.leadvibe.com/leads/import/start" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"file_id": "preview_abc123",
"primary_identifier": {
"column": "Email",
"kind": "email"
},
"field_mappings": {
"FirstName": "first_name",
"LastName": "last_name",
"Company": "company",
"Title": "title"
}
}'

# Step 3: Monitor progress
curl -X GET "https://api.leadvibe.com/leads/import/jobs/job_abc123" \
-H "Authorization: Bearer <token>"

Import Event Leads with Multiple Identifiers

Import trade show leads with both email and phone numbers.

curl -X POST "https://api.leadvibe.com/leads/import/start" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"file_id": "preview_xyz789",
"primary_identifier": {
"column": "Email",
"kind": "email"
},
"field_mappings": {
"Name": "first_name",
"Company": "company",
"Booth Notes": "notes"
},
"alias_mappings": {
"Mobile": "_alias_phone",
"Badge ID": "_alias_external_id"
}
}'

Bulk Update Existing Leads

Update profile information for existing leads.

# Import with email as primary identifier
# Existing leads will be updated with new field values
curl -X POST "https://api.leadvibe.com/leads/import/start" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"file_id": "preview_update123",
"primary_identifier": {
"column": "Email",
"kind": "email"
},
"field_mappings": {
"Updated Title": "title",
"Current Company": "company"
}
}'

Notes

  • CSV files must have a header row with column names
  • Maximum file size: 10 MB
  • File previews are cached for 1 hour (then must be re-uploaded)
  • Imports run as background jobs (non-blocking)
  • Large imports (10,000+ rows) may take several minutes
  • Import jobs are OU-scoped (only visible within the OU)
  • Empty CSV cells don't overwrite existing lead data
  • UTF-8 encoding recommended for special characters
  • Profile field names are case-insensitive in mappings