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

# Log in with Privy token

> Handles `POST /v1/auth/login/privy` via `post.v1.auth.login.privy`.



## OpenAPI

````yaml /openapi/phoenix-public-api.json post /v1/auth/login/privy
openapi: 3.1.0
info:
  title: Phoenix Eternal API
  description: >-
    RESTful API for accessing Phoenix Eternal perpetual trading data. Provides
    real-time orderbook levels, asset information, and market metadata.
  termsOfService: https://www.phoenix.trade/terms-of-service
  contact:
    name: Phoenix Development Team
    url: https://github.com/Ellipsis-Labs/phoenix
  license:
    name: Proprietary
  version: 1.0.0
servers:
  - url: https://perp-api.phoenix.trade
    description: Phoenix Eternal Perp API
security: []
tags:
  - name: Auth
    description: Wallet and session authentication.
  - name: Exchange
    description: Exchange, market, candle, and no-referral register-instruction workflows.
  - name: Invite
    description: Invite validation, referral activation, and wallet allowlist checks.
  - name: Notifications
    description: Trader notification reads and acknowledgement helpers.
  - name: Trader
    description: Trader state, account history, and transaction builders.
externalDocs:
  url: https://docs.phoenix.trade
  description: Phoenix developer documentation
paths:
  /v1/auth/login/privy:
    post:
      tags:
        - Auth
      summary: Log in with Privy token
      description: Handles `POST /v1/auth/login/privy` via `post.v1.auth.login.privy`.
      operationId: post.v1.auth.login.privy
      requestBody:
        description: JSON request payload for `post.v1.auth.login.privy`.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PrivyLoginRequest'
            example:
              privy_token: string
        required: true
      responses:
        '200':
          description: Phoenix JWT pair issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '400':
          $ref: '#/components/responses/ErrorResponse'
        '401':
          $ref: '#/components/responses/ErrorResponse'
        '403':
          $ref: '#/components/responses/ErrorResponse'
        '409':
          $ref: '#/components/responses/ErrorResponse'
        '500':
          $ref: '#/components/responses/ErrorResponse'
        '502':
          $ref: '#/components/responses/ErrorResponse'
        '503':
          $ref: '#/components/responses/ErrorResponse'
components:
  schemas:
    PrivyLoginRequest:
      type: object
      required:
        - privy_token
      properties:
        privy_token:
          type: string
        wallet_proof:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/PrivyWalletProof'
              description: >-
                Proof of ownership of `wallet_pubkey`, obtained by signing the

                transaction returned from `POST
                /v1/auth/privy/wallet-challenge`. When

                supplied this satisfies the first-time binding ownership check

                without needing the Privy linked-accounts lookup.
        wallet_pubkey:
          type:
            - string
            - 'null'
          description: >-
            Optional Solana wallet pubkey the caller is asserting ownership of.

            For first-time bindings ownership must be proved either by including

            `wallet_proof` (a Solana memo transaction signed by the wallet —
            works

            for Ledger which cannot sign off-chain messages) or, absent a proof,

            by Privy's `linked_accounts` API confirming the wallet is linked to

            the authenticated user. An unverified pubkey is rejected with

            `wallet_not_linked`. For returning users, if supplied, it must match

            the bound pubkey. If omitted when no mapping exists, login still

            succeeds but the issued token will not carry a `wallet` claim and so

            cannot satisfy user-scoped authorization.
    AuthResponse:
      type: object
      required:
        - token_type
        - access_token
        - expires_in
        - refresh_token
        - refresh_expires_in
        - pop_key
      properties:
        access_token:
          type: string
        expires_in:
          type: integer
          format: int64
          minimum: 0
        pop_key:
          type: string
        refresh_expires_in:
          type: integer
          format: int64
          minimum: 0
        refresh_token:
          type: string
        token_type:
          type: string
    PrivyWalletProof:
      type: object
      required:
        - nonce_id
        - signed_transaction
      properties:
        nonce_id:
          type: string
          description: The `nonce_id` returned from the wallet-challenge endpoint.
        signed_transaction:
          type: string
          description: |-
            The full signed Solana transaction, base64-encoded (legacy bincode
            format). The transaction must be the same one returned from the
            wallet-challenge endpoint, signed by `wallet_pubkey`.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
  responses:
    ErrorResponse:
      description: Standard JSON error payload.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

````