---
title: "Update a lead"
method: PATCH
path: "/v1/campaigns/{cid}/leads/{leadId}"
tags: ["Leads"]
---

# Update a lead

`PATCH /v1/campaigns/{cid}/leads/{leadId}`

## Request

- Base URL: `https://api.mailbeast.ai`
- URL: `https://api.mailbeast.ai/v1/campaigns/{cid}/leads/{leadId}`
- Auth: HTTP bearer

Update a lead’s fields, tags, custom fields, or status. The email address can only be changed while the lead has not been contacted yet. Reply-based statuses can only be set once the lead has replied.

Requires one of the following scopes: `leads:write`, `leads:all`, `all:all`.

## Path parameters

- `cid` string, uuid, required
- `leadId` string, uuid, required

## Headers

- `Idempotency-Key` string

## Request body

- UpdateLeadApiDto
  - `email` string: The email can only be changed while the lead has not been contacted yet.
  - `firstName` string
  - `lastName` string
  - `companyName` string
  - `jobTitle` string
  - `website` string
  - `linkedinProfile` string
  - `location` string
  - `tags` string[]
  - `customFields` object: Custom fields - each key must be lowercase letters, digits and underscores, starting with a letter, up to 64 characters (e.g. `fund_manager`); a key outside that form is rejected. The number of fields per campaign is capped, and each value is length-limited.
  - `customFieldLabels` object: Display labels for custom-field columns (applied on first definition).
  - `customFieldTypes` object: Data types for custom-field columns (text | url | number | date | image; applied on first definition).
  - `status` 'lead_replied_interested' | 'lead_replied_meeting_request' | 'lead_replied_out_of_office' | 'lead_replied_wrong_person' | 'lead_replied_not_interested' | 'lead_replied_unsubscribed' | 'lead_replied_uncategorized' | 'lead_converted' | 'lead_lost' | 'blacklisted': Only user-settable statuses are allowed; platform-managed ones such as `email_sent` or `scheduled` are rejected. Reply-based statuses (`lead_replied_*`, `lead_converted`) require the lead to have already replied. `lead_lost` and `blacklisted` can be set at any time.

## Response `200`

- LeadApiDto
  - `id` string, uuid, required
  - `email` string, required
  - `firstName` string, nullable
  - `lastName` string, nullable
  - `companyName` string, nullable
  - `jobTitle` string, nullable
  - `website` string, nullable
  - `linkedinProfile` string, nullable
  - `location` string, nullable
  - `tags` string[], required
  - `customFields` object, required
  - `status` 'not_contacted' | 'scheduled' | 'email_sent' | 'failed' | 'skipped' | 'lead_replied_interested' | 'lead_replied_meeting_request' | 'lead_replied_out_of_office' | 'lead_replied_bounce' | 'lead_replied_wrong_person' | 'lead_replied_not_interested' | 'lead_replied_unsubscribed' | 'lead_replied_uncategorized' | 'lead_converted' | 'lead_lost' | 'blacklisted', required
  - `verification` LeadVerificationView, required
    - `status` string, nullable
    - `subStatus` string, nullable
  - `provider` string, nullable
  - `metrics` LeadMetricsView, required
    - `sent` number, required: Emails sent to the lead (bounced emails included — they left our servers).
    - `opened` number, required: Emails the lead opened, counted once per email. Opens are approximate: Apple Mail and security scanners can add or hide opens.
    - `clicked` number, required: Emails in which the lead clicked a tracked link, counted once per email.
    - `replied` number, required
  - `sequenceProgress` LeadSequenceProgressView
    - `totalSteps` number, required
    - `sentCount` number, required
    - `plannedCount` number, required
    - `failedCount` number, required
    - `nextPlannedAt` string, date-time, nullable: When the next step is scheduled to send; null if none pending.
  - `createdAt` string, date-time, required
  - `lastContactedAt` string, date-time, nullable
  - `lastRepliedAt` string, date-time, nullable
  - `lastOpenedAt` string, date-time, nullable: Latest of the per-email first opens: when the lead first opened the newest email it opened. Re-opening an email does not move it; null if no email was opened.
  - `lastClickedAt` string, date-time, nullable: Latest of the per-email first clicks: when the lead first clicked a tracked link in the newest email it clicked. Repeat clicks do not move it; null if no tracked link was clicked.

## Other responses

- `400`: The request body or parameters failed validation.
- `401`: Missing or invalid API key.
- `403`: The key lacks a required scope, or the plan does not include API access.
- `404`: The resource does not exist in your workspace.
- `409`: The request conflicts with current state - e.g. a request with the same Idempotency-Key is still being processed, or the operation partially applied.
- `422`: The Idempotency-Key was already used with a different request body. Use a new key for a new operation.
- `429`: Rate limit exceeded - retry after the interval in the Retry-After header.

---

[API](https://skmtc.dev/mailbeast/apis/mailbeast-public-api.md) · [All operations](https://skmtc.dev/mailbeast/apis/mailbeast-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mailbeast/apis/mailbeast-public-api/revisions/6440ce0738a4?raw)
