Skip to main content
New to Mesh? Read How it all fits together first for a quick orientation on how the Link Token, SDK, callbacks, and webhooks connect — then come back here to build.
This guide gets you from zero to a working Mesh deposit flow in sandbox — no prior Mesh knowledge required. In 15mins, you’ll have made your first API call, launched the Mesh SDK, and seen a test transfer complete. The full guide series goes deeper on each topic. This is just to get you moving fast.
Before you start
  • You have a Mesh dashboard account. If you don’t have one yet, reach out to your Mesh representative to request an invitation.
  • You’re building a web app (this guide uses the web SDK).

Get your sandbox credentials

Log into the Mesh dashboard and navigate to Account > API keys > API keys. Create a new key with Read & Write permissions (required for transfers). You’ll need two things:
  • Client ID — your unique identifier, shown next to the key
  • API key (sandbox) — starts with sk_sandbox_...
Also note the sandbox base URL: https://sandbox-integration-api.meshconnect.com While you’re here, go to Account > API keys > Access and add the domain where you’ll be running your app (eg. localhost:3000 for local development). The Mesh SDK will refuse to load on any domain not on this list.

Install the Mesh web SDK

# with npm
npm install --save @meshconnect/web-link-sdk

# with yarn
yarn add @meshconnect/web-link-sdk
Details on mesh-web-sdk. A Link Token is how you start every user session. You request it from your server, and the parameters configure what the user can do in Link. Here’s the minimal request for a deposit flow:
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 (your Mesh Client ID)
  --header 'X-Client-Secret: YOUR_API_KEY' \ // Replace (your Mesh API Key)
  --data '
{
  "userId": "xxx", // Replace (a unique user identifier)
  "restrictMultipleAccounts": true, // "true" is standard and is used for any tranfer flow
  "transferOptions": {
    "transactionId": "xxx", // Replace (optional: a unique transaction identifier to tie back to your data)
    "transferType": "deposit", // Ensures the language and flow matches your user's mental model for a deposit
    "isInclusiveFeeEnabled": false, // "false" is standard, meaning any applicable fees are on top of the deposit amount
    "generatePayLink": false, // "true" is to be used if you're launching Mesh in a separate webpage (see more about "PayLinks" in the section about launching the Mesh SDK)
    "toAddresses": [ // Replace (example array below, update with one or multiple asset/network/address combos for testing)
      {
        "networkId": "0291810a-5947-424d-9a59-e88bb33e999d", // Solana
        "symbol": "USDC",
        "address": "YOUR_SOL_ADDRESS", // Replace (destination address for this asset/network, user-specific if necessary)
      },
      {
        "networkId": "e3c7fdd8-b1fc-4e51-85ae-bb276e075611", // Ethereum
        "symbol": "USDC",
        "address": "YOUR_ETH_ADDRESS", // Replace (destination address for this asset/network, user-specific if necessary)
      },
      {
        "networkId": "aa883b03-120d-477c-a588-37c2afd3ca71", // Base
        "symbol": "USDC",
        "address": "YOUR_BASE_ADDRESS", // Replace (destination address for this asset/network, user-specific if necessary)
      }
    ],
  }
}
'
The response will include a linkToken — hold onto it for the next step.
Why does this live server-side?Your API key is in this request, so it must be made from your server, not the browser. Your frontend receives the linkToken and uses it to initialize the SDK.

Initialize and launch the Mesh SDK

On your frontend, initialize a session of Link in the Mesh SDK using the linkToken from Step 3:
const connection = createLink({
  renderType: 'overlay',
  theme: 'system',
  language: 'system',
  displayFiatCurrency: 'USD',
})

connection.openLink(linkToken)
When openLink is called, Mesh Link opens and guides the user through connecting their account and approving the deposit.

Test it with a sandbox account

In sandbox, use one of these pre-configured test accounts to simulate a real exchange connection:
ExchangeUsernamePasswordOTP
CoinbaseMeshPass123123456
BinanceMeshPass123123456
See the Sandbox & Testnets guide for the full list of test accounts and wallet testing instructions.

What’s next

You’ve got a working deposit flow. Here’s where to go from here:
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 — 15-minute QuickstartEnd-to-end sandbox deposit integration in 5 steps using the Web SDK. No prior Mesh knowledge required.Steps: (1) Get sandbox API key + Client ID from Mesh dashboard → (2) Install @meshconnect/web-link-sdk → (3) POST /api/v1/linktoken server-side with userId, transferType: "deposit", toAddresses[] → (4) createLink({renderType, theme, language, displayFiatCurrency}).openLink(linkToken) client-side → (5) Test with username Mesh, password Pass123, OTP 123456Sandbox base URL: https://sandbox-integration-api.meshconnect.com | Auth headers: X-Client-Id, X-Client-SecretAdd allowed domain: Dashboard > Account > API keys > Access (must include localhost:3000 for local dev)Key networkIds: Solana 0291810a-5947-424d-9a59-e88bb33e999d | Ethereum e3c7fdd8-b1fc-4e51-85ae-bb276e075611 | Base aa883b03-120d-477c-a588-37c2afd3ca71Step 3 — Link Token request (server-side):
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 (your Mesh Client ID)
  --header 'X-Client-Secret: YOUR_API_KEY' \ // Replace (your Mesh API Key)
  --data '
{
  "userId": "xxx", // Replace (a unique user identifier)
  "restrictMultipleAccounts": true, // "true" is standard and is used for any tranfer flow
  "transferOptions": {
    "transactionId": "xxx", // Replace (optional: a unique transaction identifier to tie back to your data)
    "transferType": "deposit", // Ensures the language and flow matches your user's mental model for a deposit
    "isInclusiveFeeEnabled": false, // "false" is standard, meaning any applicable fees are on top of the deposit amount
    "generatePayLink": false, // "true" is to be used if you're launching Mesh in a separate webpage (see more about "PayLinks" in the section about launching the Mesh SDK)
    "toAddresses": [ // Replace (example array below, update with one or multiple asset/network/address combos for testing)
      {
        "networkId": "0291810a-5947-424d-9a59-e88bb33e999d", // Solana
        "symbol": "USDC",
        "address": "YOUR_SOL_ADDRESS", // Replace (destination address for this asset/network, user-specific if necessary)
      },
      {
        "networkId": "e3c7fdd8-b1fc-4e51-85ae-bb276e075611", // Ethereum
        "symbol": "USDC",
        "address": "YOUR_ETH_ADDRESS", // Replace (destination address for this asset/network, user-specific if necessary)
      },
      {
        "networkId": "aa883b03-120d-477c-a588-37c2afd3ca71", // Base
        "symbol": "USDC",
        "address": "YOUR_BASE_ADDRESS", // Replace (destination address for this asset/network, user-specific if necessary)
      }
    ],
  }
}
'
Step 4 — SDK initialization (client-side):
const connection = createLink({
  renderType: 'overlay',
  theme: 'system',
  language: 'system',
  displayFiatCurrency: 'USD',
  onIntegrationConnected: payload => console.log('[connected]', payload),
  onTransferFinished: payload => console.log('[transfer]', payload),
  onExit: payload => console.log('[exit]', payload),
  onEvent: ev => console.log('[event]', ev)
})
connection.openLink(linkToken)
Next steps: Fetch a Link Token (full param reference) → Launch the Mesh SDK (all 5 platforms) → Use Mesh’s callback functions → Supercharge return-users (MMT)