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

# List phone lines

> Returns the lines of the key's workspace, **newest purchase first**. By default only the lines you still hold (`ACTIVE`, `PAYMENT_PENDING`, `SUSPENDED`); add `includeClosed=true` to include the finished ones (`RETURNED`, `CANCELED`). The list is **not paginated**: it always returns every matching line. Each item is the same line object `GET /v1/phone-lines/{id}` returns.

Permissions: with an OAuth / MCP token, the user must be an **Owner or Admin** (`phone_lines:read`) — `403 PERMISSION_DENIED` otherwise.

Every `/v1/phone-lines` endpoint takes a **tenant-scoped** key only: a line belongs to the workspace, not to a WhatsApp number, so a number-scoped key (or a per-number OAuth grant) gets `403 NUMBER_SCOPE_NOT_ALLOWED` before any role is looked at. A `403 PERMISSION_DENIED` / `WORKSPACE_MEMBERSHIP_REQUIRED` is sent with `Cache-Control: no-store`.

**Requires a tenant-scoped key.**



## OpenAPI

````yaml openapi.json GET /v1/phone-lines
openapi: 3.1.0
info:
  title: Pilot Status API
  version: 1.0.0
  license:
    name: Pilot Status Terms of Service
    url: https://pilotstatus.com.br/terms
  description: >-
    Public REST API for Pilot Status. Authenticate with the `x-api-key: ps_...`
    header (or `x-api-key-id`). Base URL: https://pilotstatus.com.br
servers:
  - url: https://pilotstatus.com.br
security:
  - apiKey: []
  - apiKeyId: []
