curl --request POST \
--url https://api.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"receiverAccountId": "c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60",
"currency": "USD",
"amount": 25,
"description": "Invoice settlement",
"idempotencyKey": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
'import requests
url = "https://api.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat"
payload = {
"receiverAccountId": "c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60",
"currency": "USD",
"amount": 25,
"description": "Invoice settlement",
"idempotencyKey": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
receiverAccountId: 'c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60',
currency: 'USD',
amount: 25,
description: 'Invoice settlement',
idempotencyKey: '3fa85f64-5717-4562-b3fc-2c963f66afa6'
})
};
fetch('https://api.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat', 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.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat",
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([
'receiverAccountId' => 'c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60',
'currency' => 'USD',
'amount' => 25,
'description' => 'Invoice settlement',
'idempotencyKey' => '3fa85f64-5717-4562-b3fc-2c963f66afa6'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat"
payload := strings.NewReader("{\n \"receiverAccountId\": \"c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60\",\n \"currency\": \"USD\",\n \"amount\": 25,\n \"description\": \"Invoice settlement\",\n \"idempotencyKey\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"receiverAccountId\": \"c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60\",\n \"currency\": \"USD\",\n \"amount\": 25,\n \"description\": \"Invoice settlement\",\n \"idempotencyKey\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"receiverAccountId\": \"c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60\",\n \"currency\": \"USD\",\n \"amount\": 25,\n \"description\": \"Invoice settlement\",\n \"idempotencyKey\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"id": "a1b2c3d4-e5f6-4789-9abc-def012345678",
"senderAccountId": "b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f",
"receiverAccountId": "c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60",
"chain": "BASE",
"asset": "USDC",
"amount": 25,
"fiatOrigin": {
"currency": "USD",
"amount": 25,
"exchangeRate": 1
},
"description": "Invoice settlement",
"idempotencyKey": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "COMPLETED",
"transactionHash": "0xa1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
"createdAt": "2026-01-15T09:30:00Z",
"updatedAt": "2026-01-15T09:30:02Z"
}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
]
}{
"success": false,
"errors": [
{
"code": "unauthenticated",
"message": "Please authenticate to perform this action."
}
]
}{
"success": false,
"errors": [
{
"code": "forbidden",
"message": "You do not have permission to access this resource."
}
]
}{
"success": false,
"errors": [
{
"code": "account-not-found",
"message": "The requested resource was not found."
}
]
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "internal-error",
"message": "An unexpected error occurred. Please try again later."
}
]
}Create a fiat transfer
Send a fiat-denominated transfer between two accounts.
curl --request POST \
--url https://api.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"receiverAccountId": "c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60",
"currency": "USD",
"amount": 25,
"description": "Invoice settlement",
"idempotencyKey": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
'import requests
url = "https://api.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat"
payload = {
"receiverAccountId": "c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60",
"currency": "USD",
"amount": 25,
"description": "Invoice settlement",
"idempotencyKey": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
receiverAccountId: 'c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60',
currency: 'USD',
amount: 25,
description: 'Invoice settlement',
idempotencyKey: '3fa85f64-5717-4562-b3fc-2c963f66afa6'
})
};
fetch('https://api.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat', 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.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat",
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([
'receiverAccountId' => 'c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60',
'currency' => 'USD',
'amount' => 25,
'description' => 'Invoice settlement',
'idempotencyKey' => '3fa85f64-5717-4562-b3fc-2c963f66afa6'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat"
payload := strings.NewReader("{\n \"receiverAccountId\": \"c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60\",\n \"currency\": \"USD\",\n \"amount\": 25,\n \"description\": \"Invoice settlement\",\n \"idempotencyKey\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"receiverAccountId\": \"c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60\",\n \"currency\": \"USD\",\n \"amount\": 25,\n \"description\": \"Invoice settlement\",\n \"idempotencyKey\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.venlyfinance.com/v1/accounts/{senderAccountId}/transfers/fiat")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"receiverAccountId\": \"c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60\",\n \"currency\": \"USD\",\n \"amount\": 25,\n \"description\": \"Invoice settlement\",\n \"idempotencyKey\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"id": "a1b2c3d4-e5f6-4789-9abc-def012345678",
"senderAccountId": "b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f",
"receiverAccountId": "c3b2a1f0-9d8c-4e3a-bf21-1a2b3c4d5e60",
"chain": "BASE",
"asset": "USDC",
"amount": 25,
"fiatOrigin": {
"currency": "USD",
"amount": 25,
"exchangeRate": 1
},
"description": "Invoice settlement",
"idempotencyKey": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "COMPLETED",
"transactionHash": "0xa1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
"createdAt": "2026-01-15T09:30:00Z",
"updatedAt": "2026-01-15T09:30:02Z"
}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
]
}{
"success": false,
"errors": [
{
"code": "unauthenticated",
"message": "Please authenticate to perform this action."
}
]
}{
"success": false,
"errors": [
{
"code": "forbidden",
"message": "You do not have permission to access this resource."
}
]
}{
"success": false,
"errors": [
{
"code": "account-not-found",
"message": "The requested resource was not found."
}
]
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "internal-error",
"message": "An unexpected error occurred. Please try again later."
}
]
}manage:transfers — see Required scopes.
Transfers a fiat amount from the sender to a receiver (receiverAccountId or receiverExternalId). The amount settles in the underlying stablecoin; the response includes a fiatOrigin block with the original currency and exchange rate. Send a unique idempotencyKey (safe retries).
Concept guide: Transfers
Authorizations
OAuth2 client credentials flow. Token endpoints:
- Token URL
- https://login-staging.venly.io/auth/realms/VenlyFinance/protocol/openid-connect/token
Headers
Which tenant the request is scoped to, among those your token grants. Omit it when the token grants exactly one tenant; it is required when the token grants more than one. A supplied value must exactly match a tenant the token grants.
Absent when required, blank, malformed, or naming a tenant the token does not grant — each gets
the same generic 403 forbidden, which reveals neither whether a tenant exists nor which ones
you may use. Send the header once: a repeated header is rejected the same way.
"3fa85f64-5717-4562-b3fc-2c963f66afa6"
Path Parameters
The account ID initiating the transfer
Body
Fiat currency code (e.g. EUR, USD)
1Transfer amount
Unique key to prevent duplicate operations on retry
1ID of the receiving account
External ID of the receiving account (alternative to receiverAccountId)
Supported blockchain network. Availability per chain depends on your company's configured
supportedChains — see Supported chains and assets.
AVALANCHE, BASE, ETHEREUM, POLYGON, SOLANA Crypto asset to settle in (e.g. USDC). Send together with chain to name exactly
which asset a fiat amount settles in.
Optional while currency maps to a single asset for your tenant. Required as soon as it
maps to more than one — for example USDC on two chains both denominated in USD — in which
case omitting the pair is rejected with ambiguous-asset rather than guessing. Read
GET /supported-assets
to see which applies to you.
"USDC"
Optional transfer description
Optional merchant reference
Was this page helpful?

