---
title: "List warm leads and the people your agent found, best first"
method: GET
path: "/api/v1/leads"
---

# List warm leads and the people your agent found, best first

`GET /api/v1/leads`

## Request

- Base URL: `https://www.easeclaw.com`
- URL: `https://www.easeclaw.com/api/v1/leads`
- Auth: HTTP bearer

Two lists, each ordered by score descending, plus a summary counting both. `people` are the people the agent found for its outreach campaigns (name, title, company, score, why they fit, the drafted invitation and first message, and their state in the sequence); by default rejected, stopped and failed people are left out, and an explicit `state` reaches them. `leads` are post-leads: default view (no min_score) is post-leads scored >= 40 by buying intent PLUS all LinkedIn person-leads (commenters, surfaced from score 15 with a signal label). Post bodies are truncated to 500 chars in list results. Fetch a single lead or person for the full record. Read only.

## Query parameters

- `project_id` string, uuid
- `status` 'new' | 'saved' | 'dismissed' | 'contacted' | 'won' | 'lost'
- `min_score` integer
- `since` string, date-time
- `limit` integer
- `campaign_id` string, uuid
- `state` 'sourced' | 'qualified' | 'rejected' | 'awaiting_approval' | 'invite_approved' | 'invite_sent' | 'accepted' | 'dm_awaiting_approval' | 'dm_approved' | 'dm_sent' | 'done' | 'stale' | 'withdrawn' | 'stopped' | 'failed': Where one person stands in a campaign.

## Response `200`

Scored leads and the people the agent found

- object
  - `leads` Lead[]
    - `id` string, uuid
    - `project_id` string, uuid
    - `score` integer: buying-intent score; higher = hotter. Post-leads are always >= 40; LinkedIn person-leads surface from 15.
    - `reason` string, nullable: why the AI scored it this way
    - `signal` 'hand_raise' | 'question' | 'pain' | 'commented' | 'null', nullable: person-leads only (LinkedIn commenters): hand_raise | question | pain | commented; null on post-leads
    - `draft_reply` string, nullable: the drafted reply (person-leads: the LinkedIn connect note)
    - `draft_dm` string, nullable: person-leads only: the opener DM draft; null on post-leads
    - `draft_status` 'none' | 'generating' | 'ready'
    - `status` 'new' | 'saved' | 'dismissed' | 'contacted' | 'won' | 'lost'
    - `created_at` string, date-time
    - `match` object, nullable: the source post
      - `source` string, nullable
      - `permalink` string, nullable
      - `title` string, nullable
      - `body` string, nullable
      - `author` string, nullable
      - `posted_at` string, date-time, nullable
  - `people` AgentPerson[]
    - `id` string, uuid
    - `campaign_id` string, uuid
    - `campaign_name` string, nullable
    - `project_id` string, uuid, nullable
    - `state` 'sourced' | 'qualified' | 'rejected' | 'awaiting_approval' | 'invite_approved' | 'invite_sent' | 'accepted' | 'dm_awaiting_approval' | 'dm_approved' | 'dm_sent' | 'done' | 'stale' | 'withdrawn' | 'stopped' | 'failed': Where one person stands in a campaign.
    - `score` integer, nullable: fit score; higher = better fit
    - `intent_score` integer, nullable
    - `signal` string, nullable
    - `why` string, nullable: why the agent thinks they fit, the line the app shows
    - `name` string, nullable
    - `first_name` string, nullable
    - `headline` string, nullable
    - `company` string, nullable
    - `position` string, nullable
    - `location` string, nullable
    - `profile_url` string, nullable
    - `invite_note` string, nullable: the drafted connection note
    - `first_message` string, nullable: the drafted message for after they accept; null when the campaign's template applies
    - `invite_sent_at` string, date-time, nullable
    - `accepted_at` string, date-time, nullable
    - `replied_at` string, date-time, nullable
    - `meeting_at` string, date-time, nullable
    - `created_at` string, date-time
    - `locked` boolean: true on a trial account for a person the agent has not reached yet; their identifying fields are null
  - `summary` object
    - `leads` integer
    - `people` integer

## Other responses

- `400`: Error
- `401`: Error
- `402`: Error
- `404`: Error
- `429`: Rate limited (300/hour per account; drafting also 30/hour + daily AI budget). Retry-After header set when known.

---

[API](https://skmtc.dev/easeclaw/apis/easeclaw-api.md) · [All operations](https://skmtc.dev/easeclaw/apis/easeclaw-api/llms.txt) · [OpenAPI document](https://skmtc.dev/easeclaw/apis/easeclaw-api/revisions/79a190b20f61?raw)
