> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendora.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Leads

> Create, enrich, update, and track lead activity through the Sendora API.

## Overview

A **lead** is a contact record, a person your team is reaching out to. Leads live inside **lead lists**, which are collections used to organize contacts and enroll them into campaigns.

Every lead has:

* Core identity fields (`first_name`, `last_name`, `email`, `phone_number`, `linkedin_url`, `company`)
* Enrichment fields (`job_title`, `company_domain`, `company_size`, `location`, etc.)
* Status fields (`status`, `pipeline_stage`, `traffic_light_status`, `automation_paused`)
* A full activity timeline (calls, emails, SMS, LinkedIn, WhatsApp messages)

## Creating leads

```bash theme={"dark"}
curl -X POST https://api.sendora.ai/api/v1/public/leads \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Sarah",
    "last_name": "Chen",
    "email": "sarah@techcorp.io",
    "company": "TechCorp",
    "phone_number": "+14155550100",
    "linkedin_url": "https://linkedin.com/in/sarahchen",
    "job_title": "VP of Engineering"
  }'
```

Creating a lead without specifying a `lead_list_id` places the lead in the default list. To target a specific list:

```json theme={"dark"}
{
  "first_name": "Sarah",
  "email": "sarah@techcorp.io",
  "lead_list_id": "list_abc123"
}
```

## Listing and filtering leads

```bash theme={"dark"}
# All leads, newest first
GET /api/v1/public/leads

# Filter by pipeline stage
GET /api/v1/public/leads?pipeline_stage=engaged

# Filter by status
GET /api/v1/public/leads?status=active

# Search by name or company (partial match)
GET /api/v1/public/leads?search=techcorp
```

Valid `pipeline_stage` values: `new`, `contacted`, `engaged`, `meeting_booked`, `meeting_scheduled`, `proposal_sent`, `closed_won`, `closed_lost`

Valid `status` values: `active`, `unsubscribed`, `bounced`, `dnc`

Results are paginated. Use `page` and `per_page` to navigate:

| Param | Type | Default | Max |
| - | - | - | - |
| `page` | integer | `1` | , |
| `per_page` | integer | `50` | `100` |

The response envelope includes `total` so you can calculate the number of pages: `Math.ceil(total / per_page)`.

<Tip>
  All Sendora write operations are **idempotent**, submitting the same request twice produces the same result without side effects. Enrolling a lead who is already in a campaign returns `skipped: 1` rather than an error. Safe to retry on network failures.
</Tip>

## Updating pipeline stage

Move a lead forward (or back) in your sales pipeline:

```bash theme={"dark"}
curl -X PATCH "https://api.sendora.ai/api/v1/public/leads/{lead_id}/pipeline-stage" \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "stage": "meeting_booked" }'
```

This also fires internally within the campaign journey, the same action that moves a lead through the visual pipeline in the dashboard.

## Lead pipeline

Every lead moves through a sales pipeline. Stages advance automatically during campaign execution or can be set manually via the API.

```mermaid theme={"dark"}
flowchart LR
    new --> contacted
    contacted --> engaged
    engaged --> meeting_booked
    meeting_booked --> meeting_scheduled
    meeting_scheduled --> proposal_sent
    proposal_sent --> closed_won
    proposal_sent --> closed_lost
```

## Enriching a lead

Trigger the enrichment waterfall to fill in missing contact data:

```bash theme={"dark"}
curl -X POST "https://api.sendora.ai/api/v1/public/leads/{lead_id}/enrich" \
  -H "X-API-Key: sk_live_..."
```

Returns:

```json theme={"dark"}
{
  "success": true,
  "status": "completed",
  "fields_added": ["job_title", "company_domain", "company_size", "location"]
}
```

The enrichment waterfall tries the workspace's configured connected services in order and stops at the first successful result. The response reports the fields added and enrichment status, not the internal service used.

## Lead activity timeline

Get a full reverse-chronological history of everything that happened with a lead:

```bash theme={"dark"}
GET /api/v1/public/leads/{lead_id}/activities
```

Returns a mixed array of events:

```json theme={"dark"}
[
  {
    "id": "comm_xyz",
    "type": "sms",
    "date": "2026-06-20T14:32:00Z",
    "summary": "Outbound SMS message",
    "outcome": "delivered",
    "direction": "outbound"
  },
  {
    "id": "call_abc",
    "type": "voice",
    "date": "2026-06-18T10:15:00Z",
    "summary": "Voice call, 3m 42s",
    "outcome": "answered",
    "direction": "outbound",
    "duration_seconds": 222
  }
]
```

## Lead lists

Organize leads into lists for bulk operations:

```bash theme={"dark"}
# Create a list
POST /api/v1/public/lead-lists
{ "name": "Q3 Outbound, Enterprise" }

# Add leads to a list then enrich all at once
POST /api/v1/public/lead-lists/{list_id}/enrich
```

Bulk enrichment is async, it returns a `job_id` you can poll via `GET /api/v1/public/jobs/{job_id}`.

## DNC / unsubscribes

Leads with `status: "dnc"` or `status: "unsubscribed"` are never contacted. You can also manage the DNC list directly, see [DNC guide](/guides/dnc).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.