# Agents

> Read and update your organization's agent roster: the people shown on your listings, brochures and website.

The Agents API manages your organization's roster: the agent cards shown on your listings, brochures and website. A listing's `agentId` is an agent `id` from this roster.

These endpoints take a signed-in member's session token (`Authorization: Bearer <session-token>`); API keys do not open them. See [Authentication](https://www.fondaro.com/docs/api/authentication.md).

## How the roster works

- **Every member has a card.** Each member of your organization gets one agent card automatically when they join. Leaving deactivates it and keeps its data; rejoining reactivates it. A person in three organizations has three cards, one per organization.
- **Name and photo belong to the person.** On a member's card, `firstName`, `lastName` and the photo come from their Fondaro account. Changing them here changes the account, so it shows in every organization they belong to. Only an organization admin or the member themselves may do this.
- **Everything else belongs to the organization.** `title`, `displayEmail`, `phoneNumber`, `whatsappNumber`, `description`, `isActive` and `additionalInfo` are stored on this card only.
- **Standalone cards** are for someone without a Fondaro login, such as an outside collaborator. Your organization owns them entirely.
- **Agents are identified by `id`**, a UUID. It is the only agent identifier any endpoint accepts.

## The agent object

| Field | Type | Description |
|---|---|---|
| `id` | string | UUID |
| `organizationId` | string | UUID |
| `clerkUserId` | string or null | The member behind the card; `null` for a standalone card |
| `isClerkLinked` | boolean | `true` for a member's card |
| `firstName`, `lastName` | string or null | |
| `avatarUrl`, `avatarThumbnailUrl` | string or null | Photo and small photo |
| `displayEmail` | string or null | Public email on listings and brochures |
| `phoneNumber`, `whatsappNumber` | string or null | |
| `description` | string or null | Short biography |
| `title` | string or null | Job title |
| `isActive` | boolean | Inactive cards are hidden from listing pickers |
| `shareContactOnNetwork` | boolean | Show this card's email, phone and WhatsApp to other agencies on network listings |
| `additionalInfo` | object or null | Free-form data |
| `createdAt`, `updatedAt` | string | ISO 8601 |

Responses also carry `first_name`, `last_name` and `image_url`, older spellings of `firstName`, `lastName` and `avatarUrl`. Use the camelCase fields.

## List agents

`GET /agents`

Returns every card in your organization as an array.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `search` | Query, string | No | Case-insensitive match on name or email |

```bash
curl "https://api.fondaro.com/agents?search=ana" \
  -H "Authorization: Bearer $SESSION_TOKEN"
```

```json
[
  {
    "id": "6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b",
    "organizationId": "0b8e3f4a-1c2d-4e5f-8a9b-0c1d2e3f4a5b",
    "clerkUserId": "user_2abcDEF",
    "isClerkLinked": true,
    "firstName": "Ana",
    "lastName": "García",
    "avatarUrl": "https://…/avatar.jpg",
    "displayEmail": "ana@agency.example",
    "phoneNumber": "+34 600 000 000",
    "title": "Senior agent",
    "isActive": true,
    "shareContactOnNetwork": false
  }
]
```

## Get an agent

`GET /agents/:id`

Returns one card. An id from another organization answers `404`.

```bash
curl https://api.fondaro.com/agents/6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b \
  -H "Authorization: Bearer $SESSION_TOKEN"
```

```json
{ "id": "6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b", "firstName": "Ana", "lastName": "García", "title": "Senior agent", "isActive": true }
```

## Create a standalone agent

`POST /agents/standalone`

Creates a card for someone without a Fondaro login. Members get their card automatically, so there is no endpoint to create one for them.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `firstName` | Body, string | Yes | Up to 100 characters |
| `lastName` | Body, string | No | Up to 100 characters |
| `displayEmail` | Body, string | No | A valid email address |
| `phoneNumber` | Body, string | No | |
| `whatsappNumber` | Body, string | No | |
| `description` | Body, string | No | |
| `title` | Body, string | No | |
| `isActive` | Body, boolean | No | Default `true` |
| `additionalInfo` | Body, object | No | Free-form data |

```bash
curl -X POST https://api.fondaro.com/agents/standalone \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"firstName": "Miguel", "lastName": "Fernández", "displayEmail": "miguel@example.com", "title": "Independent agent"}'
```

```json
{ "id": "a1b2c3d4-5e6f-4a8b-9c0d-1e2f3a4b5c6d", "clerkUserId": null, "isClerkLinked": false, "firstName": "Miguel", "lastName": "Fernández", "isActive": true }
```

## Update an agent

`PUT /agents/:id`

Changes only the fields you send. On a member's card, `firstName`, `lastName`, `avatarUrl` and `shareContactOnNetwork` may be changed only by an admin or that member (`403` with `code: "ORG_ADMIN_OR_SELF_REQUIRED"` otherwise).

| Parameter | Type | Required | Description |
|---|---|---|---|
| `firstName`, `lastName` | Body, string | No | Up to 100 characters |
| `avatarUrl`, `avatarThumbnailUrl` | Body, string | No | Up to 500 characters |
| `displayEmail` | Body, string | No | A valid email address |
| `phoneNumber`, `whatsappNumber` | Body, string | No | |
| `description`, `title` | Body, string | No | |
| `isActive` | Body, boolean | No | |
| `shareContactOnNetwork` | Body, boolean | No | |
| `additionalInfo` | Body, object | No | |

```bash
curl -X PUT https://api.fondaro.com/agents/6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Sales director", "description": "Twelve years selling villas on the Golden Mile."}'
```

```json
{ "id": "6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b", "title": "Sales director", "description": "Twelve years selling villas on the Golden Mile." }
```

### Set the public contact address

`PUT /agents/:id/from-email`

Admins only. Sets `displayEmail`, or clears it with `null`. Email is still sent from the person's connected inbox, not this address.

```bash
curl -X PUT https://api.fondaro.com/agents/6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b/from-email \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"displayEmail": "ana@youragency.com"}'
```

```json
{ "id": "6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b", "displayEmail": "ana@youragency.com" }
```

## Upload or remove a photo

`POST /agents/:id/avatar`

Uploads a photo as `multipart/form-data` in the `avatar` field: JPEG, PNG, WebP or GIF, up to 5 MB. On a member's card the photo becomes their account photo (admins and the member only). Returns the updated agent.

```bash
curl -X POST https://api.fondaro.com/agents/6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b/avatar \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -F "avatar=@photo.jpg"
```

```json
{ "id": "6f1c2b3a-4d5e-4f60-8a7b-9c0d1e2f3a4b", "avatarUrl": "https://…", "avatarThumbnailUrl": "https://…" }
```

`DELETE /agents/:id/avatar` removes the photo and returns the updated agent.

## Deactivate an agent

`DELETE /agents/:id`

Sets the card to inactive (`isActive: false`). Its data stays, and listings that name it keep the reference.

```bash
curl -X DELETE https://api.fondaro.com/agents/a1b2c3d4-5e6f-4a8b-9c0d-1e2f3a4b5c6d \
  -H "Authorization: Bearer $SESSION_TOKEN"
```

```json
{ "success": true }
```

## Errors

| Status | When |
|---|---|
| `400` | Invalid field, an id that is not a UUID, or an invalid email |
| `401` | No session token, or an API key was sent |
| `403` | `ORG_ADMIN_OR_SELF_REQUIRED` on a member's name, photo or contact sharing; a member calling `from-email` |
| `404` | No such agent in your organization |
| `422` | Photo too large or not an accepted image type |

Source: https://www.fondaro.com/docs/api/agents/overview
