# List agents

Source: https://help.ruuster.com/api/agents-list

```http
GET https://api.ruuster.com/v1/agents
```

Your brokerage's agent directory with each agent's landing page. No activity figures.

- Authentication: `x-api-key` and `x-email` headers of an owner or admin
- Rate limit: 120 requests per minute per key

## Query parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `status` | string | `active` | `active`, `removed` (agents who left) or `all` |
| `cursor` | string | | `meta.nextCursor` from the previous page. Omit for the first page |
| `limit` | integer | `100` | Rows per page, 1 to 500 |
| `countOnly` | `0` \| `1` | `0` | `1` returns `{ "total": n }` and no rows |

Removed agents stay listed (with `status=removed` or `all`) so the `agentId` on older leads can still be resolved.

## Response

`data.agents` is a list of agent objects; `meta.total` and `meta.nextCursor` page through them.

## Agent object

| Field | Description |
|---|---|
| `agentId` | Same id as `agentId` on leads |
| `firstName`, `lastName`, `email`, `phone` | Contact details from the agent's Ruuster profile |
| `photoUrl` | Profile photo, when set |
| `role` | `owner`, `admin` or `agent` |
| `landingPageUrl` | The agent's page on your Ruuster site, for example `https://saguaro.ruuster.com/agent/jane-doe` |
| `mlsAgentIds`, `mlsOfficeIds` | The MLS ids on the agent's profile. Listings are attributed to your brokerage through these |
| `status` | `active` or `removed` |
| `createdAt`, `removedAt` | When the agent joined Ruuster; for a removed agent, the last change to their profile (usually the removal) |

## Example request

cURL:

```bash
curl -s "https://api.ruuster.com/v1/agents?status=active&limit=2" \
  -H "x-api-key: $RUUSTER_API_KEY" \
  -H "x-email: $RUUSTER_EMAIL"
```

Node.js:

```javascript
const res = await fetch("https://api.ruuster.com/v1/agents?status=active&limit=2", {
  headers: {
    "x-api-key": process.env.RUUSTER_API_KEY,
    "x-email": process.env.RUUSTER_EMAIL,
  },
});
const body = await res.json();
if (!body.ok) throw new Error(`${body.error.code}: ${body.error.message} (${body.requestId})`);
console.log(body.data);
```

Python:

```python
import os
import requests

res = requests.get(
    "https://api.ruuster.com/v1/agents?status=active&limit=2",
    headers={"x-api-key": os.environ["RUUSTER_API_KEY"], "x-email": os.environ["RUUSTER_EMAIL"]},
    timeout=30,
)
body = res.json()
if not body["ok"]:
    raise RuntimeError(f'{body["error"]["code"]}: {body["error"]["message"]} ({body.get("requestId")})')
print(body["data"])
```

## Example response

```json
{
  "ok": true,
  "data": {
    "agents": [
      { "agentId": "7c1e9b42-3d85-4a6f-9e07-1b2c8d4f5a69",
        "firstName": "Jane", "lastName": "Doe", "email": "jane@saguarorealty.com", "phone": "+15205550101",
        "photoUrl": "https://cdn.example.com/agents/jane-doe.jpg", "role": "admin",
        "landingPageUrl": "https://saguaro.ruuster.com/agent/jane-doe",
        "mlsAgentIds": ["28301"], "mlsOfficeIds": ["333802"],
        "status": "active", "createdAt": "2023-11-02T16:40:00Z", "removedAt": null },
      { "agentId": "e5a7d3c1-9b46-4f28-8c0e-6d2a1f7b3e95",
        "firstName": "Marco", "lastName": "Ruiz", "email": "marco@saguarorealty.com", "phone": "+15205550134",
        "photoUrl": null, "role": "agent",
        "landingPageUrl": "https://saguaro.ruuster.com/agent/marco-ruiz",
        "mlsAgentIds": ["31877"], "mlsOfficeIds": [],
        "status": "active", "createdAt": "2024-03-18T19:05:00Z", "removedAt": null }
    ]
  },
  "meta": { "brokerageId": "4f6c2a9e-8d31-4b57-9a0e-2c7d5e1b8f43", "total": 18, "nextCursor": "cur_Bq7Hc2Pq7Lm3XvT8wR" }
}
```
