> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowsbuilt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# atRisk()

> Paginate all users above a churn risk threshold.

## Overview

`atRisk()` returns a paginated list of users whose churn risk score exceeds a given threshold. Use it for bulk outreach campaigns, CS dashboards, or nightly reports.

For streaming all at-risk users without pagination management, see [atRiskAll()](/churnkit/risk/at-risk-all).

## Signature

```typescript theme={null}
churn.atRisk(options?: AtRiskOptions): Promise<AtRiskResult>
```

## AtRiskOptions

<ParamField path="threshold" type="number">
  Minimum score to include (0–1). Default: `0.5`. Must be a finite number between 0 and 1.
</ParamField>

<ParamField path="plan" type="string">
  Filter to users on a specific plan (e.g. `'pro'`, `'enterprise'`). Requires `plan` to have been set via `identify()`.
</ParamField>

<ParamField path="limit" type="number">
  Page size. Default: `50`. Maximum: `200`.
</ParamField>

<ParamField path="offset" type="number">
  Pagination offset. Default: `0`.
</ParamField>

<ParamField path="options.signal" type="AbortSignal">
  Cancel the request.
</ParamField>

## AtRiskResult

```typescript theme={null}
interface AtRiskResult {
  users: AtRiskUser[]
  total: number    // total matching users (across all pages)
  offset: number
  limit: number
}

interface AtRiskUser {
  userId: string
  score: number
  tier: RiskTier
  signals: string[]
  recommendation: string
}
```

## Examples

### Get high-risk users

```typescript theme={null}
const { users, total } = await churn.atRisk({ threshold: 0.7 })

console.log(`${total} high-risk users`)
for (const user of users) {
  console.log(user.userId, user.score, user.signals)
}
```

### Filter by plan

```typescript theme={null}
// Only enterprise users above 0.5 risk
const { users } = await churn.atRisk({
  threshold: 0.5,
  plan: 'enterprise',
})
```

### Paginate all high-risk users

```typescript theme={null}
async function getAllAtRisk(threshold = 0.7): Promise<AtRiskUser[]> {
  const all: AtRiskUser[] = []
  let offset = 0

  while (true) {
    const { users, total } = await churn.atRisk({ threshold, limit: 100, offset })
    all.push(...users)
    offset += users.length
    if (offset >= total) break
  }

  return all
}
```

### Nightly CS report

```typescript theme={null}
// cron: every night at 9pm
const { users, total } = await churn.atRisk({ threshold: 0.65, limit: 200 })

await sendSlackMessage({
  channel: '#customer-success',
  text: `🚨 ${total} at-risk users tonight`,
  blocks: users.slice(0, 10).map((u) => ({
    userId: u.userId,
    score: (u.score * 100).toFixed(0) + '%',
    signals: u.signals.join(', '),
  })),
})
```

## Errors

| Code               | When                               |
| ------------------ | ---------------------------------- |
| `VALIDATION_ERROR` | `threshold` is not between 0 and 1 |
| `UNAUTHORIZED`     | API key invalid                    |
| `TIMEOUT`          | Request timed out                  |
