# Brochures

> Create, change, renew, revoke and delete shareable brochures, and manage the listings in them, through the Fondaro API.

A brochure is a shareable page of up to 25 listings with its own link. Reading needs `brochures:read`; changing needs `brochures:write`. Creating a brochure, adding a listing, refreshing a listing and renewing also need `properties:read`, because they read the listings. Nothing is emailed: you share the link yourself.

- **A member** sees and changes only the brochures they created.
- **An admin** sees every brochure of the agency and may filter by creator.

A brochure you cannot reach answers `404` with "Brochure not found.", the same as one that does not exist. Brochures do not need an active plan.

## Keep within the daily allowance

Only listings from a property portal (the portals that property search lists, such as `idealista` and `rightmove`) are read from the portal when you create a brochure, add a listing, refresh a listing, or renew with `refreshListings`. Each of those reads counts toward your agency's daily allowance of 300, shared with the dashboard, the assistant and every other API key, counted from midnight UTC. Your own listings (`internal`) and the feeds your agency connects (`resales_online`, `zoddak`, `inmobalia`) do not count. Once it is used up, these routes answer `429` with `DAILY_LIMIT_REACHED` and nothing is created or changed. When a renewal re-reads several listings and some cannot be re-read, they come back in `failedRefreshes`.

## Choose the listings for a brochure

A listing is `{ "source", "id", "country" }`, exactly as property search returned it. `country` (`es`, `it` or `pt`) is only for sources that need one. Sources can be mixed in one brochure. Edit or remove a listing in a brochure with the **brochure-listing id** (`listings[].id`), not the source property id.

## List brochures

`GET /v1/brochures`

Brochures newest first, 20 per page at most. Each row has the share link, status, listing count and view count.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `page` | Query | integer | No | Page number, starting at 1 |
| `limit` | Query | integer | No | 1 to 20. Default 20 |
| `status` | Query | string | No | `active`, `expired`, `revoked` or `all` (the default) |
| `q` | Query | string | No | Starts-with match on the title, the recipient name or the link slug |
| `createdById` | Query | string | No | Admins only: only brochures made by this person |

```bash
curl "https://api.fondaro.com/v1/brochures?limit=2" \
  -H "Authorization: Bearer $FONDARO_API_KEY"
```

```json
{
  "data": [
    {
      "id": "3f6c2a10-0000-4000-8000-000000000011",
      "slug": "aB3dE5fG7hJ9kL1mN3pQ5r",
      "title": "R5379112",
      "recipientName": null,
      "status": "active",
      "creatorUserId": "user_2abcDEF1234567890ghiJKL",
      "showLocations": true,
      "listingCount": 2,
      "expiresAt": "2026-12-28T20:26:43.961Z",
      "viewCount": 0,
      "lastViewedAt": null,
      "createdAt": "2026-09-29T20:26:43.875Z",
      "publicUrl": "https://www.fondaro.com/b/aB3dE5fG7hJ9kL1mN3pQ5r"
    }
  ],
  "hasMore": true
}
```

Paging is by page number. `hasMore` says whether another page exists; `total` is present when it is known.

## Create a brochure

`POST /v1/brochures`

Creates a brochure from 1 to 25 listings. The share link works at once; map and image work may continue in the background. The agent card on the brochure defaults to the key's person. Needs `brochures:write` and `properties:read`. Accepts an `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `listings` | Body | object[] | Yes | 1 to 25 listings, each `{ "source", "id", "country" }` |
| `title` | Body | string | No | Up to 255 characters |
| `recipientName` | Body | string | No | Up to 255 characters |
| `recipientNote` | Body | string | No | Up to 4096 characters |
| `expiresInDays` | Body | integer | No | 1 to 365 |
| `showLocations` | Body | boolean | No | Whether the public page shows locations |
| `themeName` | Body | string | No | The brochure theme |
| `accentColorOverride` | Body | string | No | An accent colour |
| `agentUserId` | Body | string | No | The agent on the card, if not the key's person |
| `leadIds` | Body | integer[] | No | Leads to link the brochure to |

```bash
curl -X POST https://api.fondaro.com/v1/brochures \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Marbella shortlist", "listings": [{ "source": "internal", "id": "3f6c2a10-0000-4000-8000-000000000002" }] }'
```

The `201` response is the brochure:

```json
{
  "id": "3f6c2a10-0000-4000-8000-000000000005",
  "slug": "aB3dE5fG7hJ9kL1mN3pQ5r",
  "title": "Marbella shortlist",
  "status": "active",
  "showLocations": true,
  "expiresAt": "2027-01-02T12:04:41.450Z",
  "publicUrl": "https://www.fondaro.com/b/aB3dE5fG7hJ9kL1mN3pQ5r",
  "listings": [
    {
      "id": "3f6c2a10-0000-4000-8000-000000000003",
      "source": "internal",
      "sourceId": "3f6c2a10-0000-4000-8000-000000000002",
      "title": "R5208706 - Marbella",
      "ref": "R5208706",
      "price": 550000,
      "currency": "EUR",
      "coordinates": false,
      "images": 18
    }
  ]
}
```

Errors: `400` for a bad listing; `429` with `DAILY_LIMIT_REACHED` when the allowance is used up.

## Get a brochure

`GET /v1/brochures/{brochureId}`

One brochure with compact listing summaries and its share link.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |

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

