# Documents

> List folders and documents, write Markdown documents, share them by public link and attach them to leads through the Fondaro API.

Documents are your agency's library: written Markdown documents, PDFs and other files. Reading needs `documents:read`; creating, changing, sharing and attaching need `documents:write`.

**Every document route needs an active Fondaro plan.** Without one, even a read answers `403` with `SUBSCRIPTION_REQUIRED`.

- A document starts **private** to its creator and the agency's admins. Sharing it makes it visible to the whole agency and gives it a public link.
- Only a document's owner or an admin can change or share it. A private document someone else made stays invisible to you, even when it is attached to a lead you can reach: an attachment is not a grant.
- You can create and edit **Markdown** documents only. A PDF or other uploaded file is described by its metadata; the API never returns file bytes and does not upload files.

A document you cannot reach answers `404` with `NOT_FOUND`, the same as one that does not exist.

## List document folders

`GET /v1/document-folders`

Every folder of the library, with how many items you can see directly inside each. Pass a folder id as `folderId` to [list its documents](#list-documents).

```bash
curl https://api.fondaro.com/v1/document-folders \
  -H "Authorization: Bearer $FONDARO_API_KEY"
```

```json
{
  "data": [{ "id": "3f6c2a10-0000-4000-8000-000000000018", "name": "Test folder", "parentId": null, "documentCount": 1 }],
  "hasMore": false
}
```

## List documents

`GET /v1/documents`

Documents in the library, most recently changed first. Each row carries its public link while it is shared and live.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `limit` | Query | integer | No | 1 to 50. Default 20 |
| `offset` | Query | integer | No | Documents to skip. Continue with `nextOffset` |
| `q` | Query | string | No | Free-text match on the title, up to 128 characters |
| `kind` | Query | string | No | `markdown`, `pdf` or `file` |
| `visibility` | Query | string | No | `private`, `organization` or `public`. Only narrows what you can already see |
| `folderId` | Query | string | No | A folder id, or `root` for the top level. Omit for every document |
| `scope` | Query | string | No | `shared` (made by a colleague) or `pinned` |
| `mine` | Query | string | No | `true` for only the documents you created |
| `sort` | Query | string | No | `updated` (default), `title` or `size` |

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

```json
{
  "data": [
    {
      "id": "3f6c2a10-0000-4000-8000-000000000019",
      "title": "Untitled document",
      "kind": "markdown",
      "visibility": "private",
      "sizeBytes": null,
      "createdBy": "user_2abcDEF1234567890ghiJKL",
      "assigneeIds": [],
      "shareUrl": null,
      "attachedLeadCount": 0,
      "attachedListingCount": 0,
      "folderId": null,
      "createdAt": "2026-10-01T18:07:28.328Z",
      "updatedAt": "2026-10-01T18:07:28.328Z"
    }
  ],
  "hasMore": true,
  "nextOffset": 2,
  "total": 4
}
```

Paging is by offset, with an exact `total`.

## Create a Markdown document

`POST /v1/documents`

Creates a Markdown document in the library. It starts private. Accepts an `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `title` | Body | string | Yes | 1 to 200 characters |
| `body` | Body | string | Yes | GitHub Flavored Markdown, up to 1,000,000 characters |

```bash
curl -X POST https://api.fondaro.com/v1/documents \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Viewing checklist", "body": "# Checklist\n\nWritten through the Fondaro API." }'
```

The `201` response is the document:

```json
{
  "id": "3f6c2a10-0000-4000-8000-000000000007",
  "title": "Viewing checklist",
  "kind": "markdown",
  "visibility": "private",
  "createdBy": "user_2abcDEF1234567890ghiJKL",
  "shareUrl": null,
  "attachedLeadCount": 0,
  "folderId": null,
  "createdAt": "2026-10-04T12:02:29.454Z",
  "updatedAt": "2026-10-04T12:02:29.454Z",
  "body": "# Checklist\n\nWritten through the Fondaro API.",
  "truncated": false,
  "shareRevokedAt": null,
  "shareExpiresAt": null,
  "attachedLeadIds": [],
  "attachedListingIds": []
}
```

## Get a document

`GET /v1/documents/{documentId}`

One document: its metadata and, for a written document, the whole Markdown `body` (`truncated` is `false` here). An uploaded file comes back as metadata only.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `documentId` | Path | UUID | Yes | The id of the document |

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

The response is the document, in the shape shown above.

## Update a document

`PATCH /v1/documents/{documentId}`

Changes the title, the Markdown body, or both. The body replaces the whole document, so include everything that should stay. Only the owner or an admin can change it, and only a Markdown document has an editable body.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `documentId` | Path | UUID | Yes | The id of the document |
| `title` | Body | string | No | 1 to 200 characters |
| `body` | Body | string | No | Up to 1,000,000 characters |

```bash
curl -X PATCH https://api.fondaro.com/v1/documents/3f6c2a10-0000-4000-8000-000000000007 \
  -H "Authorization: Bearer $FONDARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "# Checklist\n\nEdited through the Fondaro API." }'
```

The response is the document with the new body and a later `updatedAt`.

## Share a document

`POST /v1/documents/{documentId}/share`

Publishes the document behind a public link that anyone holding the URL can open, and returns it as `shareUrl`. Sharing also makes the document visible to everyone in your agency. Sharing again while the link is live returns the same URL. Only the owner or an admin can share.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `documentId` | Path | UUID | Yes | The id of the document |
| `expiresAt` | Body | string | No | A future ISO 8601 time with `Z` or an offset. The link expires then |

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

The response is the document with `"visibility": "public"` and `shareUrl` set to a link such as `https://www.fondaro.com/d/aB3dE5fG7hJ9kL1mN3pQ5r`.

## Revoke a document's public link

`DELETE /v1/documents/{documentId}/share`

Takes the public link down: anyone holding the URL can no longer open it, and sharing again makes a different URL. The document stays in the library and stays visible to your agency; it does not become private again.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `documentId` | Path | UUID | Yes | The id of the document |

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

The response is `204` with no body.

## List a lead's documents

`GET /v1/leads/{leadId}/documents`

The documents attached to a lead, most recently attached first, with who attached each and when. At most 50, with no paging: `hasMore` is `true` when that limit was reached. You need access to the lead; a lead you cannot reach answers `404`.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `leadId` | Path | integer | Yes | The id of the lead |

```bash
curl https://api.fondaro.com/v1/leads/1042/documents \
  -H "Authorization: Bearer $FONDARO_API_KEY"
```

```json
{
  "data": [
    {
      "id": "3f6c2a10-0000-4000-8000-000000000007",
      "title": "Viewing checklist",
      "kind": "markdown",
      "visibility": "private",
      "sizeBytes": null,
      "createdBy": "user_2abcDEF1234567890ghiJKL",
      "attachedBy": "user_2abcDEF1234567890ghiJKL",
      "attachedAt": "2026-10-04T12:02:30.924Z",
      "updatedAt": "2026-10-04T12:02:30.356Z"
    }
  ],
  "hasMore": false
}
```

## Attach a document to a lead

`PUT /v1/leads/{leadId}/documents/{documentId}`

Records that the document belongs with the lead, so it shows on the lead and in its timeline. You need access to both. Attaching twice is harmless and keeps the first receipt. Needs `documents:write`.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `leadId` | Path | integer | Yes | The id of the lead |
| `documentId` | Path | UUID | Yes | The id of the document |

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

The response is the document with `attachedLeadCount` of 1 and the lead in `attachedLeadIds`.

## Detach a document from a lead

`DELETE /v1/leads/{leadId}/documents/{documentId}`

Removes the link between the document and the lead, and with it the receipt of who attached it. The document stays in the library. Detaching something already detached changes nothing.

| Parameter | In | Type | Required | Description |
|-----------|----|------|----------|-------------|
| `leadId` | Path | integer | Yes | The id of the lead |
| `documentId` | Path | UUID | Yes | The id of the document |

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

The response is `204` with no body.

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