<!-- Source: https://useworkloom.com/dev/lists/ · Workloom API v1 -->

# Lists

Lists of contacts, as your team uses them in Workloom. Add contacts to a static list and take them out; a smart list’s filter decides who is in it.

Scopes: `lists:read`, `lists:write`.

## The list object

- `id` (string, required): The list’s id.
- `name` (string, required): Its name.
- `description` (string, nullable, required): What it is for.
- `kind` (string, required): static: people are added and removed. smart: its filter decides, so it cannot be added to.
- `owner_seat_id` (string, nullable, required): Who owns it.
- `member_count` (integer, nullable, required): How many contacts are in it.
- `created_at` (timestamp, required): When it was made.

```json
{
  "id": "66ff8096e4b0a1b2c3d4dd01",
  "name": "Series B ops leaders",
  "description": null,
  "kind": "static",
  "owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
  "member_count": 42,
  "created_at": "2026-09-29T08:00:00.000Z"
}
```

## Endpoints

### List lists

`GET /lists`

Lists the key reaches: every list for a workspace key; for a key acting for one person, theirs and those shared with them.

Scope: `lists:read`

**Query parameters**

- `limit` (integer): How many to return, 1 to 100. Default 25.
- `cursor` (string): The `next_cursor` from the previous page.

**Request**

```bash
curl "https://api.useworkloom.com/api/public/v1/lists?limit=25" \
  -H "Authorization: Bearer $WORKLOOM_KEY"
```

```javascript
const res = await fetch("https://api.useworkloom.com/api/public/v1/lists?limit=25", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`
  }
});
const data = await res.json();
```

```python
import os, requests

res = requests.get(
    "https://api.useworkloom.com/api/public/v1/lists?limit=25",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
)
data = res.json()
```

**Response (sample, 200)**

```json
{
  "data": [
    {
      "id": "66ff8096e4b0a1b2c3d4dd01",
      "name": "Series B ops leaders",
      "description": null,
      "kind": "static",
      "owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
      "member_count": 42,
      "created_at": "2026-09-29T08:00:00.000Z"
    }
  ],
  "has_more": true,
  "next_cursor": "66ff8096e4b0a1b2c3d4dd01"
}
```

**Errors**

- 400: `invalid_request`, `unknown_fields`, `reason_required` or `unsupported_version`.
- 401: `authentication_required` or `invalid_key`.
- 403: `missing_scope`, `forbidden`, `seat_inactive` or `organisation_inactive`.
- 429: `rate_limited`. Wait `Retry-After` seconds.
- 500: `internal_error`.

### Get a list

`GET /lists/{id}`

Scope: `lists:read`

**Path parameters**

- `id` (string, required): The list’s id.

**Request**

```bash
curl "https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01" \
  -H "Authorization: Bearer $WORKLOOM_KEY"
```

```javascript
const res = await fetch("https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`
  }
});
const data = await res.json();
```

```python
import os, requests

res = requests.get(
    "https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
)
data = res.json()
```

**Response (sample, 200)**

```json
{
  "data": {
    "id": "66ff8096e4b0a1b2c3d4dd01",
    "name": "Series B ops leaders",
    "description": null,
    "kind": "static",
    "owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
    "member_count": 42,
    "created_at": "2026-09-29T08:00:00.000Z"
  }
}
```

**Errors**

- 400: `invalid_request`, `unknown_fields`, `reason_required` or `unsupported_version`.
- 401: `authentication_required` or `invalid_key`.
- 403: `missing_scope`, `forbidden`, `seat_inactive` or `organisation_inactive`.
- 404: `not_found`.
- 429: `rate_limited`. Wait `Retry-After` seconds.
- 500: `internal_error`.

### List who is in a list

`GET /lists/{id}/members`

The contacts in a list, oldest first, as contact objects. A smart list’s members are worked out from its filter when you ask.

Scope: `lists:read`

**Path parameters**

- `id` (string, required): The list’s id.

**Query parameters**

- `limit` (integer): How many to return, 1 to 100. Default 25.
- `cursor` (string): The `next_cursor` from the previous page.

**Request**

```bash
curl "https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members?limit=25" \
  -H "Authorization: Bearer $WORKLOOM_KEY"
