Campaigns

Contact Management

Import, organize, and manage your campaign contacts with groups, CSV upload, deduplication, and batch operations.

Contact Management

Before you can run a campaign, you need contacts. thinnestAI provides tools to import, organize, deduplicate, and manage your contact lists at scale.

Contact Groups

Contacts are organized into groups. Each campaign targets one group. You might have groups like:

  • "Trial Users"
  • "Enterprise Leads Q1"
  • "Appointment Reminders - March"
  • "VIP Customers"

Creating a Contact Group

From the Dashboard:

  1. Go to Campaigns > Contacts in the sidebar.
  2. Click New Group.
  3. Enter a group name and optional description.
  4. Add contacts manually or via CSV import.

Via the API:

curl -X POST https://api.thinnest.ai/campaigns/contact-groups \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "March Webinar Attendees",
    "description": "Contacts who registered for the March product webinar"
  }'

Adding Contacts to a Group

curl -X POST https://api.thinnest.ai/campaigns/contact-groups/group_123/contacts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      {
        "first_name": "Jane",
        "last_name": "Smith",
        "email": "jane@example.com",
        "phone": "+14155551234",
        "metadata": {
          "company": "Acme Corp",
          "plan": "enterprise"
        }
      },
      {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john@example.com",
        "phone": "+14155555678"
      }
    ]
  }'

CSV Import

The fastest way to add contacts is by uploading a CSV file.

CSV Format

Your CSV should include headers. At minimum, you need a way to reach the contact (phone or email). All other fields are optional.

first_name,last_name,email,phone,company,plan,appointment_date
Jane,Smith,jane@example.com,+14155551234,Acme Corp,enterprise,2026-03-15
John,Doe,john@example.com,+14155555678,Globex Inc,pro,2026-03-16
Sarah,Johnson,sarah@example.com,+14155559012,Wayne Enterprises,enterprise,2026-03-17

Importing a CSV

From the Dashboard:

  1. Go to Campaigns > Contacts.
  2. Select a group or create a new one.
  3. Click Import CSV.
  4. Upload your file.
  5. Map CSV columns to contact fields.
  6. Review the preview and confirm.

Via the API:

curl -X POST https://api.thinnest.ai/campaigns/contact-groups/group_123/import \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@contacts.csv" \
  -F "mapping={\"first_name\": \"first_name\", \"last_name\": \"last_name\", \"email\": \"email\", \"phone\": \"phone\"}"

Column Mapping

When column names in your CSV don't match the expected fields, use the mapping interface to connect them:

CSV ColumnMaps To
Namefirst_name
Email Addressemail
Mobilephone
Organizationcompany

Any unmapped columns are stored as custom metadata on the contact record. You can use them as template variables in campaigns.

Import Validation

During import, each row is validated:

CheckRule
Phone formatMust be E.164 format (e.g., +14155551234)
Email formatMust be a valid email address
Required fieldsAt least one contact method (phone or email)
DuplicatesDetected and flagged (see below)

Invalid rows are skipped and reported in the import summary. You can download a list of skipped rows with error details.

Contact Deduplication

When importing contacts, thinnestAI automatically checks for duplicates.

How Deduplication Works

Contacts are considered duplicates if they share:

  • The same phone number, OR
  • The same email address

Duplicate Handling Options

OptionBehavior
Skip (default)Duplicate contacts are ignored; existing records are kept
UpdateExisting contact records are updated with new data
Create AnywayDuplicates are allowed (creates separate records)

Configure this during import:

curl -X POST https://api.thinnest.ai/campaigns/contact-groups/group_123/import \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@contacts.csv" \
  -F "duplicate_strategy=update"

Cross-Group Deduplication

Contacts can exist in multiple groups without being duplicated in the database. The same contact record is linked to multiple groups. This means:

  • Updating a contact's info in one group updates it everywhere.
  • Unsubscribing a contact removes them from all future campaigns.
  • Contact-level metrics aggregate across all groups.

Batch Operations

Manage contacts in bulk from the dashboard or API.

Available Batch Operations

OperationDescription
DeleteRemove selected contacts from a group
MoveMove contacts to a different group
CopyCopy contacts to another group
TagAdd metadata tags to selected contacts
ExportDownload contacts as CSV

API Examples

Delete contacts from a group:

curl -X DELETE https://api.thinnest.ai/campaigns/contact-groups/group_123/contacts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_ids": ["contact_1", "contact_2", "contact_3"]
  }'

Move contacts to another group:

curl -X POST https://api.thinnest.ai/campaigns/contact-groups/group_123/move \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_ids": ["contact_1", "contact_2"],
    "target_group_id": "group_456"
  }'

Export contacts as CSV:

curl https://api.thinnest.ai/campaigns/contact-groups/group_123/export \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o contacts_export.csv

Contact-Level Logs and Metrics

Every interaction with a contact is logged. You can view the full history at the contact level.

Contact Activity Log

For each contact, you can see:

  • Campaigns received: Which campaigns reached this contact
  • Messages sent: Every SMS, email, or call made
  • Responses: The contact's replies and interactions
  • Status: Delivered, bounced, opted-out, etc.
  • Timestamps: When each event occurred

Viewing Contact History

From the Dashboard:

  1. Go to Campaigns > Contacts.
  2. Search for or select a contact.
  3. Click to open the contact detail view.
  4. The Activity tab shows the full interaction history.

Via the API:

curl https://api.thinnest.ai/campaigns/contacts/contact_123/activity \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "contact_id": "contact_123",
  "name": "Jane Smith",
  "total_campaigns": 5,
  "total_messages_sent": 12,
  "total_replies": 4,
  "last_contacted": "2026-03-01T14:30:00Z",
  "activity": [
    {
      "type": "sms_sent",
      "campaign": "Appointment Reminders",
      "message": "Hi Jane, your appointment is on March 15...",
      "timestamp": "2026-03-01T14:30:00Z",
      "status": "delivered"
    },
    {
      "type": "sms_received",
      "message": "CONFIRM",
      "timestamp": "2026-03-01T14:32:00Z"
    }
  ]
}

Contact Metrics

MetricDescription
ReachabilityPercentage of messages successfully delivered
Response RatePercentage of messages that received a reply
Average Response TimeHow quickly the contact typically responds
Last ContactedWhen the contact was last reached
Opt-Out StatusWhether the contact has opted out

Opt-Out Management

Contacts can opt out of future communications. thinnestAI handles this automatically:

  • SMS: Contacts who reply "STOP" are automatically opted out.
  • Email: Unsubscribe links are included in email campaigns.
  • Manual: You can mark contacts as opted out from the dashboard or API.

Opted-out contacts are skipped in all future campaigns. Attempting to add an opted-out contact to a campaign shows a warning.

Next Steps

  • Campaigns — Create your first outbound campaign.
  • Chat — Handle inbound conversations.
  • Billing — Understand the cost of campaigns.

On this page