> ## 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.

# Read resource changes

> Recover missed notifications or keep a local resource inventory current. Requires `changes:read` plus each resource's read scope: `contacts:read`, `lists:read` or `calls:read`. Events remain limited to the key's workspace and permitted owners. They contain references and deletion/access-revocation notices, not complete resource snapshots.

Start with `after=0`, then persist each returned `nextCursor` only after processing or durably queuing its page. Publication cursors are decimal strings; never convert them to JavaScript numbers. Late-committing changes receive later cursors. `hasMore:false` means no further currently published visible events; continue polling because more can appear. Empty pages retain the previous cursor.

`400 invalid_request` requires a valid decimal cursor and page size. An empty feed may reflect missing resource scopes. Capture gaps before the first key or while no active key exists require full resource enumeration; they cannot be replayed. No idempotency key is needed for this read.

See [change-feed recovery](/guides/webhooks#recover-with-the-change-feed).



## OpenAPI

````yaml /api/openapi.json get /changes
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:
  /changes:
    get:
      tags:
        - Synchronization
      summary: Read resource changes
      description: >-
        Recover missed notifications or keep a local resource inventory current.
        Requires `changes:read` plus each resource's read scope:
        `contacts:read`, `lists:read` or `calls:read`. Events remain limited to
        the key's workspace and permitted owners. They contain references and
        deletion/access-revocation notices, not complete resource snapshots.


        Start with `after=0`, then persist each returned `nextCursor` only after
        processing or durably queuing its page. Publication cursors are decimal
        strings; never convert them to JavaScript numbers. Late-committing
        changes receive later cursors. `hasMore:false` means no further
        currently published visible events; continue polling because more can
        appear. Empty pages retain the previous cursor.


        `400 invalid_request` requires a valid decimal cursor and page size. An
        empty feed may reflect missing resource scopes. Capture gaps before the
        first key or while no active key exists require full resource
        enumeration; they cannot be replayed. No idempotency key is needed for
        this read.


        See [change-feed
        recovery](/guides/webhooks#recover-with-the-change-feed).
      operationId: getChanges
      parameters:
        - name: after
          in: query
          required: false
          schema:
            type: string
            pattern: ^[0-9]{1,18}$
            default: '0'
          description: >-
            Last durably processed publication cursor as a decimal string. Use 0
            to start; pass nextCursor unchanged on subsequent reads. Never
            convert this cursor to a JavaScript number.
          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: >-
            Published visible changes, a string cursor and whether another
            currently published page 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/Changes'
              example:
                data:
                  - sequence: '42'
                    id: 00000000-0000-4000-8000-000000000002
                    orgId: org_example
                    ownerId: user_example
                    type: call.completed
                    resourceType: calls
                    resourceId: call_example_789
                    data:
                      id: call_example_789
                    createdAt: '2026-10-08T12:00:00.000Z'
                nextCursor: '42'
                hasMore: false
        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/changes?limit=50' \
              --header "Authorization: Bearer $POWERDIALER_API_KEY"
components:
  schemas:
    Changes:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Change'
          description: >-
            Visible events in publication order. Requires changes:read and the
            corresponding resource read permission.
        nextCursor:
          type: string
          description: >-
            Save this string after processing the page and send it as after on
            the next request. An empty page preserves your input cursor.
        hasMore:
          type: boolean
          description: >-
            More currently published visible events exist. False does not
            exclude pending events that publish later; continue periodic
            polling.
      required:
        - data
        - nextCursor
        - hasMore
      examples:
        - data:
            - sequence: '42'
              id: 00000000-0000-4000-8000-000000000002
              orgId: org_example
              ownerId: user_example
              type: call.completed
              resourceType: calls
              resourceId: call_example_789
              data:
                id: call_example_789
              createdAt: '2026-10-08T12:00:00.000Z'
          nextCursor: '42'
          hasMore: false
    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
    Change:
      type: object
      properties:
        sequence:
          type: string
          pattern: ^[0-9]+$
          description: >-
            Publication cursor assigned after commit and serialized as a decimal
            string; never coerce to a JavaScript number. Internal insertion
            sequence and publishedSequence field names are not part of this API.
        id:
          type: string
          format: uuid
          description: >-
            Stable event ID. Use it to deduplicate changes and webhook
            deliveries.
        orgId:
          type: string
          description: Workspace that owns the event.
        ownerId:
          type: string
          description: Member attributed to the changed resource.
        type:
          $ref: '#/components/schemas/EventType'
          description: >-
            What changed. Deletion and access-revoked events are removal
            signals.
        resourceType:
          type: string
          enum:
            - contacts
            - lists
            - calls
          description: Type of resource to fetch or remove locally.
        resourceId:
          type: string
          description: Resource identifier as a string. For calls this is the callSid.
        data:
          type: object
          properties:
            id:
              type:
                - string
                - integer
          required:
            - id
          description: >-
            Resource reference containing its ID; this is not a full contact,
            list or call snapshot.
        createdAt:
          type: string
          format: date-time
          description: >-
            Event creation time in UTC. Use sequence, not time, as the polling
            cursor.
      required:
        - sequence
        - id
        - orgId
        - ownerId
        - type
        - resourceType
        - resourceId
        - data
        - createdAt
      additionalProperties: false
      examples:
        - sequence: '42'
          id: 00000000-0000-4000-8000-000000000002
          orgId: org_example
          ownerId: user_example
          type: call.completed
          resourceType: calls
          resourceId: call_example_789
          data:
            id: call_example_789
          createdAt: '2026-10-08T12:00:00.000Z'
    EventType:
      type: string
      enum:
        - contact.created
        - contact.updated
        - contact.deleted
        - list.created
        - list.updated
        - list.deleted
        - list.membership_updated
        - call.created
        - call.updated
        - call.deleted
        - call.completed
        - call.disposition_updated
        - recording.available
        - transcript.available
        - contact.access_revoked
        - list.access_revoked
      examples:
        - call.completed
  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.