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

# Criar saque

> Cria uma solicitação de saque em produção. Requer chave `trq_live_`, conta aprovada, permissão de saque, destino aprovado, saldo disponível e `Idempotency-Key`. No piloto atual, a solicitação reserva saldo e a conclusão do pagamento passa por revisão operacional.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/withdrawals
openapi: 3.1.0
info:
  title: TroqPay API
  description: >-
    API da TroqPay para criar cobranças Pix, ler saldo, solicitar saques em
    produção e processar eventos por webhook.
  version: 1.0.0
servers:
  - url: https://api.troqpay.com
    description: >-
      Use a mesma URL-base para teste e produção. O ambiente é definido pela
      chave utilizada (`trq_test_` ou `trq_live_`).
security:
  - bearerAuth: []
tags:
  - name: Checkouts
    description: Criação e consulta de cobranças Pix.
  - name: Payment Links
    description: >-
      Criação, listagem e consulta de links de pagamento a partir de produtos
      cadastrados.
  - name: Saldo
    description: >-
      Leitura do saldo agregado da conta TroqPay (valores em decimal, todos em
      BRL).
  - name: Saques
    description: Criação e consulta de saques em produção.
  - name: Webhooks
    description: Eventos enviados pela TroqPay quando um checkout muda de estado.
  - name: Status
    description: Endpoints públicos para verificar disponibilidade da API.
paths:
  /v1/withdrawals:
    post:
      tags:
        - Saques
      summary: Criar saque
      description: >-
        Cria uma solicitação de saque em produção. Requer chave `trq_live_`,
        conta aprovada, permissão de saque, destino aprovado, saldo disponível e
        `Idempotency-Key`. No piloto atual, a solicitação reserva saldo e a
        conclusão do pagamento passa por revisão operacional.
      operationId: createWithdrawal
      parameters:
        - $ref: '#/components/parameters/RequiredIdempotencyKeyHeader'
        - $ref: '#/components/parameters/RequestIdHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WithdrawalCreateRequest'
            examples:
              brlPix:
                summary: Saque Pix em BRL
                value:
                  rail: BRL_PIX
                  amount: '100.00'
              usdt:
                summary: Saque para carteira USDT
                value:
                  rail: USDT_WALLET
                  amount: '100.00'
      responses:
        '200':
          description: 'Reentrega idempotente: o saque já existente foi retornado.'
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Withdrawal'
        '201':
          description: Saque criado.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Withdrawal'
        '400':
          description: Payload inválido ou `Idempotency-Key` ausente.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missingIdempotency:
                  summary: Idempotency-Key obrigatório
                  value:
                    error:
                      type: validation_error
                      code: idempotency_key_required
                      message: >-
                        Idempotency-Key header is required for withdrawal
                        creation.
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            Ambiente, permissão ou configuração da conta não permite criar
            saque.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                testMode:
                  summary: Saques são live-only
                  value:
                    error:
                      type: auth_error
                      code: test_withdrawals_not_supported
                      message: Withdrawals are available only in live mode.
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
                missingPermission:
                  summary: Chave sem permissão de saque
                  value:
                    error:
                      type: auth_error
                      code: api_key_scope_forbidden
                      message: >-
                        API key does not have permission to access this
                        resource.
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
                readiness:
                  summary: Conta ainda não pronta para saque
                  value:
                    error:
                      type: auth_error
                      code: withdrawal_readiness_required
                      message: >-
                        Account must complete live withdrawal setup before
                        creating withdrawals.
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
        '409':
          description: A mesma `Idempotency-Key` foi usada com corpo diferente.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Regra de negócio do saque não atendida.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                insufficientBalance:
                  summary: Saldo insuficiente
                  value:
                    error:
                      type: business_error
                      code: insufficient_balance
                      message: available balance is insufficient for this withdrawal
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
        '429':
          $ref: '#/components/responses/RateLimited'
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |-
            curl https://api.troqpay.com/v1/withdrawals \
              -X POST \
              -H "Authorization: Bearer trq_live_xxx" \
              -H "Content-Type: application/json" \
              -H "Idempotency-Key: withdrawal_1001" \
              -d '{"rail":"BRL_PIX","amount":"100.00"}'
        - lang: JavaScript
          label: JavaScript
          source: >-
            const response = await
            fetch("https://api.troqpay.com/v1/withdrawals", {
              method: "POST",
              headers: {
                "Authorization": "Bearer trq_live_xxx",
                "Content-Type": "application/json",
                "Idempotency-Key": "withdrawal_1001"
              },
              body: JSON.stringify({ rail: "BRL_PIX", amount: "100.00" })
            });


            const withdrawal = await response.json();
