Leads

Add leads in bulk (up to 1,000 per request), read, update and delete them, and read a lead's conversation.

List leads

get https://api.emailchaser.com/r/leads
Works with a read-only key

Lists the leads in the API key's workspace, newest first, with pagination. Filter by exact email address to look up a single lead, or by campaign to list only the leads in one campaign. This is how a lead created through POST /leads is found again.

  • page integer in query

    Page number (default: 1)

  • limit integer in query

    Page size (default: 20, maximum: 200)

  • email string in query

    Filter by exact email address

  • campaignId integer in query

    Filter by campaign ID

Fields in the 200 response
  • hasMore boolean
    Example: true
  • leads array of LeadResponse
    15 fields inside leads
    • company string
      Example: Acme Corp
    • createdAt string
      Example: 2024-01-15T10:30:00Z
    • customVariables map of object

      CustomVariables are the lead's merge tags beyond the named fields.

    • email string
      Example: john.doe@example.com
    • firstName string
      Example: John
    • id integer
      Example: 123
    • lastName string
      Example: Doe
    • linkedin string
      Example: https://linkedin.com/in/johndoe
    • meetingBookedAt string

      MeetingBookedAt is when a meeting was explicitly marked as booked with this lead (see POST /leads/{id}/meeting) and null while no meeting is marked.

      Example: 2026-07-30T14:05:00Z
    • middleName string
      Example: A.
    • phone string
      Example: +1234567890
    • tag string

      Tag is the lead's engagement category (interested, not_interested, bounced, out_of_office, delivery_incomplete, meeting_booked) and null while the lead has never been categorized.

      Example: interested
    • title string
      Example: Software Engineer
    • updatedAt string
      Example: 2024-01-15T10:30:00Z
    • website string
      Example: https://example.com
  • limit integer
    Example: 20
  • page integer
    Example: 1
  • total integer
    Example: 42

Request

curl -X GET "https://api.emailchaser.com/r/leads" \
  -H "Authorization: Bearer $EMAILCHASER_API_KEY"

Response

{
  "hasMore": true,
  "leads": [
    {
      "company": "Acme Corp",
      "createdAt": "2024-01-15T10:30:00Z",
      "customVariables": {},
      "email": "john.doe@example.com",
      "firstName": "John",
      "id": 123,
      "lastName": "Doe",
      "linkedin": "https://linkedin.com/in/johndoe",
      "meetingBookedAt": "2026-07-30T14:05:00Z",
      "middleName": "A.",
      "phone": "+1234567890",
      "tag": "interested",
      "title": "Software Engineer",
      "updatedAt": "2024-01-15T10:30:00Z",
      "website": "https://example.com"
    }
  ],
  "limit": 20,
  "page": 1,
  "total": 42
}

Create or update leads in bulk

post https://api.emailchaser.com/r/leads

Creates or updates up to 1,000 leads in one request. Leads are matched by email within the workspace. If a lead with that email already exists, it is updated, and every named field you leave out is cleared, so send the full lead each time. An update also clears the lead's city, country, industry and company description, which the API cannot set. middleName is only saved when a lead is created. customVariables, when sent, replaces the lead's variables; leave it out to keep them. Every lead needs a valid email: one invalid lead fails the whole request with 400, and nothing is saved. To add the leads to a campaign, pass campaignId at the top level of the request body, not inside a lead. The campaign must have at least one email account attached (POST /campaigns/{id}/sender-emails). If it has none, the leads are saved and added to the campaign, but the call fails with 500; attach an account and send the same request again. count in the response is the number of leads you sent, not the number created. Any attribute outside the named fields can be sent in customVariables and becomes a merge tag usable in email copy. PUT /leads is an alias for this endpoint and behaves identically.

  • campaignId integer
  • leads array of LeadInput required
    At least 1 item. At most 1,000 items
    10 fields inside leads
    • company string
    • customVariables map of object

      CustomVariables holds any attribute the eight named fields do not cover, for example the page a visitor landed on. Each key becomes a merge tag usable in email copy as {key}. Keys are matched case-insensitively with spaces treated as underscores, so "Page Visited" and "page_visited" are the same tag. Values are stored as given; non-string values are rendered with their JSON representation at send time.

    • email string required
    • firstName string
    • lastName string
    • linkedin string
    • middleName string

      Saved when the lead is created. Not changed when a lead with this email already exists.

    • phone string
    • title string
    • website string