```

```javascript
const res = await fetch("https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members?limit=25", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`
  }
});
const data = await res.json();
```

```python
import os, requests

res = requests.get(
    "https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members?limit=25",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
)
data = res.json()
```

**Response (sample, 200)**

```json
{
  "data": [
    {
      "id": "66f2a1c0e4b0a1b2c3d4e5f6",
      "first_name": "Priya",
      "last_name": "Nair",
      "full_name": "Priya Nair",
      "email": "priya@brightline.example",
      "phone": "+91 98200 11210",
      "title": "Head of Sales",
      "company_name": "Brightline",
      "company_domain": "brightline.example",
      "company_id": "66f19b77e4b0a1b2c3d4a1b2",
      "linkedin_url": "https://www.linkedin.com/in/priyanair",
      "location": {
        "city": "Bengaluru",
        "state": "Karnataka",
        "country": "India"
      },
      "owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
      "tags": [
        "ops-leaders",
        "series-b"
      ],
      "custom_fields": {
        "region": "South",
        "segment": "Mid-market"
      },
      "created_at": "2026-09-21T10:12:44.000Z",
      "updated_at": "2026-10-03T08:41:09.000Z"
    }
  ],
  "has_more": true,
  "next_cursor": "66f2a1c0e4b0a1b2c3d4e5f6"
}
```

**Errors**

- 400: `invalid_request`, `unknown_fields`, `reason_required` or `unsupported_version`.
- 401: `authentication_required` or `invalid_key`.
- 403: `missing_scope`, `forbidden`, `seat_inactive` or `organisation_inactive`.
- 404: `not_found`.
- 429: `rate_limited`. Wait `Retry-After` seconds.
- 500: `internal_error`.

### Add contacts to a list

`POST /lists/{id}/members`

Adds contacts to a static list the key owns, honouring the list’s rules (one per company, email required…). Every contact not added is listed with why.

Scope: `lists:write`

**Path parameters**

- `id` (string, required): The list’s id.

**Header parameters**

- `Idempotency-Key` (string): Any unique string, up to 255 characters. Send the same key when you retry and the request runs once; the first answer comes back with `Idempotent-Replayed: true`. Kept 24 hours.

**Body parameters**

- `contact_ids` (array of string, required): The contact ids, up to 500.

**Request**

```bash
curl -X POST "https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members" \
  -H "Authorization: Bearer $WORKLOOM_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "contact_ids": [
    "66f2a1c0e4b0a1b2c3d4e5f6",
    "66f2a1c0e4b0a1b2c3d4e600"
  ]
}'
```

```javascript
const res = await fetch("https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID()
  },
  body: JSON.stringify({
    "contact_ids": [
      "66f2a1c0e4b0a1b2c3d4e5f6",
      "66f2a1c0e4b0a1b2c3d4e600"
    ]
  })
});
const data = await res.json();
```

```python
import os, uuid, requests

res = requests.post(
    "https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "contact_ids": [
        "66f2a1c0e4b0a1b2c3d4e5f6",
        "66f2a1c0e4b0a1b2c3d4e600"
      ]
    },
)
data = res.json()
```

**Response (sample, 200)**

```json
{
  "data": {
    "added": 2,
    "already_in": 1,
    "skipped": [
      {
        "contact_id": "66f2a1c0e4b0a1b2c3d4e600",
        "reason": "No email address on file"
      }
    ],
    "not_found": []
  },
  "livemode": true
}
```

**Errors**

- 400: `invalid_request`, `unknown_fields`, `reason_required` or `unsupported_version`.
- 401: `authentication_required` or `invalid_key`.
- 403: `missing_scope`, `forbidden`, `seat_inactive` or `organisation_inactive`.
- 404: `not_found`.
- 409: `duplicate`, `conflict` or `idempotency_key_in_use`.
- 422: `idempotency_key_reused`.
- 429: `rate_limited`. Wait `Retry-After` seconds.
- 500: `internal_error`.

### Take contacts out of a list

`POST /lists/{id}/members/remove`

Removes contacts from a static list the key owns.

Scope: `lists:write`

**Path parameters**

- `id` (string, required): The list’s id.

**Body parameters**

- `contact_ids` (array of string, required): The contact ids, up to 500.

**Request**

```bash
curl -X POST "https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members/remove" \
  -H "Authorization: Bearer $WORKLOOM_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "contact_ids": [
    "66f2a1c0e4b0a1b2c3d4e5f6"
  ]
}'
```

```javascript
const res = await fetch("https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members/remove", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "contact_ids": [
      "66f2a1c0e4b0a1b2c3d4e5f6"
    ]
  })
});
const data = await res.json();
```

```python
import os, requests

res = requests.post(
    "https://api.useworkloom.com/api/public/v1/lists/66ff8096e4b0a1b2c3d4dd01/members/remove",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
    json={
      "contact_ids": [
        "66f2a1c0e4b0a1b2c3d4e5f6"
      ]
    },
)
data = res.json()
```

**Response (sample, 200)**

```json
{
  "data": {
    "removed": 1,
    "not_in_list": 0
  },
  "livemode": true
}
```

**Errors**

- 400: `invalid_request`, `unknown_fields`, `reason_required` or `unsupported_version`.
- 401: `authentication_required` or `invalid_key`.
- 403: `missing_scope`, `forbidden`, `seat_inactive` or `organisation_inactive`.
- 404: `not_found`.
- 409: `duplicate`, `conflict` or `idempotency_key_in_use`.
- 429: `rate_limited`. Wait `Retry-After` seconds.
- 500: `internal_error`.
