---
updatedAt: 2026-06-24T15:11:37.000Z
---

Fetch the complete documentation index at: https://docs.movmint.io/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Using a FlowLink

Send deposits to trigger automatic conversion and delivery, manage the FlowLink lifecycle (pause, resume, disable), and read transaction history. Examples in Go, TypeScript, Java, Rust, and Python.

## Sending deposits

Using a FlowLink is simple: send the source asset to the `deposit_address` returned at [creation](./create-flowlink.md). No further API calls are required — the deposit triggers the whole flow automatically.

When a deposit arrives at an `active` FlowLink, Movmint:

1. detects and accepts the deposit and records it on the ledger,
2. screens it via TRM Labs (sanctions/risk),
3. converts it at the **current market rate** with your client-specific spread and fees, and
4. delivers the target asset to the preconfigured destination (DLT transfer, push-to-card, or ACH/FedNow bank transfer).

Each deposit is processed as an **independent** transaction; concurrent deposits are queued and processed sequentially. Because pricing happens at deposit time, there is no quote to lock or capture.

> 📘 **Delivery timing**
> As with [Quote & Capture delivery](../../FX%20Services/fx-services/capture.md#when-can-i-expect-funds-to-be-delivered), wall-clock time depends on the destination rail: DLT delivery is bounded by network confirmation, push-to-card is minutes to hours, and bank (ACH/FedNow) ranges from near-instant to a few business days. A deposit flagged by screening is held for compliance review before delivery.

### What happens to deposits when not active

| FlowLink status | Behavior on deposit                                                                                         |
| --------------- | ----------------------------------------------------------------------------------------------------------- |
| `active`        | Processed straight-through.                                                                                 |
| `paused`        | Held; processed when the FlowLink is resumed (you are alerted that a deposit arrived at a paused FlowLink). |
| `disabled`      | The address is decommissioned; any held funds are returned per policy.                                      |

## Managing the lifecycle

Three endpoints move a FlowLink between states. All are `POST`, take the `flowlink_id` in the path, require an `x-idempotency-key` header, and return the updated FlowLink object.

| Action  | Endpoint                               | Valid from           | Result                                                       |
| ------- | -------------------------------------- | -------------------- | ------------------------------------------------------------ |
| Pause   | `POST /flowlink/{flowlink_id}/pause`   | `active`             | `paused` — deposits are held.                                |
| Resume  | `POST /flowlink/{flowlink_id}/resume`  | `paused`             | `active` — held deposits are queued for processing.          |
| Disable | `POST /flowlink/{flowlink_id}/disable` | `active` or `paused` | `disabled` — permanent; create a new FlowLink to resume use. |

Calling an action from the wrong state returns `409` (e.g., resuming a FlowLink that is not paused). An unknown `flowlink_id` returns `404`.

### Lifecycle code examples

The examples define a single helper that performs any lifecycle action (`pause`, `resume`, or `disable`).

#### cURL

```bash
FLOWLINK_ID="2b7a1f4c-9d8e-4a3b-bc12-3456789abcde"
# Pause
curl -X POST "https://api.sandbox.movmint.io/flowlink/$FLOWLINK_ID/pause" \
  -H "Authorization: Bearer <access_token>" -H "x-idempotency-key: $(uuidgen)"
# Resume
curl -X POST "https://api.sandbox.movmint.io/flowlink/$FLOWLINK_ID/resume" \
  -H "Authorization: Bearer <access_token>" -H "x-idempotency-key: $(uuidgen)"
# Disable
curl -X POST "https://api.sandbox.movmint.io/flowlink/$FLOWLINK_ID/disable" \
  -H "Authorization: Bearer <access_token>" -H "x-idempotency-key: $(uuidgen)"
```

#### Go

```go
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"

	"github.com/google/uuid"
)

const baseURL = "https://api.sandbox.movmint.io"

// action is one of "pause", "resume", "disable".
func lifecycle(token, flowlinkID, action string) (string, error) {
	url := fmt.Sprintf("%s/flowlink/%s/%s", baseURL, flowlinkID, action)
	req, _ := http.NewRequest(http.MethodPost, url, nil)
	req.Header.Set("Authorization", "Bearer "+token)
	req.Header.Set("x-idempotency-key", uuid.NewString())

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("%s failed (%d): %s", action, resp.StatusCode, body)
	}
	return string(body), nil
}

func main() {
	out, err := lifecycle("<access_token>", "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde", "pause")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(out)
}
```

#### TypeScript

```typescript
import { randomUUID } from "crypto";

const BASE_URL = "https://api.sandbox.movmint.io";
type Action = "pause" | "resume" | "disable";

async function lifecycle(token: string, flowlinkId: string, action: Action) {
  const res = await fetch(`${BASE_URL}/flowlink/${flowlinkId}/${action}`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "x-idempotency-key": randomUUID(),
    },
  });

  if (!res.ok) {
    throw new Error(`${action} failed (${res.status}): ${await res.text()}`);
  }
  return res.json();
}

console.log(await lifecycle("<access_token>", "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde", "pause"));
```

#### Java

```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 FlowLinkLifecycle {

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

    // action is one of "pause", "resume", "disable".
    static String lifecycle(String token, String flowlinkId, String action) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(BASE_URL + "/flowlink/" + flowlinkId + "/" + action))
                .header("Authorization", "Bearer " + token)
                .header("x-idempotency-key", UUID.randomUUID().toString())
                .POST(HttpRequest.BodyPublishers.noBody())
                .build();

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

        if (response.statusCode() != 200) {
            throw new RuntimeException(action + " failed (" + response.statusCode()
                    + "): " + response.body());
        }
        return response.body();
    }

    public static void main(String[] args) throws Exception {
        System.out.println(lifecycle("<access_token>",
                "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde", "pause"));
    }
}
```

#### Rust

```rust
use uuid::Uuid;

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

// action is one of "pause", "resume", "disable".
async fn lifecycle(token: &str, flowlink_id: &str, action: &str)
    -> Result<serde_json::Value, Box<dyn std::error::Error>>
{
    let client = reqwest::Client::new();
    let resp = client
        .post(format!("{BASE_URL}/flowlink/{flowlink_id}/{action}"))
        .bearer_auth(token)
        .header("x-idempotency-key", Uuid::new_v4().to_string())
        .send()
        .await?;

    if !resp.status().is_success() {
        let status = resp.status();
        return Err(format!("{action} failed ({status}): {}", resp.text().await?).into());
    }
    Ok(resp.json().await?)
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let fl = lifecycle("<access_token>", "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde", "pause").await?;
    println!("{}", serde_json::to_string_pretty(&fl)?);
    Ok(())
}
```

#### Python

```python
import uuid
import requests

BASE_URL = "https://api.sandbox.movmint.io"


def lifecycle(token: str, flowlink_id: str, action: str) -> dict:
    """action is one of 'pause', 'resume', 'disable'."""
    resp = requests.post(
        f"{BASE_URL}/flowlink/{flowlink_id}/{action}",
        headers={
            "Authorization": f"Bearer {token}",
            "x-idempotency-key": str(uuid.uuid4()),
        },
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()


print(lifecycle("<access_token>", "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde", "pause"))
```

## Reading transaction history

`GET /flowlink/{flowlink_id}/transactions` returns the executions for a FlowLink. Each record links the originating deposit, the market-rate conversion (rate, spread, fees), and the delivery.

| Parameter           | In     | Required | Description                                             |
| ------------------- | ------ | -------- | ------------------------------------------------------- |
| `flowlink_id`       | path   | yes      | The FlowLink to query.                                  |
| `status`            | query  | no       | Filter by transaction status (see below).               |
| `from` / `to`       | query  | no       | `date-time` bounds (inclusive).                         |
| `limit`             | query  | no       | Page size, 1–200 (default 50).                          |
| `cursor`            | query  | no       | Opaque cursor from a previous response's `next_cursor`. |
| `x-idempotency-key` | header | yes      | A UUID you generate.                                    |

### Transaction status lifecycle

| Status             | Meaning                                           |
| ------------------ | ------------------------------------------------- |
| `PENDING`          | Deposit registered, processing not yet started.   |
| `DEPOSIT_RECEIVED` | Deposit detected and accepted.                    |
| `COMPLIANCE_HOLD`  | Held by TRM screening, pending compliance review. |
| `HELD`             | Held (e.g., arrived at a paused FlowLink).        |
| `CONVERTING`       | FX conversion in progress.                        |
| `DELIVERING`       | Delivering the target asset to the destination.   |
| `COMPLETED`        | Delivered and settled.                            |
| `FAILED`           | Failed at some step.                              |
| `RETURNED`         | Funds returned to source.                         |

### Transaction code examples

#### cURL

```bash
curl "https://api.sandbox.movmint.io/flowlink/2b7a1f4c-9d8e-4a3b-bc12-3456789abcde/transactions?status=COMPLETED&limit=50" \
  -H "Authorization: Bearer <access_token>" \
  -H "x-idempotency-key: $(uuidgen)"
```

#### Go

```go
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"

	"github.com/google/uuid"
)

const baseURL = "https://api.sandbox.movmint.io"

func main() {
	token := "<access_token>"
	flowlinkID := "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde"

	q := url.Values{}
	q.Set("status", "COMPLETED")
	q.Set("limit", "50")

	endpoint := fmt.Sprintf("%s/flowlink/%s/transactions?%s", baseURL, flowlinkID, q.Encode())
	req, _ := http.NewRequest(http.MethodGet, endpoint, nil)
	req.Header.Set("Authorization", "Bearer "+token)
	req.Header.Set("x-idempotency-key", uuid.NewString())

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		log.Fatalf("get transactions failed (%d): %s", resp.StatusCode, body)
	}
	fmt.Println(string(body))
}
```

#### TypeScript

```typescript
import { randomUUID } from "crypto";

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

async function flowLinkTransactions(token: string, flowlinkId: string) {
  const url = new URL(`${BASE_URL}/flowlink/${flowlinkId}/transactions`);
  url.searchParams.set("status", "COMPLETED");
  url.searchParams.set("limit", "50");

  const res = await fetch(url, {
    headers: {
      Authorization: `Bearer ${token}`,
      "x-idempotency-key": randomUUID(),
    },
  });

  if (!res.ok) {
    throw new Error(`Get transactions failed (${res.status}): ${await res.text()}`);
  }
  return res.json();
}

console.log(await flowLinkTransactions("<access_token>", "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde"));
```

#### Java

```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 FlowLinkTransactions {

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

    public static void main(String[] args) throws Exception {
        String token = "<access_token>";
        String flowlinkId = "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde";

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(BASE_URL + "/flowlink/" + flowlinkId
                        + "/transactions?status=COMPLETED&limit=50"))
                .header("Authorization", "Bearer " + token)
                .header("x-idempotency-key", UUID.randomUUID().toString())
                .GET()
                .build();

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

        if (response.statusCode() != 200) {
            throw new RuntimeException("Get transactions failed (" + response.statusCode()
                    + "): " + response.body());
        }
        System.out.println(response.body());
    }
}
```

#### Rust

```rust
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 flowlink_id = "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde";

    let client = reqwest::Client::new();
    let resp = client
        .get(format!("{BASE_URL}/flowlink/{flowlink_id}/transactions"))
        .query(&[("status", "COMPLETED"), ("limit", "50")])
        .bearer_auth(token)
        .header("x-idempotency-key", Uuid::new_v4().to_string())
        .send()
        .await?;

    if !resp.status().is_success() {
        let status = resp.status();
        return Err(format!("get transactions failed ({status}): {}", resp.text().await?).into());
    }

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

#### Python

```python
import uuid
import requests

BASE_URL = "https://api.sandbox.movmint.io"


def flowlink_transactions(token: str, flowlink_id: str, **filters) -> dict:
    resp = requests.get(
        f"{BASE_URL}/flowlink/{flowlink_id}/transactions",
        headers={
            "Authorization": f"Bearer {token}",
            "x-idempotency-key": str(uuid.uuid4()),
        },
        params={"status": "COMPLETED", "limit": 50, **filters},
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()


print(flowlink_transactions("<access_token>", "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde"))
```

### Example response (`200`)

```json
{
  "data": [
    {
      "transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "flowlink_id": "2b7a1f4c-9d8e-4a3b-bc12-3456789abcde",
      "status": "COMPLETED",
      "deposit": {
        "tx_id": "0xdeadbeef...",
        "asset": "USDC",
        "network": "ethereum",
        "amount": 5000.00,
        "sender_address": "0xsender...",
        "received_at": "2026-06-24T12:10:00Z"
      },
      "conversion": {
        "from_asset": "USDC",
        "to_asset": "USD",
        "market_rate": 1.0,
        "spread": 0.0015,
        "fees": 2.50,
        "input_amount": 5000.00,
        "output_amount": 4990.00,
        "executed_at": "2026-06-24T12:10:20Z"
      },
      "delivery": {
        "destination_type": "BANK_ACCOUNT",
        "asset": "USD",
        "amount": 4990.00,
        "provider_reference": "ach_01H...",
        "delivered_at": "2026-06-24T12:11:00Z"
      },
      "created_at": "2026-06-24T12:10:00Z",
      "updated_at": "2026-06-24T12:11:00Z"
    }
  ],
  "next_cursor": null
}
```

Each transaction links the `deposit`, the `conversion` (with `market_rate`, `spread`, `fees`, and input/output amounts), and the `delivery` (with a `provider_reference` such as an ACH/FedNow payment ID, an iPayout transfer ID, or a DLT transfer ID). Page through results using `next_cursor` until it is `null`.

### Error responses

| HTTP  | Cause                                       |
| ----- | ------------------------------------------- |
| `404` | FlowLink not found.                         |
| `500` | Internal server error — retry with backoff. |