# 1. Function Introduction

    ​ The OTC withdrawal API allows merchants to obtain a quote for cryptocurrency and fiat currency. After receiving a valid quote, the merchant can sell the held cryptocurrency via OTC and settle the fiat funds into a designated bank account. This API is available to Gate Pay merchants only.

    # 2. API List

    # 2.1 Get Quote

    • API Description: Before creating a fiat withdrawal order, merchants must first request a quote to obtain an executable price and its validity period. During the validity period, the quote token locks the exchange rate, amount, and currency. Once a quote is successfully obtained, the merchant must execute the quote using the quote token within the validity period to create an order.

    • Data Type: JSON (content-type: application/json)

    • Request Method: POST

    • Path: /withdraw/open/otc/api/v1/quote

    • Authentication Method: Signature Verification

    • Request Body:

    Field Name Type Required Description
    cryptoCurrency string Yes Cryptocurrency. Currently supported: USDT only
    fiatCurrency string Yes Fiat currency. Currently supported: USD only
    cryptoAmount string No Cryptocurrency amount. Required when side is CRYPTO
    fiatAmount string No Fiat amount. Required when side is FIAT
    side string Yes Quote Direction: CRYPTO: Quote based on cryptocurrency amount (cryptoAmount is required) FIAT: Quote based on fiat amount (fiatAmount is required)
    promotionCode string No Promotion code
    type string Yes BUY: Deposit SELL: Withdrawal Currently supported: SELL only
    • Response Body:
    Field Name Type Description
    cryptoCurrency string Cryptocurrency
    fiatCurrency string Fiat currency
    cryptoAmount string Cryptocurrency amount
    fiatAmount string Fiat amount
    fiatRate string Fiat exchange rate (fiat/crypto)
    cryptoRate string Crypto exchange rate (crypto/fiat)
    validPeriod integer Quote validity period, in seconds
    quoteToken string Quote token, used to place an order

    CURL Request

    curl --location --request POST 'https://openplatform.gateapi.io/withdraw/open/otc/api/v1/quote' \\
    --header 'X-GatePay-Certificate-ClientId: sTTGwlmQBGMpwaLg' \\
    --header 'X-GatePay-Timestamp: 1769588949' \\
    --header 'x-GatePay-Nonce: 2730095202' \\
    --header 'x-GatePay-Signature: 7f780aa07e120dda16f0b0139e86a32ebe9833f10b3bf75fafc55dea46658e14a3f18078fa45ecfd9b81b4edf2c0bc91d1d9dc9ca4de5eed3189437f8e31fd69' \\
    --header 'Content-Type: application/json' \\
    --data-raw '{
    "cryptoCurrency": "USDT",
    "fiatCurrency": "USD",
    "cryptoAmount": "1000",
    "side": "CRYPTO",
    "type": "SELL"
    }'
    

    Response:

    {
      "code": "",
      "data": {
        "cryptoCurrency": "USDT",
        "fiatCurrency": "USD",
        "cryptoAmount": "10000",
        "fiatAmount": "9898.72",
        "fiatRate": "0.989872",
        "cryptoRate": "1.01023613",
        "validPeriod": 300,
        "quoteToken": "adhk543"
      },
      "status": "",
      "label": "",
      "errorMessage": ""
    }
    

    # 2.2 Create Order

    • API Description: After obtaining a quote, the merchant must execute the quote within its validity period to create a fiat withdrawal order.

    • Data Type: JSON (content-type: application/json)

    • Request Method: POST

    • Path: /withdraw/open/otc/api/order/create

    • Authentication Method: Signature Verification

    • Request Body:

    Field Name Type Required Description
    quoteToken string Yes Quote token
    bankAccountId string Yes Bank account ID
    cryptoCurrency string Yes Cryptocurrency
    fiatCurrency string Yes Fiat currency
    cryptoAmount string Yes Cryptocurrency amount
    fiatAmount string Yes Fiat amount
    type string Yes BUY: Deposit SELL: Withdrawal Currently supported: SELL only
    clientOrderId string Yes Merchant Order Number; Create order failed, please change the order number
    • Response Body:
    Field Name Type Description
    orderId string Order ID
    status string Order status
    createTime integer Creation Time
    clientOrderId string Merchant Order Number

    CURL Request

    curl --location --request POST 'https://openplatform.gateapi.io/withdraw/open/otc/api/order/create' \\
    --header 'Content-Type: application/json' \\
    --header 'X-GatePay-Certificate-ClientId: sTTGwlmQBGMpwaLg' \\
    --header 'X-GatePay-Timestamp: 1769669668127' \\
    --header 'x-GatePay-Nonce: 7508857261' \\
    --header 'x-GatePay-Signature: 9636bd4c3edac24af5ea2b410c38aa0bafc7e73d6333158205a3f3652cfd97e2a94e38a259a057bee565889b1c686a22b03943a196c19d1eaa43ecb5a045cec1' \\
    --data-raw '{
    "cryptoCurrency": "USDT",
    "fiatCurrency": "USD",
    "cryptoAmount": "10000",
    "fiatAmount": "9800",
    "type": "SELL",
    "quoteToken": "qdfh34543",
    "bankAccountId": "2897434"
    }'
    

    Response:

    {
      "code": "000000",
      "data": {
        "orderId": "2016768770965639168",
        "status": "PROCESSING",
        "createTime": 1769670119407
      },
      "status": "SUCCESS",
      "errorMessage": ""
    }
    

    # 2.3 Query Order Details

    • API Description: After a quote is executed and an order is successfully created, merchants can query the order status and related details using the returned order ID.

    • Data Type: JSON (content-type: application/json)

    • Request Method: GET

    • Path: /withdraw/open/otc/api/order/detail

    • Authentication Method: Signature Verification

    • Request Parameters:

    Field Name Type Required Description
    orderId string No Order ID.Required when clientOrderId is null
    clientOrderId string No Merchant Order Number.Required when orderId is null
    • Response Body:
    Field Name Type Description
    orderId string Order ID
    status string Order Status: PROCESSING: Processing FAIL: Failure DONE: Success DISPATCHED: Dispatched
    cryptoCurrency string Cryptocurrency
    fiatCurrency string Fiat currency
    type string BUY: Deposit SELL: Withdrawal
    cryptoAmount string Cryptocurrency amount
    fiatAmount string Fiat amount
    fiatRate string Fiat exchange rate (fiat/crypto)
    bankAccountId string Bank Account ID
    createTime integer Creation Time
    updateTime integer Last update time
    clientOrderId string Merchant Order Number
    errMsg string Failure reason
    tradeFee string Fee (in same currency as fiatCurrency)
    finalFiatAmount string Net amount (in same currency as fiatCurrency)

    CURL Request

    curl --location --request GET 'https://openplatform.gateapi.io/withdraw/open/otc/api/order/detail?orderId=35599620284481595' \\
    --header 'Content-Type: application/json' \\
    --header 'X-GatePay-Certificate-ClientId: sTTGwlmQBGMpwaLg' \\
    --header 'X-GatePay-Timestamp: 1769670845426' \\
    --header 'x-GatePay-Nonce: 9099836565' \\
    --header 'x-GatePay-Signature: 3eef45b012cf9710eb06587775f5fc2807b7445fb0fdd3c830cf453ee07b34824c0b4bf187a1ad783f886c592b04da7b0ab5d8bf47b8741c82bd408db7b811b4'
    

    Response:

    {
      "code": "000000",
      "data": {
        "cryptoCurrency": "USDT",
        "fiatCurrency": "USD",
        "cryptoAmount": "100000",
        "fiatAmount": "99810.08",
        "orderId": "35599620284481595",
        "status": "DONE",
        "createTime": 1761205415973,
        "updateTime": 1761205416189,
        "bankAccountId": "123141284812832183",
        "type": "SELL",
        "fiatRate": "0.9981"
      },
      "status": "SUCCESS",
      "errorMessage": ""
    }
    

    # 2.4 Query Order List

    • API Description: After executing quotes and creating orders, merchants can query order status and related details in batches using the returned order ID.

    • Data Type: JSON (content-type: application/json)

    • Request Method: POST

    • Path: /withdraw/open/otc/api/order/list

    • Authentication Method: Signature Verification

    • Request Body:

    Field Name Type Required Description
    status string No Order Status: PROCESSING: Processing FAIL: Failure DONE: Success DISPATCHED: Dispatched
    type string No BUY: Deposit SELL: Withdrawal
    cryptoCurrency string No Cryptocurrency
    fiatCurrency string No Fiat currency
    startTime string No Start time (creation time)
    endTime string No End time (creation time)
    page integer No Page number, default 1
    pageSize integer No Page size, default 10, maximum 500
    clientOrderId string No Merchant Order Number
    • Response Body:
    Field Name Type Description
    data array Order list
    data[].order_id string Order ID
    data[].status string Order Status: PROCESSING: Processing FAIL: Failure DONE: Success DISPATCHED: Dispatched
    data[].cryptoCurrency string Cryptocurrency
    data[].fiatCurrency string Fiat currency
    data[].bankAccountId string Bank Account ID
    data[].cryptoAmount string Cryptocurrency amount
    data[].fiatAmount string Fiat amount
    data[].fiatRate string Fiat exchange rate (Fiat/Crypto)
    data[].createTime integer Creation Time
    data[].updateTime integer Last update time
    data[].type string BUY: Deposit SELL: Withdrawal
    data[].clientOrderId string Merchant Order Number
    data[].errMsg string Failure reason
    data[].tradeFee string Fee (in same currency as fiatCurrency)
    data[].finalFiatAmount string Net amount (in same currency as fiatCurrency)
    page integer Current page
    pageSize integer Page size
    total integer Total records

    CURL Request

    curl --location --request POST 'https://openplatform.gateapi.io/withdraw/open/otc/api/order/list' \\
    --header 'Content-Type: application/json' \\
    --header 'X-GatePay-Certificate-ClientId: sTTGwlmQBGMpwaLg' \\
    --header 'X-GatePay-Timestamp: 1769671300600' \\
    --header 'x-GatePay-Nonce: 8907767296' \\
    --header 'x-GatePay-Signature: ec0102f15ced90319c02c8feb24ee81d0e9a701a2078c7b7fbfe68b9216611a6eaa2a67aa37d964b3cc9e491a3cfa8eee07c736d22b8d92fdd0f16e0bc316a4a' \\
    --data-raw '{
    "page": 1,
    "pageSize": 10
    }'
    

    Response:

    {
      "code": "000000",
      "data": {
        "page": 1,
        "pageSize": 10,
        "total": 49,
        "data": [
          {
            "cryptoCurrency": "USDT",
            "fiatCurrency": "USD",
            "cryptoAmount": "10000",
            "fiatAmount": "99810.08",
            "orderId": "2016769960466059264",
            "status": "DONE",
            "createTime": 1769670404763,
            "updateTime": 1769670720469,
            "type": "SELL",
            "bankAccountId": "2897434",
            "fiatRate": "0.9981",
            "clientOrderId": "980932432"
          },
          {
            "cryptoCurrency": "USDT",
            "fiatCurrency": "USD",
            "cryptoAmount": "10000",
            "fiatAmount": "99810.08",
            "orderId": "2016768770965639168",
            "status": "DONE",
            "createTime": 1769670119407,
            "updateTime": 1769670300606,
            "type": "SELL",
            "bankAccountId": "2897434",
            "fiatRate": "0.9981",
            "clientOrderId": "980932433"
          }
        ]
      },
      "status": "SUCCESS",
      "errorMessage": ""
    }
    

    # 2.5 Query List of Available Countries for Bank Cards

    • API Description:If you need to add a bank account, you may first query the list of available countries for bank account registration.

    • Data Type: JSON (content-type: application/json)

    • Request Method: GET

    • Path: /withdraw/open/otc/api/bank/country/list

    • Authentication Method: Signature Verification

    • Request Parameters:

    • Response Body:

    Field Name Type Description
    data array Countriy List
    data[].countryId int Country ID
    data[].countryName string Country name
    data[].countryCn string Country name (Chinese)

    CURL Request

    curl --location --request GET 'https://openplatform.gateapi.io/withdraw/open/otc/api/bank/country/list' \
    --header 'Content-Type: application/json' \
    --header 'X-GatePay-Certificate-ClientId: sTTGwlmQBGMpwaLg' \
    --header 'X-GatePay-Timestamp: 1769671300600' \
    --header 'x-GatePay-Nonce: 8907767296' \
    --header 'x-GatePay-Signature: ec0102f15ced90319c02c8feb24ee81d0e9a701a2078c7b7fbfe68b9216611a6eaa2a67aa37d964b3cc9e491a3cfa8eee07c736d22b8d92fdd0f16e0bc316a4a' \
    
    

    Response:

    {
      "code": "000000",
      "data": [
        {
          "countryId": 260,
          "countryCn": "阿富汗",
          "countryName": "Afghanistan"
        },
        {
          "countryId": 3,
          "countryCn": "阿尔巴尼亚",
          "countryName": "Albania"
        },
        {
          "countryId": 4,
          "countryCn": "阿尔及利亚",
          "countryName": "Algeria"
        }
      ],
      "status": "SUCCESS",
      "errorMessage": ""
    }
    

    # 2.6 Create Bank Account

    • API Description:A bank account must be added for OTC fiat withdrawal; the bank statement must be uploaded at the same time when adding a new bank account.

    • Data Type:JSON (content-type:multipart/form-data)

    • Request Method:POST

    • Path: /withdraw/open/otc/api/bank/create

    • Authentication Method:Signature Verification

    • Request Parameters:

    Field Name Type Required Description
    bankAccountName string Yes Account holder name
    bankName string Yes Bank name
    countryId int Yes Country ID
    address string Yes Bank address
    iban string Yes IBAN
    swift string Yes SWIFT
    remittanceLineNumber string No Routing / clearing code
    agentBankName string No Agent bank name
    agentBankSwift string No Agent bank SWIFT
    file file Yes File stream,max size 4MB,only suppot jpg、jpeg、png; A bank statement issued within the last 3 months. The account holder's name must exactly match the name used for identity verification. If discrepancies arise due to language or other reasons, supporting documents must be provided (e.g., a bank certificate, a passport, an official name change document)
    • Response Body:
    Field Name Type Description
    bankAccountId string Bank Account ID

    CURL Request

    curl --location --request POST 'https://openplatform.gateapi.io/withdraw/open/otc/api/bank/create' \
    --header 'X-GatePay-MerchantId;' \
    --form 'bankAccountName="bank001"' \
    --form 'bankName="bankName01"' \
    --form 'countryId="260"' \
    --form 'address="123"' \
    --form 'iban="123213213"' \
    --form 'swift="21321"' \
    --form 'remittanceLineNumber="312"' \
    --form 'agentBankName="213"' \
    --form 'agentBankSwift="454"' \
    --form 'file=@"/Downloads/bank.jpg"'
    

    Response:

    {
      "code": "000000",
      "data": {
        "bankAccountId": "2897434"
      },
      "status": "SUCCESS",
      "errorMessage": ""
    }
    

    # 2.7 List Bank Accounts

    • API Description:Returns all bank account details bound to the merchant

    • Data Type: JSON (content-type: application/json)

    • Request Method: GET

    • Path: /withdraw/open/otc/api/bank/list

    • Authentication Method: Signature Verification

    • Request Parameters: (Fuzzy Query)

    Field Name Type Required Description
    bankAccountName string No Account holder name
    iban string No IBAN
    swift string No SWIFT
    bankName string No Bank name
    • Response Body:
    Field Name Type Description
    data array Bank List
    data[].bankAccountId string Bank Account ID
    data[].bankAccountName string Account holder name
    data[].bankName string Bank name
    data[].countryId int Country ID
    data[].countryName string Country Name
    data[].address string Bank address
    data[].iban string IBAN
    data[].swift string SWIFT
    data[].remittanceLineNumber string Routing / clearing code
    data[].agentBankName string Agent bank name
    data[].agentBankSwift string Agent bank SWIFT

    CURL Request

    curl --location --request GET 'https://openplatform.gateapi.io/withdraw/open/otc/api/bank/list?bankAccountName=bank001&bankName=bankName01&iban=123213213&swift=21321' \
    --header 'Content-Type: application/json' \
    --header 'X-GatePay-Certificate-ClientId: sTTGwlmQBGMpwaLg' \
    --header 'X-GatePay-Timestamp: 1769671300600' \
    --header 'x-GatePay-Nonce: 8907767296' \
    --header 'x-GatePay-Signature: ec0102f15ced90319c02c8feb24ee81d0e9a701a2078c7b7fbfe68b9216611a6eaa2a67aa37d964b3cc9e491a3cfa8eee07c736d22b8d92fdd0f16e0bc316a4a' \
    
    

    Response:

    {
      "code": "000000",
      "data": [
        {
          "bankAccountId": 501,
          "bankAccountName": "12312",
          "bankName": "123123",
          "countryId": 260,
          "countryName": "Afghanistan",
          "address": "123123",
          "iban": "12313123",
          "swift": "123132123",
          "remittanceLineNumber": "3123123",
          "agentBankName": "",
          "agentBankSwift": ""
        },
        {
          "bankAccountId": 642,
          "bankAccountName": "testname",
          "bankName": "123123",
          "countryId": 11,
          "countryName": "Australia",
          "address": "123123",
          "iban": "UYTU****GFHG",
          "swift": "13123",
          "remittanceLineNumber": "1231",
          "agentBankName": "",
          "agentBankSwift": ""
        }
      ],
      "status": "SUCCESS",
      "errorMessage": ""
    }
    

    # 2.8 Delete Bank Account

    • API Description:Deletes a specified bank account

    • Data Type: JSON (content-type: application/json)

    • Request Method: POST

    • Path: /withdraw/open/otc/api/bank/delete

    • Authentication Method: Signature Verification

    • Request Parameters:

    Field Name Type Required Description
    bankAccountId string Yes Bank Account ID

    CURL Request

    curl --location --request POST 'https://openplatform.gateapi.io/withdraw/open/otc/api/bank/delete' \
    --header 'Content-Type: application/json' \
    --header 'X-GatePay-Certificate-ClientId: sTTGwlmQBGMpwaLg' \
    --header 'X-GatePay-Timestamp: 1769671300600' \
    --header 'x-GatePay-Nonce: 8907767296' \
    --header 'x-GatePay-Signature: ec0102f15ced90319c02c8feb24ee81d0e9a701a2078c7b7fbfe68b9216611a6eaa2a67aa37d964b3cc9e491a3cfa8eee07c736d22b8d92fdd0f16e0bc316a4a' \
    --data-raw '{
        "bankAccountId": 796
    }'
    

    Response:

    {
      "code": "000000",
      "data": {},
      "status": "SUCCESS",
      "errorMessage": ""
    }
    

    # 3. Order Status Asynchronous Notification

    # 3.1 Order Status Change Asynchronous Notification

    1. When OTC order status changes (e.g., withdrawal success, withdrawal failure, etc.), GatePay will send order status notifications to the merchant. The notification URL is the callback url parameter provided during merchant registration.

    2. If notification fails due to network or other unknown reasons, GatePay will retry at 15 seconds, 30 seconds, 3 minutes, 10 minutes, 20 minutes, 30 minutes, 60 minutes, 3 hours, and 6 hours. If retries also fail, the merchant can call the order query API to obtain the order status.

    3. When receiving asynchronous notification messages, the merchant must verify the message signature to validate the authenticity of the message.Refer to API Signature for security verification

    # 3.2 Message Structure

    Field Name Type Description
    bizType string Notification type. Fixed value: OTC
    bizId string Order ID
    bizStatus string Notification status: WITHDRAW_SUCCESS, WITHDRAW_FAIL, WITHDRAW_DISPATCHED
    clientId string Client ID of the merchant who created the order
    data string Message content

    Message structure example:

    {
        "bizType":"OTC",
        "bizId":"6948484859590",
        "bizStatus":"WITHDRAW_SUCCESS",
        "clientId":"cdhu-fgrfg44-5ggd-cdvsa",
        "data":"{...Json format data...}"
    }
    

    After receiving the asynchronous callback message, the merchant must respond to confirm successful receipt. Message structure example:

    {
        "returnCode": "SUCCESS",
        "returnMessage": ""
    }
    

    # 3.3 Data Structure

    Field Name Type Description
    orderId string Order ID
    clientOrderId string Merchant Order Number
    fiatRate string Fiat exchange rate (fiat/crypto)
    type string BUY: Deposit SELL: Withdrawal Currently supported: SELL only
    fiatCurrency string Fiat currency
    fiatAmount string Estimated fiat amount
    cryptoCurrency string Cryptocurrency
    cryptoAmount string Cryptocurrency amount
    updateTime string Last update time
    errMsg string Failure reason
    tradeFee string Fee (in same currency as fiatCurrency)
    finalFiatAmount string Net amount (in same currency as fiatCurrency)

    # 4. Error Code

    Error Code Description Solution
    400001 Invalid request parameters Check if the request parameters are valid
    400002 Signature verification failed Check if the merchant signature is correct
    400003 Request timestamp expired Check the timestamp field in the request header
    400004 API credential does not exist or is invalid Check if the API credential exists or is valid
    400611 Insufficient balance Check the account balance
    550175 Order does not exist Check if the order was initiated or if the order ID is correct
    5503001 API rate limit exceeded Retry later
    5502961 Service unavailable in user's country Check if the service is allowed in the user's country
    5502971 User is not eligible for OTC trading Check the user's OTC trading eligibility
    5502761 ClientOrderId is duplicated Change clientOrderId
    550018 Rejected by risk control Retry later
    400000 Unknown error Internal system error
    550301 The user has not completed the relevant Global OTC authentication -
    550302 The user has not completed the individual OTC professional certification application -
    550303 The user has not completed the enterprise OTC professional certification application -
    550304 The user's OTC professional certification application has been rejected -
    550305 The user's OTC professional certification has been frozen -
    550306 The user's professional certification is under review -
    550307 The user's transaction limit is insufficient, an application for limit increase is required -
    550308 The user's limit increase application is under review -
    550309 The limit increase application has been rejected, please reapply -
    550310 The user has not bound a bank card Please bind a bank account and try again
    550311 The current operation is restricted, please contact customer service for handling -
    550312 Cryptocurrency withdrawal is prohibited -
    550313 The inquiry has expired Please requote and place the order with the new token
    550314 idempotency check failed -
    550315 Amount out of range Please adjust the quotation amount. For details, contact customer service
    550316 Create bank account failed -
    550317 Delete bank account failed -
    550318 Invalid promotion code Please use a valid promotion code