# List people waiting in a campaign's Discord

`GET https://api.tryscouty.com/v1/campaigns/{campaignId}/discord-joins`

Lists people who joined this campaign's Discord server and never texted the join code, so they are not on the campaign yet. invitedAt says whether Scouty already messaged them the onboarding link. At most 50, oldest first.

- Scope: `creators:read`
- Kind: read
- MCP tool: `scouty_list_discord_joins`

## Authorization

Send `Authorization: Bearer $SCOUTY_TOKEN`. The token needs the `creators:read` scope.

## Path parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `campaignId` | `integer` | Required | The campaign. |

## Request

### cURL

```bash
curl -s https://api.tryscouty.com/v1/campaigns/42/discord-joins \
  -H "Authorization: Bearer $SCOUTY_TOKEN"
```

### JavaScript

```js
const response = await fetch("https://api.tryscouty.com/v1/campaigns/42/discord-joins", {
  headers: {
    Authorization: `Bearer ${process.env.SCOUTY_TOKEN}`,
  },
});
console.log(await response.json());
```

### Python

```python
import os

import requests

token = os.environ["SCOUTY_TOKEN"]
response = requests.get(
    "https://api.tryscouty.com/v1/campaigns/42/discord-joins",
    headers={"Authorization": f"Bearer {token}"},
)
print(response.json())
```

## Responses

### 200 OK

```json
{
  "campaignId": 42,
  "joins": [
    {
      "discordUserId": "000000000000000001",
      "discordUsername": "maya_acme",
      "joinedAt": "2026-09-25T09:00:00.000Z",
      "invitedAt": null
    }
  ]
}
```

### 401 Unauthorized

```json
{
  "error": {
    "code": "missing_token",
    "message": "This API needs an Authorization header carrying a bearer token."
  }
}
```

### 403 Forbidden

```json
{
  "error": {
    "code": "insufficient_scope",
    "message": "This token does not carry the creators:read scope. Ask the team for one that does."
  }
}
```

### 404 Not Found

```json
{
  "error": {
    "code": "not_found",
    "message": "No such campaign."
  }
}
```

### 429 Too Many Requests

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Please wait for the current minute to end."
  }
}
```

## Errors

| Status | `error.code` | Meaning |
|---|---|---|
| 401 Unauthorized | `missing_token`, `invalid_token`, `token_revoked`, `token_expired`, `token_orphaned` | No token, or one that is not recognized, revoked or expired. |
| 403 Forbidden | `insufficient_scope`, `wrong_principal` | The token does not carry the scope this capability needs. |
| 404 Not Found | `not_found` | No such route, or no such campaign for this client. |
| 429 Too Many Requests | `rate_limited` | Too many requests this minute. Retry-After says how long is left. |

Full reference: https://docs.tryscouty.com/reference
