Funding Your Client Balance

Request an ephemeral DLT deposit address and send assets to fund your Movmint Client Balance.

Funding Your Client Balance

To use a Client Balance as the source or target of an FX transaction, you first need to deposit funds. The POST /client/balance/fund endpoint returns an ephemeral DLT deposit address for a specified asset and network. Sending funds to that address credits your balance account once on-chain settlement is confirmed and TRM screening passes.

How It Works

  1. Call POST /client/balance/fund with the asset and network you want to deposit.
  2. Movmint returns a deposit_address and an expires_at timestamp.
  3. Send the desired amount of the asset to deposit_address before it expires.
  4. Movmint detects the deposit on-chain and credits pending_balance on your account.
  5. Once the deposit is fully settled and passes compliance screening, pending_balance converts to available_balance.

Deposit addresses are ephemeral. Each call to this endpoint returns a new address that is only monitored until expires_at. Do not reuse deposit addresses across sessions or share them between users.

Request

POST /client/balance/fund
Authorization: Bearer <your-token>
Content-Type: application/json

Request Body

FieldTypeRequiredDescription
assetstringYesThe asset to fund (e.g. USDC, EURC, BTC).
networkstringYesThe DLT network for the deposit. One of: ethereum, base, solana, bitcoin, sanddollar.

Code Examples

Go

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
)

const baseURL = "https://sandbox.api.movmint.com/v1"

func main() {
	body := map[string]string{
		"asset":   "USDC",
		"network": "ethereum",
	}

	payload, err := json.Marshal(body)
	if err != nil {
		log.Fatalf("marshalling request: %v", err)
	}

	req, err := http.NewRequest(http.MethodPost, baseURL+"/client/balance/fund", bytes.NewReader(payload))
	if err != nil {
		log.Fatalf("creating request: %v", err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer <your-token>")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("sending request: %v", err)
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatalf("reading response: %v", err)
	}

	if resp.StatusCode != http.StatusOK {
		log.Fatalf("unexpected status %d: %s", resp.StatusCode, respBody)
	}

	fmt.Println(string(respBody))
}

TypeScript

const BASE_URL = "https://sandbox.api.movmint.com/v1";

async function fundClientBalance(): Promise<void> {
  const response = await fetch(`${BASE_URL}/client/balance/fund`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Bearer <your-token>",
    },
    body: JSON.stringify({
      asset: "USDC",
      network: "ethereum",
    }),
  });

  if (!response.ok) {
    throw new Error(`Request failed with status ${response.status}`);
  }

  const data = await response.json();
  console.log(JSON.stringify(data, null, 2));
}

fundClientBalance();

Java

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class FundBalanceExample {

    private static final String BASE_URL = "https://sandbox.api.movmint.com/v1";

    public static void main(String[] args) throws Exception {
        String payload = """
            {
              "asset": "USDC",
              "network": "ethereum"
            }
            """;

        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(BASE_URL + "/client/balance/fund"))
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer <your-token>")
                .POST(HttpRequest.BodyPublishers.ofString(payload))
                .build();

        HttpResponse<String> response = client.send(
                request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() != 200) {
            System.err.printf("Unexpected status %d: %s%n",
                    response.statusCode(), response.body());
            System.exit(1);
        }

        System.out.println(response.body());
    }
}

Rust

use reqwest::header::{AUTHORIZATION, CONTENT_TYPE};
use serde_json::json;

const BASE_URL: &str = "https://sandbox.api.movmint.com/v1";

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let body = json!({
        "asset": "USDC",
        "network": "ethereum"
    });

    let client = reqwest::Client::new();
    let response = client
        .post(format!("{BASE_URL}/client/balance/fund"))
        .header(CONTENT_TYPE, "application/json")
        .header(AUTHORIZATION, "Bearer <your-token>")
        .json(&body)
        .send()
        .await?;

    if !response.status().is_success() {
        let status = response.status();
        let text = response.text().await?;
        eprintln!("Unexpected status {status}: {text}");
        std::process::exit(1);
    }

    let data: serde_json::Value = response.json().await?;
    println!("{}", serde_json::to_string_pretty(&data)?);

    Ok(())
}

Example Response

A successful POST /client/balance/fund returns HTTP 200:

{
  "client_account_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "ledger_account": "cl_acmecorp_funds_USDC",
  "asset": "USDC",
  "network": "ethereum",
  "deposit_address": "0xabc123def4567890abc123def4567890abc12345",
  "expires_at": "2025-06-15T13:00:00Z"
}

Response Fields

FieldDescription
client_account_idThe UUID of the Client Balance account that will be credited when the deposit is confirmed.
ledger_accountThe internal ledger account name (cl_{CLIENTNAME}_funds_{ASSET}).
assetThe asset to be deposited.
networkThe DLT network on which the deposit address is valid.
deposit_addressThe ephemeral on-chain address to send funds to.
expires_atTimestamp after which the address will no longer be monitored. Send funds before this time.

Error Responses

HTTP StatusCause
400Invalid request — unsupported asset/network combination or malformed request body.
402Your organization does not have an active Product subscription covering the requested asset.
500An internal error occurred. Retry the request or contact Movmint support.

Next Steps