curl --request POST \
--url https://api.venlyfinance.com/v1/accounts/{accountId}/payouts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"payoutRouteId": "b2c3d4e5-f607-4819-a2b3-c4d5e6f70819",
"cryptoAmount": 100,
"idempotencyKey": "payout-2026-07-14-0001"
}
'import requests
url = "https://api.venlyfinance.com/v1/accounts/{accountId}/payouts"
payload = {
"payoutRouteId": "b2c3d4e5-f607-4819-a2b3-c4d5e6f70819",
"cryptoAmount": 100,
"idempotencyKey": "payout-2026-07-14-0001"
}
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({
payoutRouteId: 'b2c3d4e5-f607-4819-a2b3-c4d5e6f70819',
cryptoAmount: 100,
idempotencyKey: 'payout-2026-07-14-0001'
})
};
fetch('https://api.venlyfinance.com/v1/accounts/{accountId}/payouts', 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/{accountId}/payouts",
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([
'payoutRouteId' => 'b2c3d4e5-f607-4819-a2b3-c4d5e6f70819',
'cryptoAmount' => 100,
'idempotencyKey' => 'payout-2026-07-14-0001'
]),
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/{accountId}/payouts"
payload := strings.NewReader("{\n \"payoutRouteId\": \"b2c3d4e5-f607-4819-a2b3-c4d5e6f70819\",\n \"cryptoAmount\": 100,\n \"idempotencyKey\": \"payout-2026-07-14-0001\"\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/{accountId}/payouts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"payoutRouteId\": \"b2c3d4e5-f607-4819-a2b3-c4d5e6f70819\",\n \"cryptoAmount\": 100,\n \"idempotencyKey\": \"payout-2026-07-14-0001\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.venlyfinance.com/v1/accounts/{accountId}/payouts")
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 \"payoutRouteId\": \"b2c3d4e5-f607-4819-a2b3-c4d5e6f70819\",\n \"cryptoAmount\": 100,\n \"idempotencyKey\": \"payout-2026-07-14-0001\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"id": "c3d4e5f6-0718-492a-b3c4-d5e6f708192a",
"accountId": "b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f",
"payoutRoute": {
"id": "b2c3d4e5-f607-4819-a2b3-c4d5e6f70819",
"depositAsset": {
"chain": "BASE",
"name": "USDC"
},
"fiatCurrency": "USD",
"depositAddress": "0x9A7f4B2c1D3e5F6a8B0c2D4e6F8a0B2c4D6e8F0a",
"beneficiary": {
"id": "a1b2c3d4-e5f6-4708-9a1b-2c3d4e5f6071",
"partyId": "7e3b9c2a-1f4d-4a8b-9c11-2d6e8f0a1b22",
"rail": "US_ACH",
"label": "Jane's checking account",
"accountHolderName": "Jane Doe",
"bankName": "Example National Bank",
"details": {
"accountNumberLast4": "9012",
"abaRoutingNumber": "021000021",
"accountType": "CHECKING"
}
}
},
"rail": "US_ACH",
"cryptoAmount": 100,
"settledFiatAmount": null,
"fundingMode": "PULL",
"status": "REQUESTED",
"sendTxHash": null,
"requestedAt": "2026-07-14T11:00:00Z",
"completedAt": null,
"failureReason": null
}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "unauthenticated",
"message": "Please authenticate to perform this action."
}
]
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"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."
}
]
}Request a payout
Send crypto from an account wallet over a route and have the provider pay out fiat.
curl --request POST \
--url https://api.venlyfinance.com/v1/accounts/{accountId}/payouts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"payoutRouteId": "b2c3d4e5-f607-4819-a2b3-c4d5e6f70819",
"cryptoAmount": 100,
"idempotencyKey": "payout-2026-07-14-0001"
}
'import requests
url = "https://api.venlyfinance.com/v1/accounts/{accountId}/payouts"
payload = {
"payoutRouteId": "b2c3d4e5-f607-4819-a2b3-c4d5e6f70819",
"cryptoAmount": 100,
"idempotencyKey": "payout-2026-07-14-0001"
}
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({
payoutRouteId: 'b2c3d4e5-f607-4819-a2b3-c4d5e6f70819',
cryptoAmount: 100,
idempotencyKey: 'payout-2026-07-14-0001'
})
};
fetch('https://api.venlyfinance.com/v1/accounts/{accountId}/payouts', 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/{accountId}/payouts",
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([
'payoutRouteId' => 'b2c3d4e5-f607-4819-a2b3-c4d5e6f70819',
'cryptoAmount' => 100,
'idempotencyKey' => 'payout-2026-07-14-0001'
]),
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/{accountId}/payouts"
payload := strings.NewReader("{\n \"payoutRouteId\": \"b2c3d4e5-f607-4819-a2b3-c4d5e6f70819\",\n \"cryptoAmount\": 100,\n \"idempotencyKey\": \"payout-2026-07-14-0001\"\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/{accountId}/payouts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"payoutRouteId\": \"b2c3d4e5-f607-4819-a2b3-c4d5e6f70819\",\n \"cryptoAmount\": 100,\n \"idempotencyKey\": \"payout-2026-07-14-0001\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.venlyfinance.com/v1/accounts/{accountId}/payouts")
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 \"payoutRouteId\": \"b2c3d4e5-f607-4819-a2b3-c4d5e6f70819\",\n \"cryptoAmount\": 100,\n \"idempotencyKey\": \"payout-2026-07-14-0001\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"id": "c3d4e5f6-0718-492a-b3c4-d5e6f708192a",
"accountId": "b2a1f0e9-8c7d-4e3a-9f21-0a1b2c3d4e5f",
"payoutRoute": {
"id": "b2c3d4e5-f607-4819-a2b3-c4d5e6f70819",
"depositAsset": {
"chain": "BASE",
"name": "USDC"
},
"fiatCurrency": "USD",
"depositAddress": "0x9A7f4B2c1D3e5F6a8B0c2D4e6F8a0B2c4D6e8F0a",
"beneficiary": {
"id": "a1b2c3d4-e5f6-4708-9a1b-2c3d4e5f6071",
"partyId": "7e3b9c2a-1f4d-4a8b-9c11-2d6e8f0a1b22",
"rail": "US_ACH",
"label": "Jane's checking account",
"accountHolderName": "Jane Doe",
"bankName": "Example National Bank",
"details": {
"accountNumberLast4": "9012",
"abaRoutingNumber": "021000021",
"accountType": "CHECKING"
}
}
},
"rail": "US_ACH",
"cryptoAmount": 100,
"settledFiatAmount": null,
"fundingMode": "PULL",
"status": "REQUESTED",
"sendTxHash": null,
"requestedAt": "2026-07-14T11:00:00Z",
"completedAt": null,
"failureReason": null
}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "unauthenticated",
"message": "Please authenticate to perform this action."
}
]
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"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:pay-outs — see Required scopes.
Requests a PULL pay-out against an ACTIVE route: Venly sends crypto from the account wallet to the provider’s deposit address using the up-front permit, and the provider pays fiat to the beneficiary.
The route already fixes the beneficiary, lane, asset and fiat currency, so you supply only the route, the crypto amount, and an idempotency key.
201 is not a success signal. Permit allowance and account-wallet balance are deliberately not pre-checked. If either is insufficient, this call still returns 201 and the asynchronous send fails terminally — the pay-out moves to FAILED with a failureReason.Track the real outcome by polling Get a payout or by registering a webhook.REQUESTED → SENDING → PROVIDER_PROCESSING → COMPLETED. Note that a fiat leg can still bounce after completion, moving to RETURNED.
PUSH pay-outs are not created here — see Pay-outs.
Idempotency: the key must be unique per company across all idempotent endpoints. Reuse with a different body, or after the original failed, returns 422; reuse while the original is in flight returns 409.
Errors
The codes this endpoint can return, in addition to the standard errors. Branch oncode, never the message.
| HTTP | code | When |
|---|---|---|
422 | route-unresolved | the route does not resolve on this account |
422 | route-not-active | the route is not ACTIVE |
422 | unsupported-asset | the route’s lane is no longer supported for your tenant |
422 | idempotency-conflict | the key was reused with a different body, or after a failed original |
Authorizations
OAuth2 client credentials flow. Token endpoints:
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
Unique account identifier
Body
Requests a PULL pay-out. The route fixes the beneficiary, lane, asset and fiat currency, so there is no fiat target, no provider field and no funding-mode field.
The selected payout route. Must belong to this account and be ACTIVE.
Crypto amount to send to the provider's deposit address. Must be greater than zero, with at most 20 integer digits and 18 fractional digits.
100
Client-supplied idempotency key. Must be unique per company across all idempotent endpoints.
255"payout-2026-07-14-0001"
Response
Payout created (REQUESTED)
Was this page helpful?

