Creating a FlowLink
Create a FlowLink with POST /flowlink by specifying an immutable source, destination, and receiver. Movmint returns a persistent deposit address. Examples in Go, TypeScript, Java, Rust, and Python.
Overview
POST /flowlink creates a FlowLink and returns the generated persistent DLT deposit address. The source, destination, and receiver fields are immutable once created.
POST https://api.sandbox.movmint.io/flowlink
Authorization: Bearer <access_token>
x-idempotency-key: <uuid>
Content-Type: application/json
Request
| Field | Required | Description |
|---|---|---|
source.asset | yes | Source asset: USDC, EURC, ETH, or BTC. |
source.network | yes | Source network: ethereum, base, solana, or bitcoin. |
destination.type | yes | CARD, BANK_ACCOUNT, or DLT_WALLET. |
destination.asset | yes | Target asset: USD, CAD, BSD, SD, USDC, ETH, or BTC. |
destination.details | yes | Type-specific delivery details (see below). |
receiver.name | yes | Receiver's name. |
receiver.address | yes | Receiver's postal address (street, city, postal_code, country required; state optional). |
metadata | no | Arbitrary client-provided key/value data. |
You must have an active Product subscription for the source/destination asset pair, or creation fails with 402.
Destination details by type
DLT_WALLET
{ "wallet_address": "0xfeed...", "network": "ethereum" }network is one of ethereum, base, solana, bitcoin, sanddollar.
BANK_ACCOUNT
{
"routing_number": "987654321",
"account_number": "123456789",
"account_holder_name": "Acme Corp",
"account_holder_address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" },
"bank_name": "Example Bank"
}CARD
{
"card_number": "4111111111111111",
"cardholder_name": "Acme Corp",
"cardholder_address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" }
}
Sensitive dataCard and bank account numbers are submitted in plaintext over TLS, encrypted at rest, and masked on responses (e.g.,
411111******1111). Thereceiverandaccount_holder/cardholderaddresses use ISO 3166-1 alpha-2 country codes.
Code examples
The examples create a FlowLink that converts incoming USDC (Ethereum) to USD and delivers it to a bank account.
cURL
curl -X POST https://api.sandbox.movmint.io/flowlink \
-H "Authorization: Bearer <access_token>" \
-H "x-idempotency-key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"source": { "asset": "USDC", "network": "ethereum" },
"destination": {
"type": "BANK_ACCOUNT",
"asset": "USD",
"details": {
"routing_number": "987654321",
"account_number": "123456789",
"account_holder_name": "Acme Corp",
"account_holder_address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" },
"bank_name": "Example Bank"
}
},
"receiver": {
"name": "Acme Corp",
"address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" }
},
"metadata": { "purpose": "treasury-sweep" }
}'Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"github.com/google/uuid"
)
const baseURL = "https://api.sandbox.movmint.io"
func main() {
token := "<access_token>"
body := map[string]any{
"source": map[string]any{"asset": "USDC", "network": "ethereum"},
"destination": map[string]any{
"type": "BANK_ACCOUNT",
"asset": "USD",
"details": map[string]any{
"routing_number": "987654321",
"account_number": "123456789",
"account_holder_name": "Acme Corp",
"account_holder_address": map[string]any{
"street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS",
},
"bank_name": "Example Bank",
},
},
"receiver": map[string]any{
"name": "Acme Corp",
"address": map[string]any{
"street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS",
},
},
"metadata": map[string]any{"purpose": "treasury-sweep"},
}
payload, _ := json.Marshal(body)
req, _ := http.NewRequest(http.MethodPost, baseURL+"/flowlink", bytes.NewReader(payload))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("x-idempotency-key", uuid.NewString())
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusCreated {
log.Fatalf("create flowlink failed (%d): %s", resp.StatusCode, out)
}
fmt.Println(string(out))
}TypeScript
import { randomUUID } from "crypto";
const BASE_URL = "https://api.sandbox.movmint.io";
async function createFlowLink(token: string) {
const res = await fetch(`${BASE_URL}/flowlink`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"x-idempotency-key": randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
source: { asset: "USDC", network: "ethereum" },
destination: {
type: "BANK_ACCOUNT",
asset: "USD",
details: {
routing_number: "987654321",
account_number: "123456789",
account_holder_name: "Acme Corp",
account_holder_address: { street: "1 Main St", city: "Nassau", postal_code: "00000", country: "BS" },
bank_name: "Example Bank",
},
},
receiver: {
name: "Acme Corp",
address: { street: "1 Main St", city: "Nassau", postal_code: "00000", country: "BS" },
},
metadata: { purpose: "treasury-sweep" },
}),
});
if (res.status !== 201) {
throw new Error(`Create FlowLink failed (${res.status}): ${await res.text()}`);
}
return res.json();
}
console.log(await createFlowLink("<access_token>"));Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.UUID;
public class CreateFlowLink {
private static final String BASE_URL = "https://api.sandbox.movmint.io";
public static void main(String[] args) throws Exception {
String token = "<access_token>";
String payload = """
{
"source": { "asset": "USDC", "network": "ethereum" },
"destination": {
"type": "BANK_ACCOUNT",
"asset": "USD",
"details": {
"routing_number": "987654321",
"account_number": "123456789",
"account_holder_name": "Acme Corp",
"account_holder_address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" },
"bank_name": "Example Bank"
}
},
"receiver": {
"name": "Acme Corp",
"address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" }
},
"metadata": { "purpose": "treasury-sweep" }
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/flowlink"))
.header("Authorization", "Bearer " + token)
.header("x-idempotency-key", UUID.randomUUID().toString())
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 201) {
throw new RuntimeException("Create FlowLink failed (" + response.statusCode()
+ "): " + response.body());
}
System.out.println(response.body());
}
}Rust
use serde_json::json;
use uuid::Uuid;
const BASE_URL: &str = "https://api.sandbox.movmint.io";
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let token = "<access_token>";
let body = json!({
"source": { "asset": "USDC", "network": "ethereum" },
"destination": {
"type": "BANK_ACCOUNT",
"asset": "USD",
"details": {
"routing_number": "987654321",
"account_number": "123456789",
"account_holder_name": "Acme Corp",
"account_holder_address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" },
"bank_name": "Example Bank"
}
},
"receiver": {
"name": "Acme Corp",
"address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" }
},
"metadata": { "purpose": "treasury-sweep" }
});
let client = reqwest::Client::new();
let resp = client
.post(format!("{BASE_URL}/flowlink"))
.bearer_auth(token)
.header("x-idempotency-key", Uuid::new_v4().to_string())
.json(&body)
.send()
.await?;
if resp.status().as_u16() != 201 {
let status = resp.status();
return Err(format!("create flowlink failed ({status}): {}", resp.text().await?).into());
}
let data: serde_json::Value = resp.json().await?;
println!("{}", serde_json::to_string_pretty(&data)?);
Ok(())
}Python
import uuid
import requests
BASE_URL = "https://api.sandbox.movmint.io"
def create_flowlink(token: str) -> dict:
resp = requests.post(
f"{BASE_URL}/flowlink",
headers={
"Authorization": f"Bearer {token}",
"x-idempotency-key": str(uuid.uuid4()),
"Content-Type": "application/json",
},
json={
"source": {"asset": "USDC", "network": "ethereum"},
"destination": {
"type": "BANK_ACCOUNT",
"asset": "USD",
"details": {
"routing_number": "987654321",
"account_number": "123456789",
"account_holder_name": "Acme Corp",
"account_holder_address": {
"street": "1 Main St", "city": "Nassau",
"postal_code": "00000", "country": "BS",
},
"bank_name": "Example Bank",
},
},
"receiver": {
"name": "Acme Corp",
"address": {
"street": "1 Main St", "city": "Nassau",
"postal_code": "00000", "country": "BS",
},
},
"metadata": {"purpose": "treasury-sweep"},
},
timeout=30,
)
resp.raise_for_status() # expects 201
return resp.json()
print(create_flowlink("<access_token>"))Example response (201)
201){
"flowlink_id": "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde",
"organization_id": "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809",
"user_id": "0f9e8d7c-6b5a-4321-fedc-ba9876543210",
"status": "active",
"source": {
"asset": "USDC",
"network": "ethereum",
"deposit_address": "0xabc123def4567890abc123def4567890abc12345",
"deposit_address_id": "dpa_01H..."
},
"destination": {
"type": "BANK_ACCOUNT",
"asset": "USD",
"details": {
"routing_number": "987654321",
"account_number": "*****6789",
"account_holder_name": "Acme Corp",
"bank_name": "Example Bank"
}
},
"receiver": { "name": "Acme Corp", "address": { "street": "1 Main St", "city": "Nassau", "postal_code": "00000", "country": "BS" } },
"metadata": { "purpose": "treasury-sweep" },
"created_at": "2026-06-24T12:00:00Z",
"updated_at": "2026-06-24T12:00:00Z"
}Store flowlink_id (for lifecycle management and transactions) and source.deposit_address (where depositors send funds). The address is persistent and reusable.
Error responses
| HTTP | Cause |
|---|---|
400 | Invalid request parameters. |
402 | No active Product subscription for the source/destination asset pair. |
409 | A FlowLink with an equivalent configuration already exists. |
500 | Internal server error — retry with backoff. |
Next steps
Continue to Using a FlowLink to send deposits, manage the lifecycle, and read transaction history.
Updated 2 months ago
