Skip to main content
Search

API: Create Verify

Where should I integrate

Wallet Verify - Unhosted Wallet Verification

Please submit the following payload to this endpoint:

curl --silent --location --request POST "/api/verify/wallet/verify" \
--cert-type P12 --cert ./certificate.p12:'[MY_PASSWORD_OF_CERT]' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer [YOUR LOGIN TOKEN]" \
--header "Connection: keep-alive" \
--data-raw "{
\"requestId\": \"[GENERATE YOUR REQUEST ID]\",
\"beneficiaryAddress\": {
\"address\": \"[TARGET ADDRESS]\",
\"tag\":\"[TARGET TAG: LEAVE EMPTY IF NO NEED]\"
},
\"originatorAddress\": {
\"address\": \"[TARGET ADDRESS]\",
\"tag\":\"[TARGET TAG: LEAVE EMPTY IF NO NEED]\"
},
\"blockchainInfo\": {
\"network\": \"[NETWORK SYMBOL]\",
\"ticker\": \"[TICKER SYMBOL]\",
\"txId\": \"[IF ITS DEPOSIT, PLEASE FILL TXID, OR LEAVE IT EMPTY STRING OR UNSET]\"
},
\"complianceInfo\": {
\"amount\": \"[AMOUNT OF CRYPTO CURRENCY TICKER]\",
\"fiatPrice\": \"[FIAT PRICE]\",
\"fiatName\": \"[FIAT NAME]\"
},
\"sourceVaspCode\": \"[ONLY TRSP VENDOR NEED TO FILL THIS, IGNORE IF YOU'RE VASP/EXCHANGE]\"
}"

⚠️ Address is case-sensitive

The address field in beneficiaryAddress / originatorAddress must be submitted with its original casing, exactly as the wallet owner will present it when they sign.

  • This applies to every supported network, including EVM-compatible chains (Ethereum, BSC, Polygon, etc.) where the address itself is not case-sensitive at the protocol level.
  • The underlying wallet-verify mechanism enables case-sensitive matching for all networks. If the casing you submit here does not exactly match the casing the wallet owner signs with, GTR cannot broadcast / dispatch the signing request to that wallet, and the verification will not proceed.
  • Do not normalize the address to lowercase or uppercase before submission. Preserve the checksummed / mixed-case form (e.g. EIP-55 for EVM chains).

You can expect to get following response. Please render the qrCodeContent as an image to your VASP user.

Your service will be awaiting the Unhosted Wallet Owner to sign a message after they scan the QR Code and connect the wallet.

GTR will notify you of the result or the expiration.

You are supposed to hold this transfer before your service receives the callback from GTR.

{
"verifyStatus": 100000,
"verifyMessage": "Success",
"data": {
"qrCodeContent": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"qrcodeExpiredAt": "[Timestamp of the current QR Code expiration, for this single QR code session only, e.g. 192848184313]",
"verifyExpiredAt": "[Timestamp of the hard expiration of this wallet verify request. After this time, the same requestId cannot be re-issued, e.g. 192848244313]"
}
}

Expiration fields

  • qrcodeExpiredAt: expiration time of the current QR code session. After this timestamp, your service may call the create verify API again with the same requestId to get a fresh QR code.
  • verifyExpiredAt: the hard expiration time for the wallet verification request. After this timestamp, the same requestId is no longer valid for issuing a new QR code. A new request must be initiated with a new requestId.

About address screening

This API does not return screeningResult in its synchronous response.

If the wallet owner later completes the signing flow successfully, GTR may perform address screening on the verified address and include that result in the callback to your service.

That means:

  • The create-verify API response is only for QR code session creation.
  • The screening result, if available, should be consumed from the Wallet Verify callback flow.