Skip to main content
By the end of this guide, you’ll know how to request a Link Token for any use case: deposits, payments, onramps, withdrawals, and wallet verification.
Before you start
  • You have a Mesh dashboard account with a sandbox API key (see Prepare to build)
  • You know which use case(s) you’re building for

Overview

A Link token, as the name implies, is an access key for a session of Link, Mesh’s SDK. You’ll request it with an API call to Mesh, and the parameters you include will configure the user session. This is how you’ll start every user session. This guide will walk you through how to request a Link token, including code snippets for specific use cases.

General information

Endpoint: Get Link token with parameters (/api/v1/linktoken) You will start every user session with this request. Its parameters configure the user’s experience within Link.
  • Tokens are short-lived (must be used within 10mins).
  • Tokens are one-time use.

Use-case-specific example requests

X-Client-Id required
Your Mesh Client ID.
X-Client-Secret required
Your Mesh API Key.
userId required
A unique, persistent user identifier. Personally identifiable information such as an email address or phone number should not be used. 300 characters length maximum.
restrictMultipleAccounts optional

Defaults to true, which is standard used for any transfer flow.

On some non-transfer flows (ie. “read” use cases), a user could connect multiple accounts in a row if this value were false. Sometimes valuable for withdrawal use cases to let the user create an external “address book”.

integrationId optional

A unique Mesh identifier representing a specific integration.

Use the Get integrations endpoint (/api/v1/transfers/managed/integrations) to pull a list of integrations and the corresponding Mesh integrationId. These values won’t change, so you do not have to hit this endpoint before each Link Token request.

To be used if the user selects the integration in your UX before launching Mesh (most commonly in an onramp flow).

transferOptions.transactionId optional
A unique transaction identifier used to tie back to your data or track this transaction in future calls to Mesh.
transferOptions.transferType optional
Ensures the language and flow matches your user’s mental model for the type of transfer they’re doing. Defaults to deposit.
transferOptions.isInclusiveFeeEnabled optional

Specifies if fees should be included in the amount to transfer.

false is standard for deposit and payment, meaning any applicable fees are on top of the deposit/payment amount. true is standard for onramp, meaning the amount the user receives is the amount specified minus applicable fees.

transferOptions.generatePayLink optional

When true, this request will return a url in addition to the Link token that can be used to launch Mesh Link in a separate web page.

This should only be used if you’re launching Mesh in a separate webpage (see more about “PayLinks” in the Launch the Mesh SDK guide).

transferOptions.amountInFiat optional

The fiat-equivalent amount of the symbol to be purchased.

To be used if the user enters an amount in your UX before launching Mesh (most commonly in an onramp flow).

transferOptions.toAddresses.networkId optional required for transfers

Mesh’s unique identifier for the network to be used for this toAddress.

Use the Get networks endpoint (/api/v1/transfers/managed/networks) to pull a list of all supported networks and the corresponding Mesh networkId. These values won’t change, so you do not have to hit this endpoint before each Link Token request.

transferOptions.toAddresses.symbol optional required for transfers
The symbol of the asset that can be transferred to this toAddress.
transferOptions.toAddresses.address optional required for transfers
The destination to which the specified symbol can be sent on the specified networkId.
transferOptions.toAddresses.amount optional required for payments

Exact amount of the asset that should be transferred.

This parameter is optional for deposit and onramp, but required when transferType: payment. Not to be used in combination with the amountInFiat field.

transferOptions.toAddresses.displayAmountInFiat optional

A fiat-equivalent amount that will be shown to the user in the Mesh UI.

This ensures a consistent experience from your checkout experience to Mesh. It will only be used if it is within 1% of the amountInFiat Mesh determines based on its pricing data. This is generally used for non-stablecoin payments, as Mesh maps stablecoins to a 1:1 price with USD for display purposes.

verifyWalletOptions.verificationMethods optional required for verifications

Method by which the user must verify their self-hosted wallet.

Enum to support future verification methods, but only one option for now.

