Contact API
Interfaces to manage contacts
A contact is a person or business prospect that you are reaching out to. You can add contacts to campaigns and send them emails or LinkedIn messages.
V2 API Recommended
Verify an email without a contact
POST /v2/email-validation/verify). It uses the same credits as validate_emails but does not create a contact.Create Contact
Create a new campaign enrollment (Contact) or upsert a team contact profile without enrolling.
CampaignId: Upserts ContactProfile + ContactTeam for the team, then creates or updates the Contact row for that campaign (enrollment). Optional contact_profile_id seeds the enrollment from an existing profile (profile must already be on the campaign’s team); identity comes from the profile.CampaignId: Upserts ContactProfile + ContactTeam only. Response data.object is contact_profile with enrolled: false (no Contact row).Optional labels: array of label names (strings). Each name is matched to an existing org/team label (case-insensitive; same behavior as CSV). Only labels with applies_to contact or both are attached; unknown names and conversation-only labels are ignored.
Important: At least one of email or linkedin_url must be provided.
V2 API (Recommended)
curl -X POST 'https://api.supersend.io/v2/contacts' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Joe",
"last_name": "Paul",
"email": "joe.paul@example.com",
"company_name": "ABC Corp",
"title": "Manager",
"phone": "+1-534-634-5346",
"city": "Raleigh",
"state": "NC",
"country": "United States",
"custom": {
"department": "Sales"
},
"TeamId": "your-team-id",
"CampaignId": "your-campaign-id"
}'# Optional: Add "validate_emails": true to verify when the profile is unvalidated or pending (consumes credits). Already-validated profiles are skipped on repeat upserts. Default is false.
# Response (201 Created)
{
"success": true,
"data": {
"id": "e8048d7f-3b04-4d6a-b73f-a400b514f626",
"email": "joe.paul@example.com",
"first_name": "Joe",
"last_name": "Paul",
"company_name": "ABC Corp",
"title": "Manager",
"phone": "+1-534-634-5346",
"city": "Raleigh",
"state": "NC",
"country": "United States",
"custom": {
"department": "Sales"
},
"CampaignId": "your-campaign-id",
"TeamId": "your-team-id",
"createdAt": "2025-08-12T15:25:50.939Z",
"updatedAt": "2025-08-12T15:25:50.939Z"
},
"request_id": "req_a1b2c3d4e5f6789012345678"
}
V1 API
curl -X POST 'https://api.supersend.io/v1/contact/create' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Joe",
"last_name": "Paul",
"email": "joe.paul@example.com",
"company_name": "ABC Corp",
"TeamId": "your-team-id",
"CampaignId": "your-campaign-id"
}'# Optional: "validate_emails": true or "validate_emails": "true" — same rules as V2 (unvalidated/pending only; skips already-validated profiles).
# Response (201 Created)
{
"message": "Contact created successfully",
"contact": {
"id": "e8048d7f-3b04-4d6a-b73f-a400b514f626",
"email": "joe.paul@example.com",
"first_name": "Joe",
"last_name": "Paul",
"company_name": "ABC Corp",
"CampaignId": "your-campaign-id",
"OrgId": "org-uuid",
"createdAt": "2025-08-12T15:25:50.939Z",
"updatedAt": "2025-08-12T15:25:50.939Z"
}
}
Contact Fields
| Field | Type | Required | Description |
|---|---|---|---|
TeamId | string | Yes | Team identifier |
CampaignId | string | No | Campaign identifier; omit for profile-only create (no enrollment row) |
labels | string[] | No | Label names to attach to the profile; existing contact/both labels only |
email | string | One required | Email address |
linkedin_url | string | One required | LinkedIn profile URL |
first_name | string | No | First name |
last_name | string | No | Last name |
company_name | string | No | Company name |
title | string | No | Job title |
phone | string | No | Phone number |
city | string | No | City |
state | string | No | State/Province |
country | string | No | Country |
company_url | string | No | Company website |
industry | string | No | Industry |
image | string | No | Profile image URL |
custom | object | No | Custom fields |
integration_contact_id | string | No | External system ID |
validate_emails | boolean | No | When true, runs email verification when the contact profile is unvalidated or pending (valid2 -1 or 0). Already-validated profiles are skipped (no extra credits). Applies on create, update, and re-enroll. Default is false. |
List Contacts
Get a paginated list of contacts with filtering.
V2 API (Recommended)
curl -X GET 'https://api.supersend.io/v2/contacts?TeamId=xxx&CampaignId=yyy&limit=20' \
-H "Authorization: Bearer YOUR_API_KEY"# Response (200 OK)
{
"success": true,
"data": [
{
"id": "contact-uuid",
"email": "contact@example.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "Acme Corp",
"title": "CEO",
"Campaign": {
"id": "campaign-uuid",
"name": "Q4 Outreach"
},
"createdAt": "2025-11-27T10:30:00Z",
"updatedAt": "2025-11-27T10:30:00Z"
}
],
"pagination": {
"total": 150,
"limit": 20,
"offset": 0,
"has_more": true
},
"request_id": "req_a1b2c3d4e5f6789012345678"
}
V2 Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
TeamId | string | Yes | Team identifier |
CampaignId | string | No | Filter by campaign |
search | string | No | Search in email, name, company |
interest | string | No | Filter by contact status. Values: interested, not_interested, meeting_request, meeting_booked, customer, future, follow_up. Comma-separated for multiple. |
deleted | boolean | No | Include deleted contacts |
limit | number | No | Results per page (default: 50, max: 100) |
offset | number | No | Pagination offset |
V1 API
curl -X POST 'https://api.supersend.io/v1/contact/all' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"TeamId": "xxx-xxx-xxx",
"CampaignId": "xxx-xxx-xxx",
"limit": 50,
"offset": 0
}'# Response
{
"count": 150,
"rows": [...],
"verified_count": 120,
"valid_count": 100,
"paused_count": 5
}
V1 supports additional filters not yet in V2:
verified, validated, finished, bounced, replied, unsubscribed, paused. For bounced contacts, list and get responses include bounce_category (invalid_recipient, policy_block, soft, or unknown) when available.has_email, has_linkedin, started_sequencevariant, email_providerGet Contact
Retrieve a single contact by ID.
Team contact profile (All Contacts) — V1
The All Contacts list is keyed by ContactProfile id. To load one profile’s fields, labels, and campaign enrollments, use the app-style endpoint (same Authorization: Bearer API key as V2):
curl -G 'https://api.supersend.io/v1/contact/profile/PROFILE_UUID' \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-urlencode "TeamId=your-team-id"Response includes success, contact (or Contact) with profile fields, __source: contact_profile, and associated_campaigns: an array of campaign enrollments for this profile.
Field (per associated_campaigns[] item) | Description |
|---|---|
id, name | Campaign |
ContactId | Enrollment Contact row id |
contactCreatedAt | When that enrollment was created; list is sorted newest first |
replied, bounced, unsubscribed, opened, clicked, finished, appointment | Engagement flags for that enrollment |
interest | Contact status in that campaign |
status | Queue status (idle, queued, processing) |
next_step, paused_at, resume_at, failed, reason, last_node_processed_at | Progress / pause / failure |
Note: GET /v2/contacts/:id returns a single enrollment by Contact id, not a profile id. Use the V1 profile URL above when you have a ContactProfile uuid from team contact lists or POST /v2/contacts profile-only responses.
V2 API (Recommended)
curl -X GET 'https://api.supersend.io/v2/contacts/contact-uuid' \
-H "Authorization: Bearer YOUR_API_KEY"# Response (200 OK)
{
"success": true,
"data": {
"id": "contact-uuid",
"email": "contact@example.com",
"first_name": "John",
"last_name": "Doe",
...
},
"request_id": "req_a1b2c3d4e5f6789012345678"
}
V1 API
curl -X GET 'https://api.supersend.io/v1/contact/contact-uuid' \
-H "Authorization: Bearer YOUR_API_KEY"# Response (200 OK)
{
"success": true,
"Contact": {
"id": "contact-uuid",
"email": "contact@example.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "Acme Corp",
"CampaignId": "campaign-uuid",
"Campaign": {
"id": "campaign-uuid",
"name": "Q4 Outreach"
},
"Sender": {
"id": "sender-uuid",
"email": "sales@yourcompany.com"
}
},
"ContactConfig": {
"id": "config-uuid",
"config": [...]
}
}
Update Contact
Update an existing contact. You can update the contact status (interest) to track pipeline stages: interested, not_interested, meeting_request, meeting_booked, customer, future, follow_up.
V2 API (Recommended)
curl -X PATCH 'https://api.supersend.io/v2/contacts/contact-uuid' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"company_name": "New Company",
"interest": "customer"
}'# Response (200 OK)
{
"success": true,
"data": {
"id": "contact-uuid",
"first_name": "Jane",
"company_name": "New Company",
...
},
"request_id": "req_a1b2c3d4e5f6789012345678"
}
V1 API
curl -X PUT 'https://api.supersend.io/v1/contact/contact-uuid' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"company_name": "New Company",
"TeamId": "xxx",
"CampaignId": "xxx"
}'# Response
{
"success": true,
"message": "Contact updated successfully."
}
Delete Contact
Delete a contact by ID or by identifier (email/LinkedIn URL).
V2 API (Recommended)
Delete by ID:
curl -X DELETE 'https://api.supersend.io/v2/contacts/contact-uuid' \
-H "Authorization: Bearer YOUR_API_KEY"# Response (200 OK)
{
"success": true,
"message": "Contact deleted successfully",
"request_id": "req_a1b2c3d4e5f6789012345678"
}
Delete by Email:
curl -X DELETE 'https://api.supersend.io/v2/contacts?TeamId=xxx&CampaignId=yyy&email=john@example.com' \
-H "Authorization: Bearer YOUR_API_KEY"Delete by LinkedIn URL:
curl -X DELETE 'https://api.supersend.io/v2/contacts?TeamId=xxx&CampaignId=yyy&linkedin_url=https://linkedin.com/in/johndoe' \
-H "Authorization: Bearer YOUR_API_KEY"List Contact Inbox Link Clicks {#list-contact-inbox-link-clicks}
Returns paginated inbox reply link click events for a contact.
V2 API
curl -X GET 'https://api.supersend.io/v2/contacts/contact-uuid/inbox-link-clicks?team_id=team-uuid&limit=50&offset=0' \
-H "Authorization: Bearer YOUR_API_KEY"# Response (200 OK)
{
"success": true,
"data": {
"clicks": [
{
"id": "click-uuid",
"link_id": "link-uuid",
"original_url": "https://your-site.com/demo",
"clicked_at": "2026-06-08T14:32:15.123Z",
"conversation_id": "conversation-uuid",
"conversation_message_id": "message-uuid",
"contact_id": "contact-uuid",
"sender_id": "sender-uuid"
}
],
"pagination": {
"total": 3,
"limit": 50,
"offset": 0,
"has_more": false
}
},
"request_id": "req_a1b2c3d4e5f6789012345678"
}
V2 Query Parameters:
| Parameter | Type | Description |
|---|---|---|
team_id | string (UUID) | Filter to a team (defaults to the contact's team) |
limit | number | Results per page (default: 50, max: 100) |
offset | number | Pagination offset |
See Campaign API: List Campaign Inbox Reply Link Clicks for campaign-attributed clicks with UTM-applied final_url.
Bulk Create Contacts
Import contacts in bulk via JSON array or CSV file upload. Processing happens asynchronously.
V2 API (Recommended)
curl -X POST 'https://api.supersend.io/v2/contacts/bulk' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{
"email": "contact1@example.com",
"first_name": "Alice",
"last_name": "Smith",
"company_name": "Acme Corp"
},
{
"email": "contact2@example.com",
"first_name": "Bob",
"last_name": "Jones",
"custom": {
"department": "Sales"
}
}
],
"TeamId": "xxx-xxx-xxx",
"CampaignId": "xxx-xxx-xxx"
}'# Optional: Add "validate_emails": true to verify when the profile is unvalidated or pending (consumes credits). Already-validated profiles are skipped on repeat upserts. Default is false.
# Response (202 Accepted)
{
"success": true,
"data": {
"upload_id": "upload-uuid",
"status": "pending",
"contact_count": 2,
"message": "Upload received. Processing will begin shortly."
},
"request_id": "req_a1b2c3d4e5f6789012345678"
}
CSV Upload (multipart/form-data):
curl -X POST 'https://api.supersend.io/v2/contacts/bulk' \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "contacts=@contacts.csv" \
-F "TeamId=xxx-xxx-xxx" \
-F "CampaignId=xxx-xxx-xxx" \
-F 700 dark:text-green-400">'mapping_fields={"Email": "email", "First Name": "first_name", "Last Name": "last_name"}' \
-F "validate_emails=true"Email validation: Set validate_emails: true (JSON) or -F "validate_emails=true" (CSV) to queue verification for contacts in the import (consumes credits). Default is false to avoid surprise billing. For single-contact create/upsert (POST /v2/contacts), already-validated profiles are not re-checked.
Limits:
V1 API
curl -X POST 'https://api.supersend.io/v1/bulk-contacts' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{
"email": "contact1@example.com",
"first_name": "Alice",
"last_name": "Smith"
},
{
"email": "contact2@example.com",
"first_name": "Bob",
"last_name": "Jones"
}
],
"TeamId": "xxx-xxx-xxx",
"CampaignId": "xxx-xxx-xxx"
}'# Response
{
"message": "Upload received. Processing will begin shortly.",
"uploadId": "upload-uuid"
}
Bulk Actions (V1 Only)
Perform bulk actions on multiple contacts.
Endpoint: POST /v1/contact/bulk-action
Available Actions
| Action | Description |
|---|---|
get_contacts | Get contacts matching filters |
verify_contacts | Mark contacts as verified |
unverify_contacts | Mark contacts as unverified |
verify_passed_email_validation | Verify contacts that passed email validation |
unverify_failed_email_validation | Unverify contacts that failed email validation |
restart | Restart contacts in sequence |
finish | Mark contacts as finished |
unfinish | Mark contacts as not finished |
resume | Resume paused contacts |
archive_unverified | Archive unverified contacts |
archive_all | Archive selected contacts |
unarchive | Unarchive contacts |
transfer | Transfer to another campaign (requires to_campaign_id) |
reassign_active_sender | Reassign active sender for contacts |
assign_step | Assign to specific sequence step (requires node_id and step_number) |
Example: Verify Contacts
curl -X POST 'https://api.supersend.io/v1/contact/bulk-action' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "verify_contacts",
"campaign_id": "xxx-xxx-xxx",
"contact_ids": ["contact-id-1", "contact-id-2"]
}'# Response
{
"success": true,
"message": "Contact(s) verified status updated successfully"
}
Example: Transfer Contacts
curl -X POST 'https://api.supersend.io/v1/contact/bulk-action' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "transfer",
"campaign_id": "source-campaign-id",
"to_campaign_id": "target-campaign-id",
"contact_ids": ["contact-id-1", "contact-id-2"]
}'V1 Advanced Filters
The V1 /v1/contact/all endpoint supports these additional filters:
Status Filters:
verified - Filter by verified statusvalidated - Filter by email validation statusfinished - Filter by finished statusappointment - Filter by appointment statusbounced - Filter by bounced statusreplied - Filter by replied statusunsubscribed - Filter by unsubscribed statuspaused - Filter by paused statusAdvanced Filters:
has_email - Filter contacts with/without emailhas_linkedin - Filter contacts with/without LinkedInhas_task - Filter contacts with pending tasksstarted_sequence - Filter contacts that started sequencenode_id - Filter by current sequence nodeinterest - Filter by interest levelvariant - Filter by A/B test variantemail_provider - Filter by email providersenderIds - Filter by assigned sender IDsreply_labels - Filter by conversation label IDscustoms - Filter by custom field values