```json
{
  "id": "3f6c2a10-0000-4000-8000-000000000005",
  "slug": "aB3dE5fG7hJ9kL1mN3pQ5r",
  "title": "Marbella shortlist",
  "recipientName": null,
  "recipientNote": null,
  "themeName": "default",
  "accentColorOverride": null,
  "showLocations": true,
  "status": "active",
  "expiresAt": "2027-01-02T12:04:41.450Z",
  "publicUrl": "https://www.fondaro.com/b/aB3dE5fG7hJ9kL1mN3pQ5r",
  "listings": [{ "id": "3f6c2a10-0000-4000-8000-000000000003", "source": "internal", "title": "R5208706 - Marbella", "price": 550000, "currency": "EUR", "images": 18 }]
}
```

Errors: `404` "Brochure not found."

## Update a brochure

`PATCH /v1/brochures/{brochureId}`

Changes the title, recipient fields, theme, accent colour, or whether locations show publicly. `null` clears a field that can be empty. Your agency's brochure branding locks apply to the look only.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |
| `title` | Body | string | No | Up to 255 characters |
| `recipientName` | Body | string or null | No | Up to 255 characters |
| `recipientNote` | Body | string or null | No | Up to 4096 characters |
| `themeName` | Body | string | No | The brochure theme |
| `accentColorOverride` | Body | string or null | No | An accent colour |
| `showLocations` | Body | boolean | No | Whether the public page shows locations |

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

The response is the brochure without its listings, with the new title.

## Add a listing to a brochure

`POST /v1/brochures/{brochureId}/listings`

Adds one listing, optionally at a zero-based `position`. A brochure holds at most 25. Needs `brochures:write` and `properties:read`. Accepts an `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |
| `source` | Body | string | Yes | The listing's source, exactly as property search returned it |
| `id` | Body | string | Yes | The listing's id at that source |
| `country` | Body | string | No | `es`, `it` or `pt`, when the source needs one |
| `position` | Body | integer | No | Zero-based position. Default: at the end |

The body is the listing itself, not a `listings` array.

```bash
curl -X POST https://api.fondaro.com/v1/brochures/3f6c2a10-0000-4000-8000-000000000005/listings \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "source": "internal", "id": "3f6c2a10-0000-4000-8000-000000000002" }'
```

The `201` response is `{ "brochureId": "...", "listing": { ... } }`, with the listing in the shape shown under Create a brochure. A body that is not a single listing answers `400` with `VALIDATION_FAILED` and the field paths in `details.issues`. Errors: `429` with `DAILY_LIMIT_REACHED`.

## Reorder a brochure's listings

`PUT /v1/brochures/{brochureId}/listings/order`

Replaces the display order. `listingIds` must be the complete set of the brochure's listing ids, in the new order; a partial list is refused.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |
| `listingIds` | Body | UUID[] | Yes | Every brochure-listing id, in the new order |

```bash
curl -X PUT https://api.fondaro.com/v1/brochures/3f6c2a10-0000-4000-8000-000000000005/listings/order \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "listingIds": ["3f6c2a10-0000-4000-8000-000000000003"] }'
```

```json
{
  "brochureId": "3f6c2a10-0000-4000-8000-000000000005",
  "order": [{ "listingId": "3f6c2a10-0000-4000-8000-000000000003", "position": 0 }]
}
```

## Refresh a brochure listing

`POST /v1/brochures/{brochureId}/listings/{listingId}/refresh`

Re-reads one listing from its source. Edits and hidden fields you set on the brochure are kept. Needs `brochures:write` and `properties:read`.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |
| `listingId` | Path | UUID | Yes | The brochure-listing id (`listings[].id`) |

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

The response is `{ "brochureId": "...", "listing": { ... } }` with the refreshed listing. Errors: `429` with `DAILY_LIMIT_REACHED` for a property site listing.

## Remove a listing from a brochure

`DELETE /v1/brochures/{brochureId}/listings/{listingId}`

Removes one listing by its brochure-listing id. The remaining positions close up.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |
| `listingId` | Path | UUID | Yes | The brochure-listing id (`listings[].id`) |

```bash
curl -X DELETE https://api.fondaro.com/v1/brochures/3f6c2a10-0000-4000-8000-000000000005/listings/3f6c2a10-0000-4000-8000-000000000003 \
  -H "Authorization: Bearer $FONDARO_API_KEY"
```

The response is `204` with no body.

## Revoke a brochure link

`POST /v1/brochures/{brochureId}/revoke`

Switches the share link off without deleting the brochure. The public page answers `410` until you renew it.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |

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

The response has `id`, `slug`, `publicUrl`, `expiresAt` and `"status": "revoked"`.

## Renew a brochure

`POST /v1/brochures/{brochureId}/renew`

Restores an expired or revoked brochure at the same link with a new expiry. With `refreshListings` it also re-reads every listing; any that could not be re-read come back in `failedRefreshes`. Needs `brochures:write` and `properties:read`.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |
| `expiresInDays` | Body | integer | No | 1 to 365 |
| `refreshListings` | Body | boolean | No | Re-read every listing from its source |

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

The response has `id`, `slug`, `publicUrl`, `expiresAt`, `"status": "active"` and `failedRefreshes`. Errors: `429` with `DAILY_LIMIT_REACHED` when `refreshListings` runs the allowance out.

## Delete a brochure

`DELETE /v1/brochures/{brochureId}`

Permanently deletes a brochure and its listings. To switch the link off and keep the brochure, revoke it instead.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `brochureId` | Path | UUID | Yes | The id of the brochure |

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

The response is `204` with no body.

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