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

# Execute a withdrawal

> Converts stablecoins held in your managed wallet to fiat and pays out to the bank account.

In one call we: validate `paymentMethodData`; set up the payout with the provider (the recipient's account name is verified **before** any funds move); check the rate against your quote (rejects if it moved beyond tolerance); then send the stablecoin from your wallet. The response is `funds_sent`; everything after is asynchronous.

**Idempotent:** retrying with the same `reference` and `sessionId` returns the same withdrawal and never sends twice. A `reference` reused with a different quote returns 409. A quote can be used once.

**Failure before funds move** (name mismatch, rate moved, provider rejection) leaves the withdrawal `failed` with `failureStage`; nothing is debited. **Webhook events:** `offramp.created`, `offramp.funds_sent`, `offramp.processing`, `offramp.completed`, `offramp.failed`, `offramp.refund_required`, `offramp.refunded`.

**Flow:** `GET /currencies` → `GET /assets` → `GET /payment-methods` (render the JSON Schema; for NGN/GHS get `bankCode`s from `GET /banks`) → `POST /quotes` (rate lock, ~2 min) → `POST /withdrawals` → track via `offramp.*` webhooks or `GET /withdrawals/{id}`.

**Routing is automatic:** NGN/GHS are paid out through our local African corridor; USD (wire/ACH) and EUR (SEPA) through our global corridor. USD/EUR payouts require an onboarded `customerId` (see Customer Onboarding).



## OpenAPI

````yaml /api-reference/openapi.json post /v1/offramp/withdrawals
openapi: 3.0.3
info:
  title: XentFi API
  version: 1.0.0
  description: >-
    API documentation for XentFi.The XentFi API gives you access to pretty much
    all the features you can use on our dashboard and lets you extend them for
    use in your application. It strives to be RESTful and is organized around
    the main resources you would be interacting with - with a few notable
    exceptions.
servers:
  - url: https://api.xentfi.com
    description: Production server
security: []
tags: []
paths:
  /v1/offramp/withdrawals:
    post:
      tags:
        - Off-ramp
      summary: Execute a withdrawal
      description: >-
        Converts stablecoins held in your managed wallet to fiat and pays out to
        the bank account.


        In one call we: validate `paymentMethodData`; set up the payout with the
        provider (the recipient's account name is verified **before** any funds
        move); check the rate against your quote (rejects if it moved beyond
        tolerance); then send the stablecoin from your wallet. The response is
        `funds_sent`; everything after is asynchronous.


        **Idempotent:** retrying with the same `reference` and `sessionId`
        returns the same withdrawal and never sends twice. A `reference` reused
        with a different quote returns 409. A quote can be used once.


        **Failure before funds move** (name mismatch, rate moved, provider
        rejection) leaves the withdrawal `failed` with `failureStage`; nothing
        is debited. **Webhook events:** `offramp.created`, `offramp.funds_sent`,
        `offramp.processing`, `offramp.completed`, `offramp.failed`,
        `offramp.refund_required`, `offramp.refunded`.


        **Flow:** `GET /currencies` → `GET /assets` → `GET /payment-methods`
        (render the JSON Schema; for NGN/GHS get `bankCode`s from `GET /banks`)
        → `POST /quotes` (rate lock, ~2 min) → `POST /withdrawals` → track via
        `offramp.*` webhooks or `GET /withdrawals/{id}`.


        **Routing is automatic:** NGN/GHS are paid out through our local African
        corridor; USD (wire/ACH) and EUR (SEPA) through our global corridor.
        USD/EUR payouts require an onboarded `customerId` (see Customer
        Onboarding).
      operationId: createOfframpWithdrawal
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - sessionId
                - reference
                - paymentMethod
                - paymentMethodData
              properties:
                sessionId:
                  type: string
                  format: uuid
                reference:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{8,64}$
                  description: Your unique idempotency reference
                paymentMethod:
                  type: string
                  example: bank_transfer
                paymentMethodData:
                  type: object
                  description: Validated against the payment method's schema
                  example:
                    bankCode: 58
                    accountNumber: 123456789
                    accountHolderFirstName: Ada
                    accountHolderLastName: Obi
                customerId:
                  type: string
                  format: uuid
                  description: Required for USD/EUR — an onboarded customer
                note:
                  type: string
                metadata:
                  type: object
      responses:
        '201':
          description: Withdrawal accepted and funded
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      reference:
                        type: string
                      status:
                        type: string
                        enum:
                          - initiated
                          - awaiting_funds
                          - funding
                          - funds_sent
                          - processing
                          - completed
                          - refund_required
                          - refunded
                          - failed
                      walletId:
                        type: string
                      assetId:
                        type: string
                      customerId:
                        type: string
                        nullable: true
                      currency:
                        type: string
                      paymentMethod:
                        type: string
                      sourceAmount:
                        type: string
                      fiatAmount:
                        type: string
                      rate:
                        type: string
                      fee:
                        type: string
                      recipient:
                        type: object
                        nullable: true
                        description: 'Masked: account numbers show last 4 digits only'
                      transactionHash:
                        type: string
                        nullable: true
                        description: On-chain hash of the funding transfer from your wallet
                      failureReason:
                        type: string
                        nullable: true
                      failureStage:
                        type: string
                        nullable: true
                        enum:
                          - provider_setup
                          - rate_moved
                          - funding
                          - provider
                          - abandoned
                      refundDetailsRequired:
                        type: boolean
                      note:
                        type: string
                        nullable: true
                      metadata:
                        type: object
                        nullable: true
                      createdAt:
                        type: string
                        format: date-time
                      updatedAt:
                        type: string
                        format: date-time
                      completedAt:
                        type: string
                        format: date-time
                        nullable: true
        '400':
          description: >-
            Validation / name mismatch / funding failed (details.transactionId
            set when a record exists)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: NOT_FOUND
                      message:
                        type: string
                        example: Wallet not found
                      timestamp:
                        type: string
                        format: date-time
                      requestId:
                        type: string
        '404':
          description: Quote session or customer not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: NOT_FOUND
                      message:
                        type: string
                        example: Wallet not found
                      timestamp:
                        type: string
                        format: date-time
                      requestId:
                        type: string
        '409':
          description: >-
            Quote used/expired, rate moved, reference conflict, or customer not
            approved
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: NOT_FOUND
                      message:
                        type: string
                        example: Wallet not found
                      timestamp:
                        type: string
                        format: date-time
                      requestId:
                        type: string
      security:
        - ApiKeyAuth: []
          OrgIdAuth: []
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: apiKey
    OrgIdAuth:
      type: apiKey
      in: header
      name: orgId

````

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