verifyWalletOptions.message optional

The message the user should sign in their wallet.

The exact language isn’t important. Mesh has standard language if this isn’t provided.

verifyWalletOptions.networkId optional

A unique Mesh identifier for the network on which the user must verify their self-hosted address.

Use the Get networks endpoint (/api/v1/transfers/managed/networks) to pull a list of all supported networks and the corresponding Mesh networkId. These values won’t change, so you do not have to hit this endpoint before each Link Token request.

To be used if you need your user to verify an address on a specific network. Should not be used in combination with networkType.

verifyWalletOptions.networkType optional

The network type on which the user must verify their self-hosted address.

To be used if you need your user to verify an address on a particular network type (eg. EVM). Should not be used in combination with networkId.

verifyWalletOptions.address optional

A list of address from which the user can verify ownership. User is not allowed to verify an address outside this list.

Used if you need your user to verify ownership of a specific address. If not provided, user can verify ownership of any self-hosted address they connect.

curl --request POST \
  --url https://sandbox-integration-api.meshconnect.com/api/v1/linktoken \ // This is pointing to sandbox
  --header 'Content-Type: application/json' \
  --header 'X-Client-Id: YOUR_CLIENT_ID' \ // Replace
  --header 'X-Client-Secret: YOUR_API_KEY' \ // Replace
  --data '
{
  "userId": "UNIQUE_USER_ID", // Replace
  "restrictMultipleAccounts": true,
  "transferOptions": {
    "transactionId": "UNIQUE_TRANSACTION_ID", // Replace
    "transferType": "deposit",
    "isInclusiveFeeEnabled": false,
    "generatePayLink": false,
    "toAddresses": [ // Replace (example array below)
      {
        "networkId": "0291810a-5947-424d-9a59-e88bb33e999d", // Solana
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
      },
      {
        "networkId": "e3c7fdd8-b1fc-4e51-85ae-bb276e075611", // Ethereum
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
      },
      {
        "networkId": "aa883b03-120d-477c-a588-37c2afd3ca71", // Base
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
      }
    ],
  }
}
'
  • The toAddresses are the possible destinations at which user deposits can be received. This object is an array. The example request shows 3 possible destination addresses (USDC.sol, USDC.eth, USDC.base), but you should provide all possible destination addresses to maximize the chances that Mesh can make a transaction happen.
    Want more help? Use our toAddress generator. This tool helps you quickly construct your toAddress array.
  • There is an additional parameter for addressTag within the toAddress object. Be sure to include that for assets like XRP or XLM if necessary for proper attribution to your user accounts.
  • There are additional parameters for minAmount & minAmountInFiat within the toAddress object. Be sure to include this if you have deposit minimums.
curl --request POST \
  --url https://sandbox-integration-api.meshconnect.com/api/v1/linktoken \ // This is pointing to sandbox
  --header 'Content-Type: application/json' \
  --header 'X-Client-Id: YOUR_CLIENT_ID' \ // Replace
  --header 'X-Client-Secret: YOUR_API_KEY' \ // Replace
  --data '
{
  "userId": "UNIQUE_USER_ID", // Replace
  "restrictMultipleAccounts": true,
  "transferOptions": {
    "transactionId": "UNIQUE_TRANSACTION_ID", // Replace
    "transferType": "payment",
    "isInclusiveFeeEnabled": false,
    "generatePayLink": false,
    "toAddresses": [ // Replace (example array below)
      {
        "networkId": "0291810a-5947-424d-9a59-e88bb33e999d", // Solana
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
        "amount": 99.99 // Replace
      },
      {
        "networkId": "e3c7fdd8-b1fc-4e51-85ae-bb276e075611", // Ethereum
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
        "amount": 99.99 // Replace
      },
      {
        "networkId": "aa883b03-120d-477c-a588-37c2afd3ca71", // Base
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
        "amount": 99.99 // Replace
      },
      {
        "networkId": "03dee5da-7398-428f-9ec2-ab41bcb271da", // Bitcoin
        "symbol": "BTC", // Replace
        "address": "xxx", // Replace
        "amount": 0.00141, // Replace
        "displayAmountInFiat": 99.99 // Replace
      }
    ],
  }
}
'
  • The toAddresses are the possible destinations at which user payments can be received. This object is an array. The example request shows 4 possible destination addresses (USDC.sol, USDC.eth, USDC.base, BTC.btc), but you should provide all possible destination addresses to maximize the chances that Mesh can make a transaction happen.
    Want more help? Use our toAddress generator. This tool helps you quickly construct your toAddress array.
  • The amount parameter is the amount of the symbol specified in this object that must be transferred (ie. the total payment amount, in crypto). Do not use the amountInFiat parameter, as Mesh cannot guarantee exchange rates.
  • There is an additional parameter for addressTag within the toAddress object. Be sure to include that for assets like XRP or XLM if necessary for proper attribution on your end.
