curl --request POST \
--url https://api-sb.meld.io/crypto/onramp/requirements-sessions \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"customerId": "W9kL817BBS7bNEwxAZaX4z",
"serviceProviders": [
"BANXA",
"UPHOLD"
]
}
'import requests
url = "https://api-sb.meld.io/crypto/onramp/requirements-sessions"
payload = {
"customerId": "W9kL817BBS7bNEwxAZaX4z",
"serviceProviders": ["BANXA", "UPHOLD"]
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({customerId: 'W9kL817BBS7bNEwxAZaX4z', serviceProviders: ['BANXA', 'UPHOLD']})
};
fetch('https://api-sb.meld.io/crypto/onramp/requirements-sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sb.meld.io/crypto/onramp/requirements-sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'customerId' => 'W9kL817BBS7bNEwxAZaX4z',
'serviceProviders' => [
'BANXA',
'UPHOLD'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-sb.meld.io/crypto/onramp/requirements-sessions"
payload := strings.NewReader("{\n \"customerId\": \"W9kL817BBS7bNEwxAZaX4z\",\n \"serviceProviders\": [\n \"BANXA\",\n \"UPHOLD\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-sb.meld.io/crypto/onramp/requirements-sessions")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customerId\": \"W9kL817BBS7bNEwxAZaX4z\",\n \"serviceProviders\": [\n \"BANXA\",\n \"UPHOLD\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sb.meld.io/crypto/onramp/requirements-sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"customerId\": \"W9kL817BBS7bNEwxAZaX4z\",\n \"serviceProviders\": [\n \"BANXA\",\n \"UPHOLD\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "Ny9YeB5gTh8WaQc3DrUf7k",
"customerId": "W9kL817BBS7bNEwxAZaX4z",
"serviceProviders": [
"BANXA",
"UPHOLD"
],
"readyWhen": "ALL",
"expiresAt": "2026-11-04T15:28:30Z",
"token": "<session token>",
"requirementsActions": {
"version": 1,
"endpoint": "/crypto/onramp/requirements-sessions/Ny9YeB5gTh8WaQc3DrUf7k/actions",
"bearerTokenPointer": "/token",
"operations": [
{
"operation": "READ",
"idempotencyKeyRequired": false
},
{
"operation": "RUN_STEP",
"idempotencyKeyRequired": true
}
]
}
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}Create a requirements session
Mints a requirements session for one customer and up to five providers. Call it from your backend with an API key that can create orders, and pass the 201 response unchanged to Meld.ensureReady in your app or page. The SDK then runs the customer’s requirements for those providers with the session token, and your API key never leaves your backend. The token is a bearer for this customer, these providers and this order only, and it expires after 30 minutes (expiresAt): never log or store it. Requirements sessions are unversioned, so every Meld-Version answers the same, and each provider’s checklist is the one GET /crypto/onramp/{serviceProvider}/requirements returns at Meld-Version 2026-11-01. They are enabled per account: until yours is, the call answers 403 REQUIREMENTS_SESSIONS_NOT_ENABLED. Responses carry Cache-Control: no-store.
curl --request POST \
--url https://api-sb.meld.io/crypto/onramp/requirements-sessions \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"customerId": "W9kL817BBS7bNEwxAZaX4z",
"serviceProviders": [
"BANXA",
"UPHOLD"
]
}
'import requests
url = "https://api-sb.meld.io/crypto/onramp/requirements-sessions"
payload = {
"customerId": "W9kL817BBS7bNEwxAZaX4z",
"serviceProviders": ["BANXA", "UPHOLD"]
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({customerId: 'W9kL817BBS7bNEwxAZaX4z', serviceProviders: ['BANXA', 'UPHOLD']})
};
fetch('https://api-sb.meld.io/crypto/onramp/requirements-sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sb.meld.io/crypto/onramp/requirements-sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'customerId' => 'W9kL817BBS7bNEwxAZaX4z',
'serviceProviders' => [
'BANXA',
'UPHOLD'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-sb.meld.io/crypto/onramp/requirements-sessions"
payload := strings.NewReader("{\n \"customerId\": \"W9kL817BBS7bNEwxAZaX4z\",\n \"serviceProviders\": [\n \"BANXA\",\n \"UPHOLD\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-sb.meld.io/crypto/onramp/requirements-sessions")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customerId\": \"W9kL817BBS7bNEwxAZaX4z\",\n \"serviceProviders\": [\n \"BANXA\",\n \"UPHOLD\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sb.meld.io/crypto/onramp/requirements-sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"customerId\": \"W9kL817BBS7bNEwxAZaX4z\",\n \"serviceProviders\": [\n \"BANXA\",\n \"UPHOLD\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "Ny9YeB5gTh8WaQc3DrUf7k",
"customerId": "W9kL817BBS7bNEwxAZaX4z",
"serviceProviders": [
"BANXA",
"UPHOLD"
],
"readyWhen": "ALL",
"expiresAt": "2026-11-04T15:28:30Z",
"token": "<session token>",
"requirementsActions": {
"version": 1,
"endpoint": "/crypto/onramp/requirements-sessions/Ny9YeB5gTh8WaQc3DrUf7k/actions",
"bearerTokenPointer": "/token",
"operations": [
{
"operation": "READ",
"idempotencyKeyRequired": false
},
{
"operation": "RUN_STEP",
"idempotencyKeyRequired": true
}
]
}
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}{
"code": "<string>",
"errors": [
"<string>"
],
"message": "<string>",
"requestId": "<string>",
"serviceProviderDetails": {
"code": "5034",
"message": "Digital currency and blockchain combination is restricted for customer's country"
},
"timestamp": "2026-08-14T09:41:22.482+00:00"
}Headers
Body
Who the session is for, and what for
Response
The session. Pass it to the SDK unchanged
The session. Pass it to Meld.ensureReady unchanged, and never log it: it carries the token