Integration Quickstart
This quickstart is for developers integrating Meld’s White-Label API for the first time. You’ll go from zero credentials to a successfully completed sandbox transaction in about 30 minutes.
Time required: 30 minutes
Difficulty: API knowledge required
Before you begin
- A Meld dashboard invitation (check your email)
- Ability to make authenticated REST calls (curl, Postman, or your language of choice)
- A publicly reachable webhook URL (optional; you can poll the API instead)
Sandbox base URL: https://api-sb.meld.io. Production credentials and URLs are separate — sandbox credentials will not work in production and vice versa.
Step 1: Get Your API Key
Your API key is required for all Meld API calls.
Process:
- Check your email for the Meld dashboard invitation
- Click the invitation link and log in
- In the dashboard https://dashboard.meld.io , navigate to Developer > API Keys
- Click “Reveal Key”
- Copy and save your API key securely
Important: Always add BASIC before your API key in all requestsExample: BASIC W9kZTT7332okCEc1A9aqAq:3sYKoXQv6oHVHSts7G2agw9vTCXz
Step 2: Set Up Webhooks
Webhooks notify your server when transactions are created and updated. This step can be completed later.
Requirements:
- A publicly accessible URL (localhost will not work)
- For testing, consider using ngrok, webhook.site or similar services
Setup Process:
- Navigate to Developer > Webhooks in the dashboard
- Click “Add Endpoint”
- Enter your webhook URL (must start with http/https)
- Give your webhook a descriptive name
- Select “Subscribe to all events”
- Click “Add endpoint”
Note: You will receive notifications to this URL for all transaction creations and updates.
Step 3: Test Your API Connection
Verify your API key by requesting a price quote.
API Call Details:
- Endpoint:
POST /payments/crypto/quote
- Authorization:
BASIC [your-api-key]
Request Body:
{
"countryCode": "US",
"sourceCurrencyCode": "USD",
"destinationCurrencyCode": "BTC",
"paymentMethodType": "CREDIT_DEBIT_CARD",
"sourceAmount": 100
}
Testing Notes:
- Use the interactive docs at the endpoint URL
Expected Response:
✅ 200 status code with quote details
Here is an example of a single quote. You can expect multiple quotes, 1 per onramp, in the response.
{
"quotes": [
{
"transactionType": "CRYPTO_PURCHASE",
"sourceAmount": 100.00,
"sourceAmountWithoutFees": 95.82,
"fiatAmountWithoutFees": 95.82,
"destinationAmountWithoutFees": null,
"sourceCurrencyCode": "USD",
"countryCode": "US",
"totalFee": 4.18,
"networkFee": 0.28,
"transactionFee": 2.9,
"partnerFee": 1,
"destinationAmount": 0.00105423,
"destinationCurrencyCode": "BTC",
"exchangeRate": 94856.0,
"paymentMethodType": "CREDIT_DEBIT_CARD",
"serviceProvider": "TOPPER",
"rampIntelligence": {
"rampScore": 21.66,
"lowKyc": false
}
}
]
}
Step 4: Create a Test Transaction
Create a test transaction without using real money.
API Call Details:
- Endpoint:
POST /crypto/session/widget
- Authorization:
BASIC [your-api-key]
Request Body:
{
"countryCode": "US",
"sourceCurrencyCode": "USD",
"destinationCurrencyCode": "BTC",
"paymentMethodType": "CREDIT_DEBIT_CARD",
"sourceAmount": 100,
"serviceProvider": "TRANSAK",
"walletAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
}
Note: Replace walletAddress with your own or use the test address provided.
Expected Response:
✅ 200 status code with onramp url details
{
"id": "WePjVaT4iBHPpqW49F419x",
"externalSessionId": "testSession",
"externalCustomerId": "testCustomer",
"customerId": "WePZCYZjAK97cJWokfH3Jc",
"widgetUrl": "https://meldcrypto.com?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJtZWxkLmlvIiwiaWF0IjoxNzY1MjM2MjExLCJzdWIiOiJjcnlwdG8iLCJleHAiOjE3NjUyMzgwMTEsImFjY291bnRJZCI6IldRNVJ5aGRGekU0NXFqc29tZHpRMXUiLCJzZXNzaW9uSWQiOiJXZVBqVmFUNGlCSFBwcVc0OUY0MTlhIn0.TH6P9KVKN4GNu4CNsDAN9uicjMBashgA9QY7jiMiDEF",
"serviceProviderWidgetUrl": "https://topper.com?apiKey=1234&sessionId=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJvdHQiOiIxZDFjOTM1ODY0YTQ0NGM0YTJiMmQ5ODJkYjc0Njg1NCIsImlhdCI6MTc2NTIzNjIxMiwiZXhwIjoxNzY1MjM2NTEyfQ.6ZnmR5FAxzr9bG3n_I54L1EmHYljfhPJNeqp97WZPI7GUm9VCksbKv_rWK4KiB6YkAAJR6_C1Xsnn-fliUrABC",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJtZWxkLmlvIiwiaWF0IjoxNzY1MjM2MjExLCJzdWIiOiJjcnlwdG8iLCJleHAiOjE3NjUyMzgwMTEsImFjY291bnRJZCI6IldRNVJ5aGRGekU0NXFqc29tZHpRMXUiLCJzZXNzaW9uSWQiOiJXZVBqVmFUNGlCSFBwcVc0OUY0MTlhIn0.TH6P9KVKN4GNu4CNsDAN9uicjMBashgA9QY7jiMiDEF"
}
Complete the Test Flow:
- Copy the
widgetUrl from the API response
- Open the URL in your browser
- For KYC testing:
- SSN: Use any fake number
- ID Upload: Any image file works
- For payment testing:
- Card Number:
4111 1111 1111 1111
- Expiry: Any future date
- CVV: Any 3 digits
📚 Full test data reference: Sandbox testing credentials
Step 5: Verify Your Transaction
Fetch Transaction Details after Receiving Webhooks
- Check your webhook endpoint for a webhook that the transaction has been created.
Expected Webhook Response
{
"eventType": "TRANSACTION_CRYPTO_PENDING",
"eventId": "AAsuLXHXD3mS1cjNBuHHzv",
"timestamp": "2022-02-24T16:36:41.717262Z",
"accountId": "WQ5RyhdFzE45qjsomdzQ1u",
"profileId": "W9ka8vLE4ufBkSg3BEciZb",
"version": "2025-03-01",
"payload": {
"requestId": "f07f1accb7404aec9bd9a5d64975eed1",
"accountId": "W2aRZnYGPwhBWB94iFsZus",
"paymentTransactionId": "WePZCYJW7cdXR7SxUMp8mE",
"customerId": "WePZCYZjAK97cJWokfH3Jc",
"externalCustomerId": "testCustomer",
"externalSessionId": "testSession",
"paymentTransactionStatus": "PENDING",
"transactionType": "CRYPTO_PURCHASE",
"sessionId": "WePjVaT4iBHPpqW49F419x"
}
}
- Extract the
paymentTransactionId from the webhook payload
- Call
GET /payments/transactions/{transactionId}
Expected Response:
✅ 200 status code with transaction details
{
"transaction": {
"id": "WePZCYJW7cdXR7SxUMp8mE",
"parentPaymentTransactionId": null,
"accountId": "WQ5RyhdFzE45qjsomdzQ1u",
"isPassthrough": false,
"passthroughReference": null,
"isImported": false,
"customer": {
"id": "WePZCYZjAK97cJWokfH3Cc",
"accountId": "WQ5RyhdFzE45qjsomdzQ1u",
"externalId": "YC100"
},
"transactionType": "CRYPTO_PURCHASE",
"status": "SETTLED",
"sourceAmount": 100.00,
"sourceCurrencyCode": "USD",
"destinationAmount": 0.00105423,
"destinationCurrencyCode": "BTC",
"paymentMethodType": "CREDIT_DEBIT_CARD",
"serviceProvider": "TOPPER",
"serviceTransactionId": "1f0d470c-f5c2-6fc2-a54d-b6cdd6b6f014",
"orderId": null,
"description": null,
"externalReferenceId": "testSession",
"serviceProviderDetails": {
**raw details from the onramp**
},
"multiFactorAuthorizationStatus": null,
"createdAt": "2025-12-08T20:03:07.173223Z",
"updatedAt": "2025-12-08T20:08:08.877106Z",
"countryCode": "US",
"sessionId": "WePZCbr96gAUxgu7Auvm4q",
"externalSessionId": "testSession",
"paymentDetails": null,
"externalCustomerId": "testCustomer",
"fiatAmountInUsd": 100.00,
"sessionClientTags": null,
"serviceProviderTransactionUrl": null,
"serviceProviderCreatedAt": "2025-12-08T20:02:22Z",
"cryptoDetails": {
"sourceWalletAddress": null,
"destinationWalletAddress": "0xd72cc3468979360e31bc83b84f0887deccfd81d5",
"sessionWalletAddress": "0xd72cc3468979360e31bc83b84f0887deccfd81d5",
"totalFee": 4.18,
"networkFee": 0.28,
"transactionFee": 2.9,
"partnerFee": 1,
"totalFeeInUsd": 4.18,
"networkFeeInUsd": 0.28,
"transactionFeeInUsd": 2.9,
"partnerFeeInUsd": 1,
"blockchainTransactionId": "0x553d295955a978ed3e9fc1717b5bcb903c69577e49c8ad255abece945ffa9ba0",
"institution": null,
"chainId": "1"
}
}
}
Dashboard Verification:
- Navigate to the Transactions tab
- If your transaction isn’t visible:
- Click the Status dropdown
- Select “Select All”
- Your transaction should appear
✅ White-Label API Integration Complete! You can now build custom crypto experiences.
➡️ Build Custom UI Guide — complete implementation guide
Next steps
If you’re ready to begin your integration, follow the end-to-end White-Label API Guide.
Troubleshooting
Common Issues and Solutions:
🚫 401 Unauthorized
- Ensure
BASIC is added before your API key
- Check for extra spaces or incorrect formatting
🚫 Webhook Not Received
- Verify URL is publicly accessible
- Check firewall settings
- Ensure webhook endpoint returns 200 status
🚫 Transaction Not Visible
- Change status filter to “Select All” in dashboard
- Wait 30 seconds and refresh
- Check if using correct environment (sandbox vs production)