---
title: "Convert a lead into a deal"
method: POST
path: "/api/v1/rest/crm/leads/{id}/convert"
tags: ["CRM"]
---

# Convert a lead into a deal

`POST /api/v1/rest/crm/leads/{id}/convert`

## Request

- Base URL: `https://api.custodo.ai`
- URL: `https://api.custodo.ai/api/v1/rest/crm/leads/{id}/convert`
- Auth: HTTP bearer

Turns a lead into a real opportunità: the same row, the same id, the same stage history and the same activities, now attached to an anagrafica and committed to a close date. The customer record must already exist — pass `party_id`, creating it with anagrafiche_create_party first — and `expected_close_date` is required, because committing to a date is what the conversion means. The lead’s own contact details are left exactly as they are and are never written back to the anagrafica. Most organisations do not use the lead inbox: if it is off here this tool refuses and names the setting that turns it on.

## Path parameters

- `id` string, uuid, required

## Headers

- `X-Tenant-Id` string, uuid

## Request body

- object
  - `party_id` string, uuid, required: The anagrafica the lead becomes attached to. It must already exist — create it with anagrafiche_create_party first, which owns the fiscal checks and the duplicate warning.
  - `contact_id` string, uuid: The person at that customer, when one is named.
  - `title` string: Rename it on the way through. Omit to keep the lead’s own title.
  - `stage_id` string, uuid: Move it as part of the conversion. Omit and it stays where it is; a terminal stage is refused, and so is a stage belonging to another pipeline.
  - `amount` number: The agreed figure, when one is now known.
  - `expected_close_date` string, required: When it is expected to close, YYYY-MM-DD. Required: committing to a date IS the commercial meaning of the conversion.
  - `owner_user_id` string, uuid: Hand it to a colleague as it converts. Omit to keep the lead’s owner.

## Response `200`

Done. `data` is the tool’s own answer.

- RestResult
  - `ok` true, required
  - `data` unknown, required

## Other responses

- `400`: The arguments did not validate: `error.message` names the field, what it expects and what arrived.
- `401`: No API key, or one that is malformed, unknown, revoked or expired.
- `403`: The call never ran: the module is off for this organisation, the credential lacks the permission or the module, the tier does not cover it, or the tool is destructive and the key was not minted for that.
- `404`: Nothing with that id in this organisation.
- `409`: The record is in a state that does not allow it — under legal hold, already sent, already closed. `error.code` says which.
- `422`: The tool ran and refused, in a sentence of its own (`TOOL_REFUSED`): the message says what to change. Retrying the same call will not help.
- `429`: The API key has spent its minute, or its day. Every request a key makes counts. See `Retry-After`.

---

[API](https://skmtc.dev/custodo/apis/custodo-integrazioni.md) · [All operations](https://skmtc.dev/custodo/apis/custodo-integrazioni/llms.txt) · [OpenAPI document](https://skmtc.dev/custodo/apis/custodo-integrazioni/revisions/16d336d3ec2a?raw)
