> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.sailorhq.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.sailorhq.io/_mcp/server.

# Smart Lists

> Create, configure, inspect, clone, and populate Sailor Smart Lists through the public API.

The Smart Lists API exposes the same dialing configuration used across Sailor. Every request is pinned to the one workspace encoded in the API key; organization and subaccount identifiers are never accepted from the caller.

Use a key with `smart_lists:read` to inspect lists and members, or `smart_lists:write` to create, update, clone, delete, and mutate membership.

## Create every supported configuration

```bash
curl https://api.sailorhq.io/smart-lists \
  -X POST \
  -H "Authorization: Bearer $SAILOR_API_TOKEN" \
  -H "Idempotency-Key: $SAILOR_REQUEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Fresh inbound leads",
    "description": "New demo requests called first",
    "priority": "highest",
    "max_attempts_per_day": 4,
    "max_attempts_total": 10,
    "min_retry_seconds": 2700,
    "dial_timeout_seconds": 30,
    "next_list_id": null
  }'
```

| Field                  | Behavior                                                                                                                                                                                                                          |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `priority`             | `highest`, `high`, `medium`, `low`, or `lowest`. Sailor drains the tiers in that order, using its durable deterministic cursor inside a tier. Every eligible listed contact is considered before contacts that are not in a list. |
| `max_attempts_per_day` | Per-contact, per-list daily cap. `null` means unlimited; `0` freezes dispatch.                                                                                                                                                    |
| `max_attempts_total`   | Per-contact, per-list lifetime cap. `null` means unlimited; `0` freezes dispatch.                                                                                                                                                 |
| `min_retry_seconds`    | Minimum time before the same list member is eligible again.                                                                                                                                                                       |
| `dial_timeout_seconds` | Ring timeout from 15 through 60 seconds in five-second increments.                                                                                                                                                                |
| `next_list_id`         | Same-workspace list that receives a member after the total-attempt rule completes. `null` clears the waterfall.                                                                                                                   |

`source`, creation timestamps, membership attempt counters, statuses, and dispositions are read-only evidence. They are owned by Sailor's ingest and scheduler, not writable configuration.

## Update, clone, and delete

`PATCH /smart-lists/{smartListId}` applies only the fields present in the JSON body. Send `null` for either cap to make it unlimited, or for `next_list_id` to clear the waterfall.

`POST /smart-lists/{smartListId}/clone` copies all dialing settings but no members. This avoids accidentally doubling a live dial pool. `DELETE /smart-lists/{smartListId}` deletes the list and its memberships; calls already in flight retain their immutable call snapshot.

## Add existing contacts

Batch operations accept 1–100 existing contacts. Identify each contact by Sailor `contact_id` or E.164 `phone`. Sailor resolves the reference only inside the API key's workspace and stores the canonical contact ID.

```bash
curl https://api.sailorhq.io/smart-lists/$SMART_LIST_ID/members/batch \
  -X POST \
  -H "Authorization: Bearer $SAILOR_API_TOKEN" \
  -H "Idempotency-Key: $SAILOR_REQUEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{"members":[{"contact_id":"00000000-0000-4000-8000-000000000010"},{"phone":"+14165550124"}]}'
```

The response reports `inserted`, `skipped`, and `unmatched` counts. An already-active membership is skipped. An ID or phone that does not resolve inside this workspace is unmatched; it never resolves from another tenant.

## Remove contacts

Use `POST /smart-lists/{smartListId}/members/batch-remove` to remove members from one list. Use `POST /smart-list-members/batch-remove` for the same contacts across every active list in this workspace. Both operations are atomic, accept 1–100 references, and return `removed`, `skipped`, and `unmatched` counts.

## Pagination and polling

`GET /smart-lists` and `GET /smart-lists/{smartListId}/members` use opaque cursor pagination. Pass `next_page_token` back as `page_token` without decoding or modifying it. Member reads may filter by `status` and expose the scheduler-owned attempt count, last attempt, last disposition, schedule time, and status reason.

Polling is safe, but prefer a bounded interval and respect `RateLimit`, `RateLimit-Policy`, and `Retry-After`. Reads are strongly tenant-scoped and do not accept `X-Active-Subaccount` as an override.

## Reliability rules

* Reuse one `Idempotency-Key` only for retries of the exact same logical write.
* A duplicate active list name returns `409 resource_conflict`.
* A missing or cross-workspace list returns a generic `404` or `400`; tenant existence is never disclosed.
* Batch removal is one database mutation, so a partial cross-list removal cannot leak through a worker crash.
* Priority traversal is restart-safe: the scheduler persists its cursor, resumes without reordering a tenant's queue, and reaches unlisted contacts only after every eligible listed tier has been traversed.
* [Kixie's PowerList API](https://support.kixie.com/hc/en-us/articles/19135310564635-PowerList-API) exposes contact add/update/remove operations. Sailor additionally exposes complete list resource CRUD, cloning, configuration, pagination, member state, bounded batches, durable idempotency, and least-privilege scopes.
* Sailor's five priorities, retry interval, daily and total attempt caps, next-list waterfall, and config-only clone are the Sailor equivalents informed by Kixie's [PowerList setup guide](https://support.kixie.com/hc/en-us/articles/4565589331483-How-to-Set-Up-PowerLists) and [Next Action guide](https://support.kixie.com/hc/en-us/articles/20406923205275-PowerList-Next-Action). Kixie also documents vendor-specific controls Sailor does not implement; Sailor never publishes fictional settings.

## Related

* [Authentication](/authentication)
* [Rate limits](/rate-limits)
* [Phone-system outcomes](/phone-system/outcomes)