# Deals

> List, read, create and update deals, move them through the pipeline stages, and close them as won or lost through the Fondaro API.

A deal is a sale or rental you are working on a lead. Reading needs `crm:read`; every change needs `crm:write` and an active plan.

- **A member** reaches only the deals they are assigned to. A deal that is not theirs answers `404` with "Deal not found.", the same as one that does not exist. Creating a deal on a lead needs access to that lead.
- **An admin** reaches every deal and may reassign owners.

Money fields (`amount`, `commissionAmount`, `commissionPercent`) come back as decimal strings. The pipeline stages are, in order, `qualified` (shown to people as Interested), `viewing`, `offer`, `reserved` and `under_contract`. A deal's `status` is `open`, `won` or `lost`. A deal's opening stage, stage moves and reopens made through the API are recorded in the deal's history with the source value `api`, shown in Fondaro as an API change. Marking a deal won or lost writes no history row. Owner changes made through the API are recorded with `api` too.

## List deals

`GET /v1/deals`

With `leadId`, every deal on that lead. Without it, up to 1,000 of the key's person's most recently active deals. An admin passes `assigneeIds` to read colleagues' deals. There is no paging: `hasMore` is `true` only when the 1,000-row limit cut the results, so narrow with filters.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `leadId` | Query | integer | No | Every deal on this lead. You need access to it |
| `status` | Query | string | No | `open`, `won` or `lost` |
| `stage` | Query | string | No | One stage. Meaningful when `status` is `open` |
| `stages` | Query | string[] | No | Any of these stages. Ignored when `leadId` is set |
| `q` | Query | string | No | Up to 200 characters, matched against the deal title and the lead's name or email |
| `assigneeIds` | Query | string or string[] | No | Admins only: read these people's deals |
| `propertyListingId` | Query | UUID | No | Deals tied to this listing |
| `amountMin`, `amountMax` | Query | number | No | Compared in each deal's own currency, with no conversion |
| `expectedCloseFrom`, `expectedCloseTo` | Query | string | No | ISO date or date-time. A plain date includes that whole day (UTC) |
| `createdFrom`, `createdTo` | Query | string | No | ISO date or date-time |
| `closedFrom`, `closedTo` | Query | string | No | ISO date or date-time. Uses `wonAt` for won deals and `lostAt` for lost ones |
| `collectionState` | Query | string | No | `invoiced_not_collected` or `collected` |

```bash
curl "https://api.fondaro.com/v1/deals?leadId=1042" \
  -H "Authorization: Bearer $FONDARO_API_KEY"
```

```json
{
  "data": [
    {
      "id": "3f6c2a10-0000-4000-8000-000000000010",
      "leadId": 1042,
      "assigneeIds": ["user_2abcDEF1234567890ghiJKL"],
      "title": "Villa in Marbella",
      "status": "open",
      "stage": "qualified",
      "amount": null,
      "currency": "EUR",
      "propertyListingId": null,
      "expectedCloseAt": null,
      "wonAt": null,
      "lostAt": null,
      "stageChangedAt": "2026-10-04T12:02:16.228Z",
      "createdAt": "2026-10-04T12:02:16.730Z",
      "updatedAt": "2026-10-04T12:02:16.730Z",
      "participants": []
    }
  ],
  "hasMore": false
}
```

## Get a deal

`GET /v1/deals/{dealId}`

One deal with its commission participants.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `dealId` | Path | UUID | Yes | The id of the deal |

```bash
curl https://api.fondaro.com/v1/deals/3f6c2a10-0000-4000-8000-000000000010 \
  -H "Authorization: Bearer $FONDARO_API_KEY"
```

The response is the deal, in the shape shown above. Errors: `404` "Deal not found."

## Create a deal

`POST /v1/deals`

