# Get phone verification contacts

Page through the phone numbers your traders verified by SMS in your community, each with the trader's email.

- Endpoint: `GET https://api.returning.ai/v1/community-analytics/phone-verification-contacts`
- Section: Community / Analytics
- Authentication: `Authorization: Bearer <API_KEY>` (Community API key)
- Permission: `customerSuccess` (Shown in the dashboard as "Customer Success")
- Retries: Read-only; exact retries are safe
- Guide: hand-written
- Verified: live, 2026-09-27
- Last updated: 26 Sep 2026
- Web page: https://docs.returning.ai/api-reference/community-analytics/get-phone-verification-contacts

## When to use this

- Copy verified phone numbers into your CRM or marketing tool on a schedule.
- Check which traders have completed phone verification in your community.
- Match verified numbers to your own client records by email.

**Instead:** Use [Get loyalty overview](https://docs.returning.ai/api-reference/community-analytics/get-loyalty-overview.md) instead for balances, roles and visits per trader.

## Authentication

- Header: `Authorization: Bearer <API_KEY>`
- Permission: `customerSuccess`

Use a Community API key with `customerSuccess`, shown in the dashboard as Customer Success, and keep it on your server. The key decides the community, so you only see contacts from your own community and never send a `communityId`. A key without the permission gets `401`, not `403`. Personal API keys are rejected with `401`.

## Behaviour

A trader appears here once they verify a phone number by SMS in your community. If they verify again with another number, the new number replaces the old one, so each trader has at most one contact. Contacts are returned in a fixed order, so you can page through all of them; read every page up to `totalPages`.

Every row is personal data. Responses are sent with `Cache-Control: no-store`, and you should store them with the same care as the rest of your client records.

## Request

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | `integer` | No | Page number, starting at 1. (Whole number, 1 or more; default 1) |
| `limit` | `integer` | No | Contacts per page. (Default 100; max 500) |

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Authorization` | `string` | Yes | Community API key with `customerSuccess`. (`Bearer <API_KEY>`) |

### Example request

```bash
curl --request GET \
  --url 'https://api.returning.ai/v1/community-analytics/phone-verification-contacts?page=1&limit=100' \
  --header 'Authorization: Bearer <API_KEY>'
```

## Response

A `200` returns the page in `data.data` and the totals in `data.pagination`. A community with no verified numbers returns `200` with an empty `data.data` and `total` `0`, not `404`.

### Response fields

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `status` | `string` | always | Result of the request. (`success`) |
| `message` | `string` | always | Human-readable summary. Do not branch on it. |
| `data` | `object` | always | This page of contacts and the paging totals. |
| `data.data` | `object[]` | always | One contact per verified phone record on this page. Empty when nothing matches or past the last page. |
| `data.data.email` | `string` | always | The trader's email, or `null` when the account has none. |
| `data.data.phoneNumber` | `string` | always | The verified phone number in international format, with the country code. (E.164, such as `+6581234567`) |
| `data.pagination` | `object` | always | Paging totals for every contact in your community. |
| `data.pagination.total` | `integer` | always | Contacts across all pages. |
| `data.pagination.page` | `integer` | always | The page you asked for. |
| `data.pagination.limit` | `integer` | always | The page size used. |
| `data.pagination.totalPages` | `integer` | always | Pages at this `limit`. `0` when there are no contacts. |

### Example response (200)

```json
{
  "status": "success",
  "message": "Phone verification contacts fetched successfully",
  "data": {
    "data": [
      {
        "email": "trader@example.com",
        "phoneNumber": "+6581234567"
      }
    ],
    "pagination": {
      "total": 1,
      "page": 1,
      "limit": 100,
      "totalPages": 1
    }
  }
}
```

## Errors

Errors on this endpoint have no machine-readable code; branch on the HTTP status. A validation `400` lists each problem in `details`, as `field` and `message`. A `401` carries only `message`, or `status` and `message`.

### Fix the request

| Status | Code | What to do |
| --- | --- | --- |
| 400 | - | A query value is invalid. Each entry in `details` names a `field` and says why: `page` must be a whole number of 1 or more, `limit` a whole number from 1 to 500, and `query` means an unknown parameter was sent. Only `page` and `limit` are accepted; `communityId` is rejected. |
| 401 | - | The key is missing (`Invalid token`), unknown (`Invalid API key`) or expired, it's a personal key, or it lacks `customerSuccess` (`Your api key does not have permission to access this action`). Send `Authorization: Bearer <API_KEY>` with a Community API key, and add Customer Success in Settings > Integration > API Keys. |

### Retry with backoff

| Status | Code | What to do |
| --- | --- | --- |
| 429 | - | Your community has a [rate limit](https://docs.returning.ai/how-it-works.md#rate-limits) for these analytics endpoints, and this caller has used it up for the current window. Wait until the window resets, as shown in the `RateLimit` header, then retry. |
| 500 | - | The contacts could not be read, or the key could not be checked (`Authentication failed`). Retry the same request with exponential backoff. |

**Retries:** This endpoint is read-only and doesn't accept an `Idempotency-Key`. Retrying the exact same request is safe after a network error or a `500`; use bounded exponential backoff. The request limit is off unless Returning.AI has set one for your community. When it is on, it counts requests per community and caller IP address over a fixed window, shared across the community analytics endpoints, and responses carry `RateLimit` and `RateLimit-Policy` headers. A `429` means wait for the window to reset, then retry.

## Next step

- [Look up the trader behind a contact with Get User Data](https://docs.returning.ai/api-reference/users/get-user-data.md): `POST /v1/users/info`. Use the contact's `email` to read the trader's profile and platform user ID.
- [Get loyalty overview](https://docs.returning.ai/api-reference/community-analytics/get-loyalty-overview.md): `GET /v1/community-analytics/loyalty-overview`. Add balances, roles and visit counts for the same traders.