curl --request POST \
  --url https://sandbox-integration-api.meshconnect.com/api/v1/linktoken \ // This is pointing to sandbox
  --header 'Content-Type: application/json' \
  --header 'X-Client-Id: YOUR_CLIENT_ID' \ // Replace
  --header 'X-Client-Secret: YOUR_API_KEY' \ // Replace
  --data '
{
  "userId": "UNIQUE_USER_ID", // Replace
  "restrictMultipleAccounts": true,
  "integrationId": "5620bf49-3240-4f85-8b4f-9dd6261597e2", // Binance Connect (Replace)
  "transferOptions": {
    "transactionId": "UNIQUE_TRANSACTION_ID", // Replace
    "transferType": "onramp",
    "amountInFiat": 100.00, // Replace
    "isInclusiveFeeEnabled": true,
    "generatePayLink": false,
    "toAddresses": [ // Replace (this could be a full array, or only one destination if the user selects a token/network in your UX before launching Mesh)
      {
        "networkId": "0291810a-5947-424d-9a59-e88bb33e999d", // Solana
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
      }
    ],
  }
}
'
  • There is an additional parameter for addressTag within the toAddress object. Be sure to include that for assets like XRP or XLM if necessary for proper attribution to your user accounts.
    Want more help? If you’re passing an array of multiple possible destinations for your user’s purchase, use our toAddress generator. This tool helps you quickly construct your toAddress array.
  • There are additional parameters for minAmount & minAmountInFiat within the toAddress object. Be sure to include this if you have deposit minimums.
  • Read more about this in Add Mesh onramp integrations to your “Buy” lineup.
curl --request POST \
  --url https://sandbox-integration-api.meshconnect.com/api/v1/linktoken \ // This is pointing to sandbox
  --header 'Content-Type: application/json' \
  --header 'X-Client-Id: YOUR_CLIENT_ID' \ // Replace
  --header 'X-Client-Secret: YOUR_API_KEY' \ // Replace
  --data '
{
  "userId": "UNIQUE_USER_ID", // Replace
  "restrictMultipleAccounts": true,
}
'
curl --request POST \
  --url https://sandbox-integration-api.meshconnect.com/api/v1/linktoken \ // This is pointing to sandbox
  --header 'Content-Type: application/json' \
  --header 'X-Client-Id: YOUR_CLIENT_ID' \ // Replace
  --header 'X-Client-Secret: YOUR_API_KEY' \ // Replace
  --data '
{
  "userId": "UNIQUE_USER_ID", // Replace
  "restrictMultipleAccounts": true,
  "integrationId": "757e703f-a8fe-4dc4-d0ec-08dc6737ad96", // Phantom, replace, optional
  "verifyWalletOptions": {
    "verificationMethods": [
      "signedMessage"
    ],
    "message": "MESSAGE_TO_BE_SIGNED", // Replace
    "networkId": "0291810a-5947-424d-9a59-e88bb33e999d", // Solana, replace, optional
    "networkType": "solana", // Replace, optional
    "addresses": [ // Optional
      "xxx" // Replace
    ],
  }
}
'
  • Wallet verification is fully compatible with the deposit & payment use cases. If you require users to verify that they own a self-custody wallet before initiating a deposit or payment from that wallet, you can add these configurations into the same Link Token request.
  • Read more about this in Verify self-hosted wallets.

