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

# List contacts

> Read the contacts your integration can access, for example when building an initial CRM synchronization. Requires `contacts:read`. Results are restricted to the key's workspace and permitted contact owners; membership in a visible calling list does not broaden contact access.

Contacts arrive in increasing numeric ID order. Set `limit` to control page size and pass a non-null `nextCursor` back as `after`. Stop when the cursor is null. Pages are not a frozen snapshot; use the change feed to reconcile updates and deletions during enumeration.

An empty page means no matching visible records, not proof that historical contacts never existed. Legacy contacts need established attribution before they are available. `400 invalid_request` indicates invalid pagination or unsupported query fields; `403 insufficient_scope` requires a key with contact-read permission. Reads can be retried without an idempotency key.

See [contacts and imports](/guides/contact-lists).



## OpenAPI

````yaml /api/openapi.json get /contacts
openapi: 3.1.0
info:
  title: PowerDialer API v2
  version: 2.0.0
  description: >-
    Connect your CRM, sales workspace or reporting tools to PowerDialer using
    scoped API keys. Manage contacts and calling lists, read call evidence and
    analytics, and receive signed events. All example records and IDs are
    synthetic; replace them with values from your workspace. Shared-key v1 is
    retired. API availability was verified on 2026-10-08; see /availability for
    historical data coverage. Legacy outbound webhooks use a separate contract.
servers:
  - url: https://api.migration.powerdialer.ai/api/public/v2
    description: Production API v2; availability verified on 2026-10-08.
security:
  - ApiKey: []
tags:
  - name: Authentication
  - name: Contacts
  - name: Calling lists
  - name: Imports
  - name: Calls
  - name: Synchronization
  - name: Analytics
  - name: Webhooks
  - name: Webhook deliveries
  - name: Incoming webhook payloads
paths:
  /contacts:
    get:
      tags:
        - Contacts
      summary: List contacts
      description: >-
        Read the contacts your integration can access, for example when building
        an initial CRM synchronization. Requires `contacts:read`. Results are
        restricted to the key's workspace and permitted contact owners;
        membership in a visible calling list does not broaden contact access.


        Contacts arrive in increasing numeric ID order. Set `limit` to control
        page size and pass a non-null `nextCursor` back as `after`. Stop when
        the cursor is null. Pages are not a frozen snapshot; use the change feed
        to reconcile updates and deletions during enumeration.


        An empty page means no matching visible records, not proof that
        historical contacts never existed. Legacy contacts need established
        attribution before they are available. `400 invalid_request` indicates
        invalid pagination or unsupported query fields; `403 insufficient_scope`
        requires a key with contact-read permission. Reads can be retried
        without an idempotency key.


        See [contacts and imports](/guides/contact-lists).
      operationId: getContacts
      parameters:
        - name: after
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
            maximum: 2147483647
            default: 0
          description: >-
            Exclusive numeric ID cursor. Omit or use 0 for the first page, then
            pass the previous nextCursor. Keep the same filters while paging.
          example: 0
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          description: >-
            Maximum items to return in one page, from 1 to 200. Defaults to 50.
            Smaller pages reduce response size; this is not a total-result
            limit.
          example: 50
      responses:
        '200':
          description: >-
            A page of visible contacts and the next cursor, or null when no
            further page currently exists.
          headers:
            X-Request-Id:
              schema:
                type: string
                format: uuid
            RateLimit-Limit:
              schema:
                type: integer
            RateLimit-Remaining:
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactPage'
              example:
                data:
                  - ownerId: user_example
                    externalId: crm-contact-123
                    name: Alex Morgan
                    phoneNumber: '+12125550100'
                    additionalNumbers: []
                    metadata:
                      source: website
                      timeZone: America/New_York
                      timeZoneSource: provided
                    timeZone: America/New_York
                    timeZoneSource: provided
                    id: 123
                    createdAt: '2026-10-08T12:00:00.000Z'
                    updatedAt: '2026-10-08T12:00:00.000Z'
                nextCursor: null
        default:
          description: >-
            Error. 400 invalid request; 401 invalid credential; 403 insufficient
            access; 404 not found; 409 state/idempotency conflict; 413 size
            limit; 422 verification failure; 429 rate limit (Retry-After
            seconds); 503 temporary service failure.
          headers:
            Retry-After:
              schema:
                type: integer
            X-Request-Id:
              schema:
                type: string
                format: uuid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: invalid_api_key
                  message: API key is invalid, expired or revoked
                  requestId: 00000000-0000-4000-8000-000000000004
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >-
            # Replace example resource IDs and ownerId with values from your
            workspace.

            : "${POWERDIALER_API_KEY:?Set POWERDIALER_API_KEY to your scoped API
            key}"

            curl --request GET \
              --url 'https://api.migration.powerdialer.ai/api/public/v2/contacts?limit=50' \
              --header "Authorization: Bearer $POWERDIALER_API_KEY"
