curl --request POST \
--url https://laso.finance/fund-card-from-account-balance \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"amount": 25
}'import requests
url = "https://laso.finance/fund-card-from-account-balance"
payload = { "amount": 25 }
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({amount: 25})
};
fetch('https://laso.finance/fund-card-from-account-balance', 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://laso.finance/fund-card-from-account-balance",
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([
'amount' => 25
]),
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://laso.finance/fund-card-from-account-balance"
payload := strings.NewReader("{\n \"amount\": 25\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://laso.finance/fund-card-from-account-balance")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 25\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://laso.finance/fund-card-from-account-balance")
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 \"amount\": 25\n}"
response = http.request(request)
puts response.read_body{
"top_up_id": "1761580800000",
"status": "paid",
"funded_usd": 25,
"note": "Your account balance has been debited and the amount is being delivered to your card balance, which usually takes under a minute."
}{
"error": "No card issuer account is linked to this wallet.",
"note": "Link it with POST /start-card-issuer-link (the account holder enters a one-time code; check progress with GET /get-card-issuer-status), or the account holder sets it up at https://laso.finance/agent/dashboard/verified/card."
}{
"error": "Missing or invalid Authorization header"
}{
"error": "Your account balance is $12.00. Lower the amount, or choose another way to pay.",
"code": "insufficient_account_balance",
"hint": "Check GET /get-account-balance and request that amount or less, or top up with a new payment through GET /fund-card-balance."
}{
"error": "Account is frozen",
"frozen_message": "Your account is frozen pending a compliance review. Contact support@laso.finance."
}{
"error": "A request with this Idempotency-Key is still being processed",
"code": "idempotency_key_in_progress"
}{
"error": "Idempotency-Key reused with a different request",
"code": "idempotency_key_reused"
}{
"error": "Adding from your account balance is unavailable right now. Nothing was charged. Please try again later or choose another way to pay.",
"code": "account_balance_funding_unavailable",
"hint": "Nothing was debited. Retry later, or top up with a new payment through GET /fund-card-balance."
}Top up a reloadable card from the account balance
Load the account holder’s reloadable card balance from their Laso account balance, the USDC already credited to the account (read it with GET /get-account-balance). GET /fund-card-balance takes a new payment; this spends money the account already holds, such as a paid request that could not be fulfilled.
Free. The account balance is debited exactly amount, and that amount lands on the card balance. Laso delivers it to the holder’s deposit address at the card issuer, usually within a minute.
Tracking. The response carries a top_up_id. Poll GET /list-card-transactions until that top-up’s status under top_ups is credited, or GET /get-card-deposit-address until balance reflects it, then call POST /create-reloadable-card. If the delivery fails, the amount is returned to the account balance.
Amount: $5 to $10,000, and no more than the account balance.
A linked card issuer account is required (see POST /start-card-issuer-link).
Requires a Bearer token from /auth or /get-card.
curl --request POST \
--url https://laso.finance/fund-card-from-account-balance \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"amount": 25
}'import requests
url = "https://laso.finance/fund-card-from-account-balance"
payload = { "amount": 25 }
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({amount: 25})
};
fetch('https://laso.finance/fund-card-from-account-balance', 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://laso.finance/fund-card-from-account-balance",
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([
'amount' => 25
]),
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://laso.finance/fund-card-from-account-balance"
payload := strings.NewReader("{\n \"amount\": 25\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://laso.finance/fund-card-from-account-balance")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 25\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://laso.finance/fund-card-from-account-balance")
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 \"amount\": 25\n}"
response = http.request(request)
puts response.read_body{
"top_up_id": "1761580800000",
"status": "paid",
"funded_usd": 25,
"note": "Your account balance has been debited and the amount is being delivered to your card balance, which usually takes under a minute."
}{
"error": "No card issuer account is linked to this wallet.",
"note": "Link it with POST /start-card-issuer-link (the account holder enters a one-time code; check progress with GET /get-card-issuer-status), or the account holder sets it up at https://laso.finance/agent/dashboard/verified/card."
}{
"error": "Missing or invalid Authorization header"
}{
"error": "Your account balance is $12.00. Lower the amount, or choose another way to pay.",
"code": "insufficient_account_balance",
"hint": "Check GET /get-account-balance and request that amount or less, or top up with a new payment through GET /fund-card-balance."
}{
"error": "Account is frozen",
"frozen_message": "Your account is frozen pending a compliance review. Contact support@laso.finance."
}{
"error": "A request with this Idempotency-Key is still being processed",
"code": "idempotency_key_in_progress"
}{
"error": "Idempotency-Key reused with a different request",
"code": "idempotency_key_reused"
}{
"error": "Adding from your account balance is unavailable right now. Nothing was charged. Please try again later or choose another way to pay.",
"code": "account_balance_funding_unavailable",
"hint": "Nothing was debited. Retry later, or top up with a new payment through GET /fund-card-balance."
}Authorizations
Firebase ID token from /auth or any paid route, sent as a Bearer token: Authorization: Bearer <id_token> (the Bearer prefix is required).
Headers
Optional client-generated unique key (a UUID works) that makes this write safe to retry. A retry with the same key within 24 hours returns the recorded response of the original request, marked with an Idempotency-Replayed: true header, instead of performing the write again. Reusing a key with a different body or route is rejected with 422 (code: idempotency_key_reused); a retry that arrives while the original is still running gets 409 (code: idempotency_key_in_progress), so wait a moment and retry with the same key. Keys are scoped to the authenticated account.
255Body
USD to move from the account balance onto the card balance (min $5, max $10,000).
5 <= x <= 10000Response
The account balance was debited and the top-up is on its way to the card balance.
Identifies this top-up under top_ups in GET /list-card-transactions.
Always paid: the account balance has been debited. Follow the top-up through bridging, delivered, and credited in GET /list-card-transactions.
"paid"
USD debited from the account balance and loaded onto the card balance.
What happens next and how to track it.
Was this page helpful?