What’s next

Next up: Launch the Mesh SDK — use the Link Token you just requested to initialize and launch a user-facing SDK session.
AI coding reference — a compact summary of this page’s APIs, parameters, and patterns for use by AI coding assistants (following the llms.txt standard). Human readers can safely ignore this.llms.txt — Fetch a Link TokenEvery Mesh session starts server-side with a Link Token request. Tokens are short-lived (10 min) and single-use.Endpoint: POST /api/v1/linktokenRequired params: userId (unique, persistent, non-PII, ≤300 chars) — the only universally required body param.Conditionally required: transferOptions.toAddresses[].networkId, .symbol, .address — required for any transfer flow | transferOptions.toAddresses[].amount — required for payment flows (not for deposit/onramp) | verifyWalletOptions.verificationMethods — required when using wallet verificationKey optional params: transferOptions.transferType (deposit/payment/onramp — defaults to deposit) | integrationId (deep-link to specific provider) | accessTokens (MMT return-user array) | restrictMultipleAccounts (default true) | generatePayLink (true returns paymentLink URL) | transferOptions.isInclusiveFeeEnabled (false for deposit/payment; true for onramp) | transferOptions.amountInFiat | transferOptions.toAddresses[].addressTag (for XRP, XLM) | transferOptions.toAddresses[].minAmount / minAmountInFiatverifyWalletOptions (wallet ownership): verificationMethods: ["signedMessage"] | message | networkId or networkType (not both) | addresses[]Get networkIds: Use GET /api/v1/transfers/managed/networks to fetch the full list of supported networks and their networkId values. These values don’t change — safe to cache permanently, no need to call this endpoint before every Link Token request.Key networkIds: Solana 0291810a-5947-424d-9a59-e88bb33e999d | Ethereum e3c7fdd8-b1fc-4e51-85ae-bb276e075611 | Base aa883b03-120d-477c-a588-37c2afd3ca71 | Bitcoin 03dee5da-7398-428f-9ec2-ab41bcb271daTool: toAddress generator — quickly construct your toAddresses array.Deposit use case — canonical request body:
curl --request POST \
  --url https://sandbox-integration-api.meshconnect.com/api/v1/linktoken \ // This is pointing to sandbox
  --header 'Content-Type: application/json' \
  --header 'X-Client-Id: YOUR_CLIENT_ID' \ // Replace
  --header 'X-Client-Secret: YOUR_API_KEY' \ // Replace
  --data '
{
  "userId": "UNIQUE_USER_ID", // Replace
  "restrictMultipleAccounts": true,
  "transferOptions": {
    "transactionId": "UNIQUE_TRANSACTION_ID", // Replace
    "transferType": "deposit",
    "isInclusiveFeeEnabled": false,
    "generatePayLink": false,
    "toAddresses": [ // Replace (example array below)
      {
        "networkId": "0291810a-5947-424d-9a59-e88bb33e999d", // Solana
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
      },
      {
        "networkId": "e3c7fdd8-b1fc-4e51-85ae-bb276e075611", // Ethereum
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
      },
      {
        "networkId": "aa883b03-120d-477c-a588-37c2afd3ca71", // Base
        "symbol": "USDC", // Replace
        "address": "xxx", // Replace
      }
    ],
  }
}
'
Payment use case — same as deposit but add "amount": 99.99 to each toAddress entry and set "transferType": "payment".Onramp use case — add "integrationId": "...", "amountInFiat": 100.00, "isInclusiveFeeEnabled": true and set "transferType": "onramp".Verify use case — replace transferOptions with "verifyWalletOptions": { "verificationMethods": ["signedMessage"], "message": "...", "networkId": "..." }.