Fields in the 201 response
  • count integer
    Example: 5
  • leads array of CreatedLead
    2 fields inside leads
    • email string
      Example: john.doe@example.com
    • id integer
      Example: 123
  • message string
    Example: leads processed successfully

Request

curl -X POST "https://api.emailchaser.com/r/leads" \
  -H "Authorization: Bearer $EMAILCHASER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "campaignId": 123,
  "leads": [
    {
      "company": "Acme",
      "customVariables": {},
      "email": "jane@acme.com",
      "firstName": "Jane",
      "lastName": "Doe",
      "linkedin": "https://www.linkedin.com/in/janedoe",
      "middleName": "",
      "phone": "+1 415 555 0100",
      "title": "Head of Sales",
      "website": "https://acme.com"
    }
  ]
}'

Response

{
  "count": 5,
  "leads": [
    {
      "email": "john.doe@example.com",
      "id": 123
    }
  ],
  "message": "leads processed successfully"
}

Get a lead by ID

get https://api.emailchaser.com/r/leads/{id}
Works with a read-only key

Retrieves one lead. The lead comes back as a flat object, not wrapped in a "lead" key. It has no middleName; GET /leads includes it.

  • id integer required in path

    Lead ID

Fields in the 200 response
  • company string
    Example: Acme Corp
  • createdAt string
    Example: 2024-01-15T10:30:00Z
  • customVariables map of object

    CustomVariables are the lead's merge tags beyond the named fields. Always present; null or empty when the lead has none.

  • email string
    Example: john.doe@example.com
  • firstName string
    Example: John
  • id integer
    Example: 123
  • lastName string
    Example: Doe
  • linkedin string
    Example: https://linkedin.com/in/johndoe
  • meetingBookedAt string

    MeetingBookedAt is when a meeting was explicitly marked as booked with this lead (see POST /leads/{id}/meeting) and null while no meeting is marked.

    Example: 2026-07-30T14:05:00Z
  • phone string
    Example: +1234567890
  • tag string

    Tag is the lead's engagement category (interested, not_interested, bounced, out_of_office, delivery_incomplete, meeting_booked) and null while the lead has never been categorized.

    Example: interested
  • title string
    Example: Software Engineer
  • updatedAt string
    Example: 2024-01-15T10:30:00Z
  • website string
    Example: https://example.com

Request

curl -X GET "https://api.emailchaser.com/r/leads/123" \
  -H "Authorization: Bearer $EMAILCHASER_API_KEY"

Response

{
  "company": "Acme Corp",
  "createdAt": "2024-01-15T10:30:00Z",
  "customVariables": {},
  "email": "john.doe@example.com",
  "firstName": "John",
  "id": 123,
  "lastName": "Doe",
  "linkedin": "https://linkedin.com/in/johndoe",
  "meetingBookedAt": "2026-07-30T14:05:00Z",
  "phone": "+1234567890",
  "tag": "interested",
  "title": "Software Engineer",
  "updatedAt": "2024-01-15T10:30:00Z",
  "website": "https://example.com"
}

Update a lead by ID

put https://api.emailchaser.com/r/leads/{id}