components:
  schemas:
    ContactPage:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Contact'
          description: Resources in ascending numeric ID order.
        nextCursor:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Send this value as after to read the next page. Null means this
            result has no next page.
      required:
        - data
        - nextCursor
      examples:
        - data:
            - ownerId: user_example
              externalId: crm-contact-123
              name: Alex Morgan
              phoneNumber: '+12125550100'
              additionalNumbers: []
              metadata:
                source: website
                timeZone: America/New_York
                timeZoneSource: provided
              timeZone: America/New_York
              timeZoneSource: provided
              id: 123
              createdAt: '2026-10-08T12:00:00.000Z'
              updatedAt: '2026-10-08T12:00:00.000Z'
          nextCursor: null
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: Stable machine-readable error code.
            message:
              type: string
              description: Human-readable explanation.
            requestId:
              type: string
              format: uuid
              description: Request identifier to include when investigating a failure.
            details:
              type: array
              items:
                type: object
                properties:
                  path:
                    type: string
                  message:
                    type: string
                required:
                  - path
                  - message
              description: Validation errors, when available.
          required:
            - code
            - message
            - requestId
      required:
        - error
      examples:
        - error:
            code: insufficient_scope
            message: Requires contacts:read
            requestId: 00000000-0000-4000-8000-000000000004
    Contact:
      type: object
      properties:
        id:
          type: integer
          description: PowerDialer contact ID. Use this integer in contact URLs.
        name:
          type: string
          description: Stored contact name.
        phoneNumber:
          type: string
          description: Stored primary phone number. V2 writes require E.164.
        additionalNumbers:
          type: array
          items:
            type: string
          description: Stored additional phone numbers.
        metadata:
          description: >-
            Stored JSON metadata. v2 writes use objects; legacy rows may contain
            other JSON values.
        ownerId:
          anyOf:
            - type: string
            - type: 'null'
          description: Attributed PowerDialer member ID.
        externalId:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Your source-system identifier, or null when no identifier was
            assigned.
        createdAt:
          type: string
          format: date-time
          description: Time the contact was created, in UTC.
        updatedAt:
          type: string
          format: date-time
          description: Time the contact was last updated, in UTC.
        timeZone:
          description: >-
            Stored timezone metadata. V2 writes produce an IANA string or null;
            legacy metadata may contain another JSON value.
        timeZoneSource:
          description: >-
            Stored timezone-source metadata. V2 writes use provided,
            phone_estimate, or unknown; legacy values may differ.
      required:
        - id
        - name
        - phoneNumber
        - additionalNumbers
        - metadata
        - ownerId
        - externalId
        - createdAt
        - updatedAt
        - timeZone
        - timeZoneSource
      examples:
        - ownerId: user_example
          externalId: crm-contact-123
          name: Alex Morgan
          phoneNumber: '+12125550100'
          additionalNumbers: []
          metadata:
            source: website
            timeZone: America/New_York
            timeZoneSource: provided
          timeZone: America/New_York
          timeZoneSource: provided
          id: 123
          createdAt: '2026-10-08T12:00:00.000Z'
          updatedAt: '2026-10-08T12:00:00.000Z'
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      bearerFormat: pd_<live|test>_<credential UUID>.<random secret>
      description: >-
        Issued in Developers. Workspace/owner/scopes come from credential, never
        acting-user headers. API keys cannot manage API credentials.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.