components:
  parameters:
    RequiredIdempotencyKeyHeader:
      name: Idempotency-Key
      in: header
      required: true
      description: >-
        Chave de idempotência obrigatória para criação de saque. Mesma chave e
        mesmo corpo retornam o mesmo saque; mesma chave com corpo diferente
        retorna `409 idempotency_conflict`.
      schema:
        type: string
        example: withdrawal_1001
    RequestIdHeader:
      name: Request-Id
      in: header
      required: false
      description: >-
        Identificador opcional fornecido pelo cliente para correlação. A API
        aceita também `X-Request-Id`. O valor é ecoado de volta no header de
        resposta `Request-Id`. Se nenhum dos dois é enviado, a API gera `req_<24
        hex>`.
      schema:
        type: string
        example: req_4a8b3c1d5e6f2a9b0c1d2e3f
  schemas:
    WithdrawalCreateRequest:
      type: object
      required:
        - rail
        - amount
      description: >-
        Dados para solicitar um saque. O destino não é enviado no corpo; a API
        usa o destino aprovado na conta para o trilho escolhido.
      properties:
        rail:
          type: string
          enum:
            - BRL_PIX
            - USDT_WALLET
          description: Trilho do saque.
          example: BRL_PIX
        amount:
          type: string
          description: Valor bruto solicitado em BRL, como string decimal.
          example: '100.00'
    Withdrawal:
      type: object
      required:
        - id
        - livemode
        - rail
        - currency
        - status
        - requestedAmount
        - destination
        - quote
        - requestedAt
        - approvedAt
        - processingAt
        - completedAt
        - failedAt
        - cancelledAt
        - failure
      properties:
        id:
          type: string
          description: Identificador público do saque.
          example: wdr_4a8b3c1d5e6f2a9b0c1d
        livemode:
          type: boolean
          description: Sempre `true` para saques criados pela API.
          example: true
        rail:
          type: string
          enum:
            - BRL_PIX
            - USDT_WALLET
          example: BRL_PIX
        currency:
          type: string
          enum:
            - BRL
          example: BRL
        status:
          $ref: '#/components/schemas/WithdrawalStatus'
        requestedAmount:
          type: string
          description: Valor bruto solicitado em BRL.
          example: '100.00'
        destination:
          $ref: '#/components/schemas/WithdrawalDestination'
        quote:
          anyOf:
            - $ref: '#/components/schemas/WithdrawalQuote'
            - type: 'null'
        requestedAt:
          type: string
          format: date-time
        approvedAt:
          type:
            - string
            - 'null'
          format: date-time
        processingAt:
          type:
            - string
            - 'null'
          format: date-time
        completedAt:
          type:
            - string
            - 'null'
          format: date-time
        failedAt:
          type:
            - string
            - 'null'
          format: date-time
        cancelledAt:
          type:
            - string
            - 'null'
          format: date-time
        failure:
          anyOf:
            - $ref: '#/components/schemas/WithdrawalFailure'
            - type: 'null'
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
    WithdrawalStatus:
      type: string
      description: >-
        Estado atual do saque. `INDETERMINATE` indica um saque cujo pagamento
        ficou incerto (por exemplo, timeout ou falha após um passo irreversível)
        e que aguarda confirmação manual.
      enum:
        - REQUESTED
        - APPROVED
        - PROCESSING
        - INDETERMINATE
        - COMPLETED
        - FAILED
        - CANCELLED
    WithdrawalDestination:
      type: object
      required:
        - summary
        - label
      description: Resumo mascarado do destino usado no saque.
      properties:
        summary:
          type: string
          description: Destino mascarado para exibição segura.
          example: Pix CPF • 1234...7890
        label:
          type:
            - string
            - 'null'
          description: Rótulo ou nome associado ao destino, quando disponível.
          example: Maria Silva
    WithdrawalQuote:
      type: object
      required:
        - sourceAmount
        - sourceCurrency
        - withdrawalFeeAmount
        - withdrawalFeeCurrency
        - netSourceAmount
        - netSourceCurrency
        - destinationAmount
        - destinationCurrency
        - quotedRateBrlPerUsdt
        - quotedAt
        - quoteSource
        - network
      description: Resumo financeiro usado para calcular o valor do saque.
      properties:
        sourceAmount:
          type: string
          example: '100.00'
        sourceCurrency:
          type: string
          enum:
            - BRL
        withdrawalFeeAmount:
          type: string
          example: '0.00'
        withdrawalFeeCurrency:
          type: string
          enum:
            - BRL
        netSourceAmount:
          type: string
          example: '100.00'
        netSourceCurrency:
          type: string
          enum:
            - BRL
        destinationAmount:
          type: string
          example: '100.00'
        destinationCurrency:
          type: string
          enum:
            - BRL
            - USDT
        quotedRateBrlPerUsdt:
          type:
            - string
            - 'null'
          description: Taxa BRL/USDT quando o saque for em USDT.
          example: null
        quotedAt:
          type:
            - string
            - 'null'
          format: date-time
          description: Momento da cotação quando aplicável.
        quoteSource:
          type: string
          description: Identificador da regra/cotação aplicada.
          example: BRL_PIX_TERMS_V1
        network:
          type:
            - string
            - 'null'
          description: Rede usada quando o destino for carteira USDT.
          example: null
    WithdrawalFailure:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          example: insufficient_balance
        message:
          type:
            - string
            - 'null'
          example: available balance is insufficient for this withdrawal
    ErrorBody:
      type: object
      required:
        - type
        - code
        - message
        - requestId
      description: >-
        Corpo padronizado de erro da API. As mensagens em `message` chegam em
        inglês — é o que a API emite literalmente.
      properties:
        type:
          type: string
          description: Categoria do erro.
          enum:
            - auth_error
            - validation_error
            - business_error
            - not_found_error
            - conflict_error
            - provider_error
            - rate_limit_error
            - internal_error
          example: validation_error
        code:
          type: string
          description: Código estável para tratar a falha no seu backend.
          example: invalid_request_body
        message:
          type: string
          description: Mensagem legível do erro (em inglês, literal).
          example: Number must be greater than 0
        requestId:
          type: string
          description: Identificador da requisição para logs e investigação.
          example: req_4a8b3c1d5e6f2a9b0c1d2e3f
  headers:
    RequestIdResponseHeader:
      description: >-
        Identificador da requisição. Sempre presente. Ecoa o valor enviado em
        `Request-Id` ou `X-Request-Id`, ou um identificador gerado pela API no
        formato `req_<24 hex>`.
      schema:
        type: string
        example: req_4a8b3c1d5e6f2a9b0c1d2e3f
  responses:
    Unauthorized:
      description: >-
        Chave ausente, mal formatada, inválida ou revogada. A API sempre devolve
        `code: "unauthorized"` em 401.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestIdResponseHeader'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            unauthorized:
              summary: Bearer ausente ou inválido
              value:
                error:
                  type: auth_error
                  code: unauthorized
                  message: invalid or missing bearer token
                  requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
    RateLimited:
      description: Limite de requisições excedido. Faça retry com backoff.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestIdResponseHeader'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rateLimited:
              summary: Limite excedido
              value:
                error:
                  type: rate_limit_error
                  code: rate_limit_exceeded
                  message: Too many requests. Please retry with backoff.
                  requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key

````