---
title: "Bulk identity feed for contact sync"
method: GET
path: "/api/v1/people/identities"
tags: ["People"]
---

# Bulk identity feed for contact sync

`GET /api/v1/people/identities`

## Request

- Base URL: `https://api.recruitwithatlas.com`
- URL: `https://api.recruitwithatlas.com/api/v1/people/identities`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/recruitwithatlas/apis/atlas-api/docs/api/v1/people/identities/get.ts> (a function with typed inputs; its response is checked against the schema)

Use this endpoint to download a full list of contact details (phone numbers, email addresses, LinkedIn URLs, etc.) for everyone in your Atlas account - intended for syncing contacts into an external system such as a VOIP phone system or address book.

For example, a phone system integration could call this endpoint periodically to keep its contact list up to date, so that when a candidate calls in, their name automatically appears on screen.

**How it works:**
- Results are returned in the order they were added to Atlas (oldest first), making it easy to pick up only what's new since your last sync
- You can filter by `updatedAfter` to only fetch identities added or updated after a certain point
- Results are paginated - if there are more results than fit in one response, `hasMore` will be `true` and you can fetch the next page

**Important:** This feed is designed for background syncing and caching, not for real-time lookups. You may occasionally receive duplicate entries - your system should handle this by updating existing records rather than creating duplicates (known as an "upsert"). Use the `identityId` field as the unique key when doing so.

**Syncing opt-outs:** every row carries `active` and `inactiveReason`, and inactive identities are included. Poll with `updatedAfter` set to the time of your last sync - marking an address unsubscribed updates its `updatedAt`, so every opt-out since then is in the feed.

## Query parameters

- `page` integer: Page number (1-indexed)
- `pageSize` integer: Items per page (max 100)
- `perPage` integer: Alias for pageSize
- `createdAfter` union: Only identities created after this point (inclusive). Accepts an ISO 8601 datetime or a date-only YYYY-MM-DD value (covering from the start of that UTC day)
  - string
  - string, date-time
- `createdBefore` union: Only identities created before this point (inclusive). Accepts an ISO 8601 datetime or a date-only YYYY-MM-DD value (covering through the end of that UTC day)
  - string
  - string, date-time
- `updatedAfter` union: Only identities updated after this point (inclusive). Accepts an ISO 8601 datetime or a date-only YYYY-MM-DD value (covering from the start of that UTC day)
  - string
  - string, date-time
- `updatedBefore` union: Only identities updated before this point (inclusive). Accepts an ISO 8601 datetime or a date-only YYYY-MM-DD value (covering through the end of that UTC day)
  - string
  - string, date-time

## Response `200`

Paginated list of contact identities

- object
  - `status` 'ok', required
  - `data` object[], required
    - `identityId` string, uuid, required: Identity ID
    - `type` string, required: Identity type (email, phone, linkedin, etc.)
    - `value` string, required: Identity value
    - `active` boolean, required: `false` when the identity is inactive; `inactiveReason` says why
    - `inactiveReason` 'bounced' | 'other' | 'unsubscribed' | 'suppressed' | 'null', nullable, required: Why the identity is inactive: `unsubscribed` - the person opted out of email; `bounced` - email to the address bounced; `suppressed` - the address is on the agency's suppression list; `other` - deactivated for another reason. `null` when the identity is active, or when it was deactivated without a recorded reason.
    - `createdAt` string, date-time, required: When the identity was created
    - `updatedAt` string, date-time, required: When the identity was last updated
    - `person` object, required
      - `id` string, uuid, required
      - `firstName` string, nullable, required
      - `lastName` string, nullable, required
  - `page` integer, required: Use pagination.page instead
  - `pageSize` integer, required: Use pagination.pageSize instead
  - `hasMore` boolean, required: Use pagination instead
  - `pagination` object, required
    - `page` integer, required: Current page number
    - `pageSize` integer, required: Items per page
    - `total` integer, required: Total matching items
    - `totalPages` integer, required: Total number of pages

## Other responses

- `401`: Unauthorized - missing or invalid API key
- `422`: Validation error - the request failed schema validation (`errors.fieldErrors`) or a business rule (`errors.formErrors`)
- `429`: Too many requests - the caller has exceeded the per-agency rate limit for the tier this endpoint counts against (default per minute: 1200 read / 400 write / 60 upload). Inspect the `RateLimit-*` headers — returned on every response, not only on 429s — and back off until the window resets. See the "Rate limits" section of the introduction for details.
- `500`: Internal server error

## Changes

- **2026-11-03** `158ee454751c`: 1 warning
  - added the new `undefined` enum value to the `data/items/inactiveReason` response property for the response status `200`
- **2026-10-20** `b7e1215476a1`: 2 info
  - added the required property `data/items/active` to the response with the `200` status
  - added the required property `data/items/inactiveReason` to the response with the `200` status
- **2026-10-03** `cd4bc8bbd95e`: 1 info
  - added the optional property `error` to the response with the `422` status

[Operation history](https://skmtc.dev/recruitwithatlas/apis/atlas-api/changes/api/v1/people/identities/get.md)

---

[API](https://skmtc.dev/recruitwithatlas/apis/atlas-api.md) - [All operations](https://skmtc.dev/recruitwithatlas/apis/atlas-api/llms.txt) - [OpenAPI document](https://skmtc.dev/recruitwithatlas/apis/atlas-api/revisions/158ee454751c?raw)
