---
title: "Transfer an NFT"
method: POST
path: "/v3/nft/transaction"
tags: ["NFT (ERC-721 or compatible)"]
---

# Transfer an NFT

`POST /v3/nft/transaction`

## Request

- Base URL: `https://api.tatum.io`
- URL: `https://api.tatum.io/v3/nft/transaction`
- Auth: API key in header `x-api-key`

/v3/nft/transaction

**2 credits per API call**

Transfer an NFT from the smart contract (the `contractAddress` parameter in the request body) to the specified blockchain address (the `to` parameter in the request body).

In one API call, you can transfer only one NFT.

This API is supported for the following blockchains:

*   Algorand
*   BNB Smart Chain
*   Celo
*   Ethereum
*   Harmony
*   Klaytn
*   KuCoin Community Chain
*   Polygon
*   Solana
*   TRON
*   Tezos
*   Flare
*   Cronos
*   Base
*   Avalanche
*   Fantom
*   Optimism

For Ethereum, Celo, Flare and BNB Smart Chain, transferring NFTs invokes the `safeTransfer()` method.

**Transferring NFTs on Algorand**

*   On Algorand, the recipient has to agree in advance to receive your NFT because Algorand charges users for storing NFTs on their addresses, and an Algorand blockchain address by default does not receive NFTs unless explicitly agreed. Before transferring an NFT, make sure that the recipient [has agreed to receive the NFT](https://apidoc.tatum.io/tag/Algorand#operation/AlgorandBlockchainReceiveAsset) to their address.
*   If you want to transfer an NFT that [was minted using NFT Express](#operation/NftMintErc721), use the `transferNftAlgoExpress` schema of the request body.  
    **NOTE:** On the **mainnet**, Tatum covers your transaction fees for the NFT transfer and pays for them from its own blockchain address. Then, the fee amount paid by Tatum is converted to the number of credits, and these credits are deducted from the monthly credit allowance of your paid pricing plan. On the **testnet**, only one credit is deducted from the monthly credit allowance for transaction fee.

**Transferring NFTs on Solana**  
If you want to transfer an NFT that [was minted using NFT Express](#operation/NftMintErc721), use the `transferNftSolana` or `transferNftSolanaKMS` schema of the request body. In the request body:

*   Set the `from` parameter to the address that you used in the `to` parameter in the request body of the minting call.
*   Set the `to` parameter to the recipient's address.
*   Set the `contractAddress` parameter to the address from the `nftAddress` parameter returned in the response body of the minting call.
*   Set the `fromPrivateKey`/`signatureId` parameter to the private key/signature ID of the blockchain address that you specified in the `from` parameter.

**Signing a transaction**  
When transferring an NFT, you are charged a fee for the transaction, and you must sign the transaction with the private key of the blockchain address from which the fee will be deducted.

Providing the private key in the API is not a secure way of signing transactions, because the private key can be stolen or exposed. Your private keys should never leave your security perimeter. You should use the private keys only for testing a solution you are building on the **testnet** of a blockchain.

For signing transactions on the **mainnet**, we strongly recommend that you use the Tatum [Key Management System (KMS)](https://github.com/tatumio/tatum-kms) and provide the signature ID instead of the private key in the API. Alternatively, you can use the [Tatum JavaScript client](https://github.com/tatumio/tatum-js/tree/v2).

**NOTE:** This does not apply to transferring NFTs that were minted on Algorand using NFT Express (see earlier in this section).

## Query parameters

- `testnetType` 'ethereum-sepolia' | 'flare-coston' | 'flare-coston2' | 'flare-songbird': Specifies the testnet type. The default is ethereum-sepolia for Ethereum (ETH) currency and flare-coston for Flare (FLR) currency. Valid testnet types depend on the specified currency.

## Headers

- `x-testnet-type` Schema (unresolved $ref)

## Request body

- union
  - TransferNft
    - `chain` 'ETH' | 'MATIC' | 'KCS' | 'ONE' | 'KLAY' | 'BSC' | 'FLR' | 'CRO' | 'BASE' | 'AVAX' | 'OPTIMISM' | 'FTM', required: The blockchain to work with
    - `to` string, required: Blockchain address to send NFT token to
    - `tokenId` string, uint256, required: ID of the token.
    - `contractAddress` string, required: Address of NFT token
    - `fromPrivateKey` string, required: Private key of sender address. Private key, or signature Id must be present.
    - `nonce` number: The nonce to be set to the transaction; if not present, the last known nonce will be used
    - `fee` CustomFee: The custom defined fee; if not present, will be calculated automatically
      - `gasPrice` string, required: The price for one gas unit (in Gwei)
      - `gasLimit` string, required: The maximum number of gas units that you are willing to spend on processing the transaction at the provided gas price
  - TransferNftCelo
    - `chain` 'CELO', required: The blockchain to work with
    - `to` string, required: Blockchain address to send NFT token to
    - `tokenId` string, uint256, required: ID of the token.
    - `contractAddress` string, required: Address of NFT token
    - `fromPrivateKey` string, required: Private key of sender address. Private key, or signature Id must be present.
    - `nonce` number: The nonce to be set to the transaction; if not present, the last known nonce will be used
    - `feeCurrency` 'CELO' | 'CUSD' | 'CEUR', required: The currency in which the transaction fee will be paid
    - `fee` CustomFee: The custom defined fee; if not present, will be calculated automatically
      - `gasPrice` string, required: The price for one gas unit (in Gwei)
      - `gasLimit` string, required: The maximum number of gas units that you are willing to spend on processing the transaction at the provided gas price
  - TransferNftTron
    - `chain` 'TRON', required: The blockchain to work with
    - `to` string, required: Blockchain address to send NFT token to
    - `tokenId` string, uint256, required: ID of the token.
    - `contractAddress` string, required: Address of NFT token
    - `fromPrivateKey` string, required: Private key of sender address. Private key, or signature Id must be present.
    - `feeLimit` number, required: The maximum amount to be paid as the transaction fee (in TRX)
  - TransferNftSolana
    - `chain` 'SOL', required: The blockchain to work with
    - `from` string, required: The blockchain address to send the NFT from; this is the address that you used in the <code>to</code> parameter in the request body of the <a href="#operation/NftMintErc721">minting call</a>; from this address, the transaction fee will be paid
    - `to` string, required: The blockchain address to send the NFT to
    - `contractAddress` string, required: The blockchain address of the NFT; this is the address from the <code>nftAddress</code> parameter returned in the response body of the <a href="#operation/NftMintErc721">minting call</a>
    - `fromPrivateKey` string, required: The private key of the blockchain address that you are sending the NFT from (the address that you specified in the <code>from</code> parameter)
    - `feePayer` string: Address on the Solana blockchain, from which the fee will be paid for transaction. Defaults to from.
    - `feePayerPrivateKey` string: Private key of the fee payer address.
  - TransferNftAlgo
    - `chain` 'ALGO', required: The blockchain to work with
    - `to` string, required: The blockchain address to transfer the NFT to
    - `contractAddress` string, required: The asset ID (the ID of the NFT)
    - `fromPrivateKey` string, required: The private key of the sender's blockchain address
    - `amount` number: (For <a href="https://developer.algorand.org/docs/get-started/tokenization/nft/#fractional-nfts" target="_blank">fractional NFTs</a> only) The number of NFT fractions to transfer; if not set, defaults to 1, which means that one fraction of the NFT will be transferred
    - `fee` string: The transaction fee in Algos
  - TransferNftAlgoExpress
    - `chain` 'ALGO', required: The blockchain to work with
    - `to` string, required: The blockchain address to transfer the NFT to
    - `contractAddress` string, required: The asset ID (the ID of the NFT)
    - `fee` string: The transaction fee in Algos
    - `amount` number: (For <a href="https://developer.algorand.org/docs/get-started/tokenization/nft/#fractional-nfts" target="_blank">fractional NFTs</a> only) The number of NFT fractions to transfer; if not set, defaults to 1, which means that one fraction of the NFT will be transferred
  - TransferNftTezos
    - `chain` 'TEZOS', required: The blockchain to work with
    - `from` string, required: Blockchain address that owns the NFT token
    - `to` string, required: Blockchain address to send NFT token to
    - `contractAddress` string, required: The blockchain address of the NFT smart contract
    - `tokenId` string, uint256, required: The ID of the NFT
    - `fromPrivateKey` string, required: The private key of the blockchain address that owns the token or has rights to transfer the token. This address will pay the fee for the transaction,
  - TransferNftKMS
    - `chain` 'ETH' | 'MATIC' | 'KCS' | 'ONE' | 'KLAY' | 'BSC', required: The blockchain to work with
    - `to` string, required: Blockchain address to send NFT token to
    - `tokenId` string, uint256, required: ID of the token.
    - `contractAddress` string, required: Address of NFT token
    - `index` number: If signatureId is mnemonic-based, this is the index to the specific address from that mnemonic.
    - `signatureId` string, uuid, required: Identifier of the private key associated in signing application. Private key, or signature Id must be present.
    - `nonce` number: The nonce to be set to the transaction; if not present, the last known nonce will be used
    - `fee` CustomFee: The custom defined fee; if not present, will be calculated automatically
      - `gasPrice` string, required: The price for one gas unit (in Gwei)
      - `gasLimit` string, required: The maximum number of gas units that you are willing to spend on processing the transaction at the provided gas price
  - TransferNftKMSCelo
    - `chain` 'CELO', required: The blockchain to work with
    - `to` string, required: Blockchain address to send NFT token to
    - `tokenId` string, uint256, required: ID of the token.
    - `contractAddress` string, required: Address of NFT token
    - `index` number: If signatureId is mnemonic-based, this is the index to the specific address from that mnemonic.
    - `signatureId` string, uuid, required: Identifier of the private key associated in signing application. Private key, or signature Id must be present.
    - `nonce` number: The nonce to be set to the transaction; if not present, the last known nonce will be used
    - `feeCurrency` 'CELO' | 'CUSD' | 'CEUR', required: The currency in which the transaction fee will be paid
    - `fee` CustomFee: The custom defined fee; if not present, will be calculated automatically
      - `gasPrice` string, required: The price for one gas unit (in Gwei)
      - `gasLimit` string, required: The maximum number of gas units that you are willing to spend on processing the transaction at the provided gas price
  - TransferNftAlgoKMS
    - `chain` 'ALGO', required: The blockchain to work with
    - `from` string, required: The blockchain address to transfer the NFT from
    - `to` string, required: The blockchain address to transfer the NFT to
    - `contractAddress` string, required: The asset ID (the ID of the NFT)
    - `fee` string: The transaction fee in Algos
    - `signatureId` string, uuid, required: The KMS identifier of the private key of the sender's blockchain address
    - `amount` number: (For <a href="https://developer.algorand.org/docs/get-started/tokenization/nft/#fractional-nfts" target="_blank">fractional NFTs</a> only) The number of NFT fractions to transfer; if not set, defaults to 1, which means that one fraction of the NFT will be transferred
  - TransferNftSolanaKMS
    - `chain` 'SOL', required: The blockchain to work with
    - `from` string, required: The blockchain address to send the NFT from; this is the address that you used in the <code>to</code> parameter in the request body of the <a href="#operation/NftMintErc721">minting call</a>; from this address, the transaction fee will be paid
    - `to` string, required: The blockchain address to send the NFT to
    - `contractAddress` string, required: The blockchain address of the NFT; this is the address from the <code>nftAddress</code> parameter returned in the response body of the <a href="#operation/NftMintErc721">minting call</a>
    - `signatureId` string, uuid, required: The KMS identifier of the private key of the blockchain address that you are sending the NFT from (the address that you specified in the <code>from</code> parameter)
    - `feePayer` string: Blockchain address to pay the fee for the transaction from
    - `feePayerSignatureId` string, uuid: Identifier of the private key used for paying the gas costs in signing application. Defaults to the signatureId.
  - TransferNftKMSTron
    - `chain` 'TRON', required: The blockchain to work with
    - `from` string, required: Blockchain address to perform transaction from
    - `to` string, required: Blockchain address to send NFT token to
    - `tokenId` string, uint256, required: ID of the token.
    - `contractAddress` string, required: Address of NFT token
    - `index` number: If signatureId is mnemonic-based, this is the index to the specific address from that mnemonic.
    - `signatureId` string, uuid, required: Identifier of the private key associated in signing application. Private key, or signature Id must be present.
    - `feeLimit` number, required: The maximum amount to be paid as the transaction fee (in TRX)

## Response `200`

OK

- union
  - TransactionHash
    - `txId` string, required: The hash (ID) of the transaction
  - SignatureId
    - `signatureId` string, uuid, required: The internal Tatum ID of the prepared transaction for Key Management Sysytem (KMS) to sign<br/>This is different from the <code>signatureId</code> parameter that you provided in the request body. The <code>signatureId</code> parameter in the request body specifies the signature ID associated with the private key in KMS.

## Other responses

- `400`: Bad Request
- `401`: Unauthorized. Not valid or inactive subscription key present in the HTTP Header.
- `403`: Forbidden. The request is authenticated, but it is not possible to perform the operation due to logical error or invalid permissions.
- `500`: Internal server error. There was an error on the server during the processing of the request.

---

[API](https://skmtc.dev/tatum/apis/smart-contracts.md) - [All operations](https://skmtc.dev/tatum/apis/smart-contracts/llms.txt) - [OpenAPI document](https://skmtc.dev/tatum/apis/smart-contracts/revisions/c0146043bb37?raw)