Creates a deal on a lead. The stage defaults to the first stage, `qualified`. Accepts an `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `leadId` | Body | integer | Yes | The lead. A member must have access to it |
| `title` | Body | string | Yes | The deal title |
| `amount` | Body | number | No | 0 or more |
| `stage` | Body | string | No | One of the five stages |
| `expectedCloseAt` | Body | string | No | `YYYY-MM-DD` or an ISO 8601 timestamp |
| `propertyListingId` | Body | UUID | No | A listing the deal is about |
| `assigneeIds` | Body | string or string[] | No | Owners other than the key's person |
| `teamIds` | Body | UUID or UUID[] | No | Teams to assign |

```bash
curl -X POST https://api.fondaro.com/v1/deals \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "leadId": 1042, "title": "Villa in Marbella" }'
```

The `201` response is the deal. Errors: `404` "Lead not found." for a lead you cannot reach.

## Update a deal

`PATCH /v1/deals/{dealId}`

Changes the title, amount, listing link, expected close date, commission, invoice and collection fields, or the owner (admin only). It does not change the stage or status: use the stage, won, lost and reopen routes.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `dealId` | Path | UUID | Yes | The id of the deal |
| `title` | Body | string | No | New title |
| `amount` | Body | number | No | 0 or more |
| `propertyListingId` | Body | UUID | No | The listing the deal is about |
| `expectedCloseAt` | Body | string | No | `YYYY-MM-DD` or an ISO 8601 timestamp |
| `commissionMode` | Body | string | No | `exact` or `percentage` |
| `commissionAmount` | Body | number | No | 0 or more |
| `commissionPercent` | Body | number | No | 0 to 100 |
| `invoiceNumber` | Body | string | No | Up to 255 characters |
| `estimatedCollectionAt`, `collectedAt` | Body | string | No | `YYYY-MM-DD` or an ISO 8601 timestamp |
| `assigneeIds`, `teamIds` | Body | string or string[] | No | Admins only |

```bash
curl -X PATCH https://api.fondaro.com/v1/deals/3f6c2a10-0000-4000-8000-000000000010 \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Villa in Marbella, edited" }'
```

The response is the deal with the new values.

## Change a deal stage

`PUT /v1/deals/{dealId}/stage`

Moves a deal to another stage. If the deal is won or lost, this reopens it into the new stage.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `dealId` | Path | UUID | Yes | The id of the deal |
| `stage` | Body | string | Yes | `qualified`, `viewing`, `offer`, `reserved` or `under_contract` |

```bash
curl -X PUT https://api.fondaro.com/v1/deals/3f6c2a10-0000-4000-8000-000000000010/stage \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "stage": "viewing" }'
```

The response is the deal with `"stage": "viewing"` and a new `stageChangedAt`.

## Close a deal as won

`POST /v1/deals/{dealId}/won`

Marks the deal won and records `wonAt`. Any lost fields are cleared.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `dealId` | Path | UUID | Yes | The id of the deal |
| `wonAt` | Body | string | No | `YYYY-MM-DD` or an ISO 8601 timestamp. Now when omitted |

```bash
curl -X POST https://api.fondaro.com/v1/deals/3f6c2a10-0000-4000-8000-000000000010/won \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

The response is the deal with `"status": "won"` and `wonAt` set.

## Close a deal as lost

`POST /v1/deals/{dealId}/lost`

Marks the deal lost, with an optional reason. Any won fields are cleared.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `dealId` | Path | UUID | Yes | The id of the deal |
| `lostReason` | Body | string | No | Up to 2000 characters |
| `lostAt` | Body | string | No | `YYYY-MM-DD` or an ISO 8601 timestamp. Now when omitted |

```bash
curl -X POST https://api.fondaro.com/v1/deals/3f6c2a10-0000-4000-8000-000000000010/lost \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

The response is the deal with `"status": "lost"`, `lostAt` set, and `lostReason` (null here, as none was sent).

## Reopen a deal

`POST /v1/deals/{dealId}/reopen`

Reopens a won or lost deal into the stage you name, or into its previous stage when you omit it.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `dealId` | Path | UUID | Yes | The id of the deal |
| `stage` | Body | string | No | The stage to reopen into |

```bash
curl -X POST https://api.fondaro.com/v1/deals/3f6c2a10-0000-4000-8000-000000000010/reopen \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

The response is the deal with `"status": "open"` and its stage.

Source: https://www.fondaro.com/docs/api/v1/deals