paths:
  /v1/phone-lines:
    get:
      tags:
        - Phone Lines
      summary: List phone lines
      description: >-
        Returns the lines of the key's workspace, **newest purchase first**. By
        default only the lines you still hold (`ACTIVE`, `PAYMENT_PENDING`,
        `SUSPENDED`); add `includeClosed=true` to include the finished ones
        (`RETURNED`, `CANCELED`). The list is **not paginated**: it always
        returns every matching line. Each item is the same line object `GET
        /v1/phone-lines/{id}` returns.


        Permissions: with an OAuth / MCP token, the user must be an **Owner or
        Admin** (`phone_lines:read`) — `403 PERMISSION_DENIED` otherwise.


        Every `/v1/phone-lines` endpoint takes a **tenant-scoped** key only: a
        line belongs to the workspace, not to a WhatsApp number, so a
        number-scoped key (or a per-number OAuth grant) gets `403
        NUMBER_SCOPE_NOT_ALLOWED` before any role is looked at. A `403
        PERMISSION_DENIED` / `WORKSPACE_MEMBERSHIP_REQUIRED` is sent with
        `Cache-Control: no-store`.


        **Requires a tenant-scoped key.**
      operationId: get_phone_lines
      parameters:
        - name: includeClosed
          in: query
          required: false
          description: >-
            `true` or `1` includes finished lines (`RETURNED`, `CANCELED`);
            `false`, `0` or absent leaves them out. Any other value
            (case-sensitive: `TRUE` is refused) → **400 `INVALID_QUERY`**.
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
              - '1'
              - '0'
            default: 'false'
          example: 'true'
      responses:
        '200':
          description: The workspace's lines, newest purchase first
          content:
            application/json:
              schema:
                type: object
                properties:
                  lines:
                    type: array
                    description: The lines, newest purchase first. Not paginated.
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: >-
                            The line id. Use it in every `/v1/phone-lines/{id}`
                            path.
                          example: cmg5k2l1n0001pl8example9x
                        name:
                          type: string
                          description: >-
                            The name your team gave the line in the dashboard,
                            up to 60 characters. **Never empty:** a line without
                            a name returns its formatted number, the same as
                            `display` — and every line is bought without one. It
                            cannot be set or changed through the API. It is a
                            label: identify the line by its `id`.
                          example: Support SP
                        number:
                          type: string
                          description: E.164 digits **without** `+`, e.g. `551148637200`.
                          example: '551148637200'
                        display:
                          type: string
                          description: 'The number formatted for people: `(11) 4863-7200`.'
                          example: (11) 4863-7200
                        ddd:
                          type: string
                          description: The two-digit area code.
                          example: '11'
                        status:
                          type: string
                          description: >-
                            `ACTIVE`, `PAYMENT_PENDING`, `SUSPENDED`, `RETURNED`
                            or `CANCELED`. The field to branch on.
                          example: ACTIVE
                          enum:
                            - ACTIVE
                            - PAYMENT_PENDING
                            - SUSPENDED
                            - RETURNED
                            - CANCELED
                        price:
                          type: number
                          description: >-
                            What **this** line costs per month — the price of
                            its next renewal (e.g. `33.9`): the purchase price,
                            or the workspace's own phone line price when the
                            Pilot Status team set one (applied to lines bought
                            before it too).
                          example: 33.9
                        currency:
                          type: string
                          description: '`BRL` or `USD` — the currency `price` is charged in.'
                          example: BRL
                          enum:
                            - BRL
                            - USD
                        purchasedAt:
                          type: string
                          description: >-
                            ISO 8601 — when the line was bought. Renewals count
                            from it.
                          example: '2026-10-01T14:03:11.000Z'
                          format: date-time
                        currentPeriodEnd:
                          type: string
                          description: >-
                            ISO 8601 — end of the paid period. The next renewal
                            is attempted in the first hourly billing run after
                            it. For a line cancelled at period end, when it
                            becomes `CANCELED`. It does not move while a renewal
                            is unpaid.
                          example: '2026-11-01T14:03:11.000Z'
                          format: date-time
                        cancelAtPeriodEnd:
                          type: boolean
                          description: >-
                            `true` after a `DELETE` on an `ACTIVE` line: it will
                            not renew and becomes `CANCELED` at
                            `currentPeriodEnd`.
                          example: false
                        paymentPendingSince:
                          type:
                            - string
                            - 'null'
                          description: >-
                            ISO 8601 — when the renewal charge failed. The line
                            is suspended 2 days after this. `null` once a
                            renewal succeeds.
                          example: null
                          format: date-time
                        suspendedAt:
                          type:
                            - string
                            - 'null'
                          description: >-
                            ISO 8601 — when the line was suspended. It is
                            returned 1 day after this. `null` once a renewal
                            succeeds.
                          example: null
                          format: date-time
                        returnedAt:
                          type:
                            - string
                            - 'null'
                          description: >-
                            ISO 8601 — when the number was returned to the
                            carrier (`RETURNED`).
                          example: null
                          format: date-time
                        canceledAt:
                          type:
                            - string
                            - 'null'
                          description: >-
                            ISO 8601 — when a line cancelled at period end
                            became `CANCELED`.
                          example: null
                          format: date-time
                        activationCount:
                          type: integer
                          description: >-
                            How many code requests were opened on this line so
                            far. A `POST …/activations` that answered `503` is
                            not counted.
                          example: 1
                        amountDue:
                          type:
                            - number
                            - 'null'
                          description: >-
                            On a `PAYMENT_PENDING` or `SUSPENDED` line, what
                            paying it now charges — the amount of its overdue
                            period, fixed when that period was first charged.
                            `null` on any other line.
                          example: null
              example:
                lines:
                  - id: cmg5k2l1n0001pl8example9x
                    name: Support SP
                    number: '551148637200'
                    display: (11) 4863-7200
                    ddd: '11'
                    status: ACTIVE
                    price: 33.9
                    currency: BRL
                    purchasedAt: '2026-10-01T14:03:11.000Z'
                    currentPeriodEnd: '2026-11-01T14:03:11.000Z'
                    cancelAtPeriodEnd: false
                    paymentPendingSince: null
                    suspendedAt: null
                    returnedAt: null
                    canceledAt: null
                    activationCount: 1
                    amountDue: null
        '400':
          description: '`includeClosed` is not `true`, `false`, `1` or `0` (`INVALID_QUERY`)'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: >-
                  includeClosed must be true or false. | includeClosed deve ser
                  true ou false.
                code: INVALID_QUERY
        '401':
          description: >-
            Missing or invalid credential (`x-api-key`, `x-api-key-id` or
            `Authorization: Bearer`). The body carries only `error`, no `code`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              examples:
                missing:
                  summary: No credential
                  value:
                    error: >-
                      Missing x-api-key, x-api-key-id or Authorization Bearer
                      token
                invalid:
                  summary: Invalid API key
                  value:
                    error: Invalid API key
        '403':
          description: >-
            Number-scoped key (`NUMBER_SCOPE_NOT_ALLOWED`), OAuth/MCP token of a
            user who is not Owner or Admin (`PERMISSION_DENIED`) or no longer an
            active member (`WORKSPACE_MEMBERSHIP_REQUIRED`), or archived
            workspace (`WORKSPACE_ARCHIVED`). `TENANT_REQUIRED`: credential not
            bound to any workspace
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              examples:
                numberScope:
                  summary: Number-scoped key
                  value:
                    error: This endpoint requires a tenant-scoped API key
                    code: NUMBER_SCOPE_NOT_ALLOWED
                permissionDenied:
                  summary: OAuth/MCP user who is not Owner or Admin
                  value:
                    error: >-
                      Your workspace role does not allow this action
                      (phone_lines:read).
                    code: PERMISSION_DENIED
                notMember:
                  summary: OAuth/MCP user no longer a member
                  value:
                    error: >-
                      The user behind this token is not an active member of this
                      workspace.
                    code: WORKSPACE_MEMBERSHIP_REQUIRED
                archived:
                  summary: Workspace archived
                  value:
                    error: >-
                      This workspace has been archived and its API is closed. |
                      Este workspace foi arquivado e sua API está encerrada.
                    code: WORKSPACE_ARCHIVED
                tenantRequired:
                  summary: Credential not bound to a workspace
                  value:
                    error: This credential is not bound to a workspace.
                    code: TENANT_REQUIRED
        '404':
          description: >-
            An `x-whatsapp-number-id` header was sent and names no WhatsApp
            number of your account (`NUMBER_NOT_FOUND`). This endpoint needs no
            such header — remove it.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: >-
                  x-whatsapp-number-id does not name a WhatsApp number of this
                  account | x-whatsapp-number-id não indica um número de
                  WhatsApp desta conta
                code: NUMBER_NOT_FOUND
        '500':
          description: Unexpected failure (`INTERNAL_ERROR`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Unexpected error. | Erro inesperado.
                code: INTERNAL_ERROR
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Your ps_ API key
    apiKeyId:
      type: apiKey
      in: header
      name: x-api-key-id
      description: API key id (alternative to x-api-key)

````

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