Updates one lead. What happens depends on whether the lead is in a campaign. For a lead in no campaign, only the fields you send are changed, and customVariables, when sent, replaces the whole set. For a lead in a campaign, the lead is saved again from your request: every named field you leave out is cleared, so send the full lead each time. This also clears the lead's city, country, industry and company description, which the API cannot set. customVariables is kept if you leave it out. Sending a different email does not change this lead: it creates a lead with the new email in the same campaign, or overwrites the lead that already has that email, and this lead stays as it was. middleName is accepted but never saved. The response holds only the lead's id, email, firstName and lastName, plus customVariables for a lead in no campaign. Read the full lead with GET /leads/{id}.

  • id integer required in path

    Lead ID

  • company string
  • customVariables map of object

    CustomVariables replaces the lead's whole custom variable map when provided. Omit it to leave the existing variables untouched.

  • email string

    For a lead in a campaign, a different email does not change this lead: it creates a lead with the new email in the same campaign, or overwrites the lead that already has it.

  • firstName string
  • lastName string
  • linkedin string
  • middleName string

    Accepted but never saved by this endpoint.

  • phone string
  • title string
  • website string
Fields in the 200 response
  • 5 fields inside lead
    • customVariables map of object

      CustomVariables is returned only for a lead in no campaign.

    • email string
      Example: john.doe@example.com
    • firstName string
      Example: John
    • id integer
      Example: 123
    • lastName string
      Example: Doe
  • message string
    Example: lead updated successfully

Request

curl -X PUT "https://api.emailchaser.com/r/leads/123" \
  -H "Authorization: Bearer $EMAILCHASER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "company": "Acme",
  "customVariables": {},
  "email": "jane@acme.com",
  "firstName": "Jane",
  "lastName": "Doe",
  "linkedin": "https://www.linkedin.com/in/janedoe",
  "middleName": "",
  "phone": "+1 415 555 0100",
  "title": "Head of Sales",
  "website": "https://acme.com"
}'

Response

{
  "lead": {
    "customVariables": {},
    "email": "john.doe@example.com",
    "firstName": "John",
    "id": 123,
    "lastName": "Doe"
  },
  "message": "lead updated successfully"
}

Delete a lead by ID

delete https://api.emailchaser.com/r/leads/{id}

Deletes a lead and all associated unsent emails. If the lead is associated with campaigns, it will be removed from those campaigns first.

  • id integer required in path

    Lead ID

Fields in the 200 response
  • id integer
    Example: 123
  • message string
    Example: lead deleted successfully

Request

curl -X DELETE "https://api.emailchaser.com/r/leads/123" \
  -H "Authorization: Bearer $EMAILCHASER_API_KEY"

Response

{
  "id": 123,
  "message": "lead deleted successfully"
}

Set or correct a lead's category

put https://api.emailchaser.com/r/leads/{id}/category

Sets the lead's category (tag), typically to correct an AI misclassification of a reply. Validated against the category enum: interested, not_interested, bounced, out_of_office, delivery_incomplete, meeting_booked. Setting meeting_booked behaves exactly like POST /leads/{id}/meeting: it records meetingBookedAt when unset and keeps an existing one, because a meeting is an explicit mark set by you or your agent, never inferred by the system. A real category change fires the LeadCategoryUpdate webhook; setting the value the lead already has is a no-op. Changing the category away from meeting_booked does NOT clear the booked-meeting mark - use DELETE /leads/{id}/meeting for that.

  • id integer required in path

    Lead ID

  • category string required

    Category must be one of the lead category values: interested, not_interested, bounced, out_of_office, delivery_incomplete, meeting_booked.

    Example: interested
Fields in the 200 response
  • 3 fields inside lead
    • id integer
      Example: 123
    • meetingBookedAt string

      MeetingBookedAt is when the meeting was marked as booked and null while no meeting is marked.

      Example: 2026-07-30T14:05:00Z
    • tag string

      Tag is the lead's engagement category and null while the lead has never been categorized.

      Example: meeting_booked
  • message string
    Example: lead category updated successfully

Request

curl -X PUT "https://api.emailchaser.com/r/leads/123/category" \
  -H "Authorization: Bearer $EMAILCHASER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "category": "interested"
}'

Response

{
  "lead": {
    "id": 123,
    "meetingBookedAt": "2026-07-30T14:05:00Z",
    "tag": "meeting_booked"
  },
  "message": "lead category updated successfully"
}

Generated from the Emailchaser API's own OpenAPI definition, so it always matches the running API.