Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.venlyfinance.com/llms.txt

Use this file to discover all available pages before exploring further.

What is Fundflow?

Fundflow is Venly’s enterprise API platform that enables businesses to seamlessly convert between traditional fiat currency and cryptocurrency through a comprehensive REST API.

On-Ramp

Convert fiat to cryptocurrency via API

Off-Ramp

Convert cryptocurrency to fiat via API

Key Features

🔒 Enterprise-Grade Security

  • OAuth2 authentication
  • KYB (Know Your Business) verification
  • Optimistic locking for concurrent updates
  • Wallet ownership verification
  • Role-based access control

💰 Transparent Pricing

  • Company-specific fee tiers
  • Volume-based discounts
  • Real-time fee calculation API
  • Clear exchange rates

🌍 Multi-Currency Support

Fiat Currencies: EUR, USD, GBP Payment Networks:
  • EUR_SEPA (European SEPA transfers)
  • USD_WIRE, USD_ACH, USD_SWIFT (US transfers)
  • GBP_FPS, GBP_CHAPS (UK transfers)
  • OTHER_SWIFT (International transfers)
Cryptocurrencies:
  • USDC (Ethereum)
  • EURC (Ethereum)
  • USDS (Ethereum)
  • ETH (Ethereum)
  • POL (Polygon)
Blockchain Networks:
  • Ethereum
  • Polygon
  • Base
  • Arbitrum
  • Sui

Prerequisites

Before you begin, ensure you have: Company Account: Contact Venly to set up your company account
OAuth2 Credentials: Client ID and secret for authentication
API Access: Staging: https://api-fundflow-staging.venly.io/v1 · Production: https://api-fundflow.venly.io/v1
Development Environment: REST API client or SDK

Integration Steps

1

1. Authentication

Obtain an OAuth2 access token from Venly Identity Platform
POST https://login-staging.venly.io/auth/realms/VenlyFinance/protocol/openid-connect/token

Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Use the access token in all API requests:
Authorization: Bearer YOUR_ACCESS_TOKEN
2

2. Verify Company Status

Check your company’s KYB verification status
GET /v1/company
Response:
{
  "success": true,
  "result": {
    "id": "company-id",
    "name": "Your Company",
    "kybStatus": "VERIFIED",
    "invoicesUrl": "https://portal.venly.io/invoices"
  }
}
Your company must have kybStatus: "VERIFIED" to create ramp requests.
3

3. Add Bank Accounts

Register company bank accounts for fiat transactions
POST /v1/company-bank-accounts
Content-Type: application/json

{
  "bankAccountType": "EUR_SEPA",
  "name": "Primary EUR Account",
  "bankName": "Deutsche Bank",
  "companyName": "Your Company Ltd",
  "iban": "DE89370400440532013000",
  "bic": "COBADEFFXXX",
  "bankCountry": "DE",
  "beneficiaryAddressLine1": "123 Main Street",
  "beneficiaryCity": "Berlin",
  "beneficiaryPostalCode": "10115",
  "beneficiaryCountry": "DE",
  "supportedRampType": "ON_AND_OFF_RAMP"
}
Status Flow: PENDING → VERIFIED (manual review by Venly)
Bank accounts require manual verification. This process may take 1-2 business days.
4

4. Add Crypto Wallets

Register company cryptocurrency wallets
POST /v1/company-wallets
Content-Type: application/json

{
  "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
  "chain": "ETHEREUM",
  "description": "Main treasury wallet"
}
Status Flow: PENDING → VERIFIEDComplete the verification process to prove wallet ownership.
5

5. Get Available Currency Pairs

Retrieve supported currency pairs for your operationsFor On-Ramp:
GET /v1/ramp-requests/on-ramp/pairs
For Off-Ramp:
GET /v1/ramp-requests/off-ramp/pairs
Response:
{
  "success": true,
  "result": [
    {
      "from": {
        "id": "eur-id",
        "currency": "EUR",
        "label": "Euro"
      },
      "to": {
        "id": "usdc-id",
        "currency": "USDC",
        "chain": "ETHEREUM",
        "label": "USD Coin"
      }
    }
  ]
}
6

6. Calculate Fees

Calculate fees before creating ramp requests
POST /v1/fees/calculate
Content-Type: application/json

{
  "amount": 1000.00,
  "type": "ON_RAMP"
}
Response:
{
  "success": true,
  "result": {
    "amount": 10.00,
    "percentage": 1.0
  }
}
7

7. Create Ramp Requests

Create on-ramp or off-ramp transactionsOn-Ramp Example:
POST /v1/ramp-requests
Content-Type: application/json

{
  "rampType": "ON_RAMP",
  "amount": 1000.00,
  "fiatCurrencyId": "eur-currency-id",
  "cryptoCurrencyId": "usdc-ethereum-id",
  "companyWalletId": "your-wallet-id"
}
Off-Ramp Example:
POST /v1/ramp-requests
Content-Type: application/json

{
  "rampType": "OFF_RAMP",
  "amount": 0.5,
  "cryptoCurrencyId": "usdc-ethereum-id",
  "fiatCurrencyId": "eur-currency-id",
  "companyBankAccountId": "your-bank-account-id"
}
Request is created in AWAITING_APPROVAL status.
8

8. Approve Ramp Request

Approve the ramp request to proceed
POST /v1/ramp-requests/{id}/approve
Content-Type: application/json

{
  "version": 1
}
Status changes to AWAITING_FUNDS.
  • On-Ramp: Customer sends fiat to provided deposit bank account
  • Off-Ramp: Customer sends crypto to provided deposit wallet
9

9. Monitor Status

Poll or use webhooks to monitor ramp request status
GET /v1/ramp-requests/{id}
Status Flow:
AWAITING_APPROVAL → AWAITING_FUNDS → PROCESSING → SUCCEEDED

User Management

Invite Users

POST /v1/company/users/invite
Content-Type: application/json

{
  "email": "user@example.com",
  "role": "COMPANY_MANAGER",
  "firstName": "John",
  "lastName": "Doe"
}

User Roles

RolePermissions
COMPANY_ADMINFull access including user management
COMPANY_MANAGERCreate and manage ramp requests
COMPANY_VIEWERRead-only access

Update User Role

PUT /v1/company/users/{userId}/role
Content-Type: application/json

{
  "role": "COMPANY_ADMIN"
}

Best Practices

Authentication

Token Management: Implement token refresh logic to handle expired tokens gracefully.
// Example: Token refresh logic
async function getAccessToken() {
  if (tokenExpired()) {
    return await refreshToken();
  }
  return currentToken;
}

Error Handling

Optimistic Locking: Always handle HTTP 409 conflicts by fetching the latest version and retrying.
async function updateResource(id, data) {
  try {
    return await api.patch(`/resource/${id}`, data);
  } catch (error) {
    if (error.status === 409) {
      // Fetch latest version and retry
      const latest = await api.get(`/resource/${id}`);
      data.version = latest.version;
      return await api.patch(`/resource/${id}`, data);
    }
    throw error;
  }
}

Pagination

Efficient Pagination: Use appropriate page sizes and implement cursor-based pagination for large datasets.
GET /v1/ramp-requests?page=1&size=50&sortOn=createdAt&sortOrder=DESC

Webhooks

Real-time Updates: Configure webhooks for real-time notifications instead of polling.
Configure webhooks to receive notifications for:
  • Ramp request status changes
  • Payment received confirmations
  • Transaction completions

Testing

Staging Environment

Use the staging environment for testing:
  • Test OAuth2 authentication
  • Create test ramp requests
  • Verify webhook integrations
  • Test error scenarios

Test Scenarios

  1. Successful On-Ramp: Create, approve, and complete an on-ramp request
  2. Successful Off-Ramp: Create, approve, and complete an off-ramp request
  3. Cancellation: Create and cancel a ramp request
  4. Rejection: Create and reject a ramp request
  5. Version Conflict: Test optimistic locking behavior

Common Integration Patterns

Pattern 1: Automated On-Ramp

// 1. Create ramp request
const request = await createRampRequest({
  rampType: 'ON_RAMP',
  amount: 1000,
  fiatCurrencyId: eurId,
  cryptoCurrencyId: usdcId,
  companyWalletId: walletId
});

// 2. Auto-approve if within limits
if (request.amount <= autoApprovalLimit) {
  await approveRampRequest(request.id, request.version);
}

// 3. Monitor status via webhook
// Webhook handler will process status updates

Pattern 2: Batch Processing

// Process multiple ramp requests efficiently
const requests = await listRampRequests({
  status: 'AWAITING_APPROVAL',
  page: 1,
  size: 100
});

for (const request of requests.result) {
  if (shouldApprove(request)) {
    await approveRampRequest(request.id, request.version);
  }
}

Security Considerations

Never expose:
  • OAuth2 client secrets
  • Access tokens in client-side code
  • Private keys or seed phrases
  • API credentials in version control

Secure Storage

  • Store credentials in environment variables or secure vaults
  • Use HTTPS for all API communications
  • Implement proper access controls
  • Rotate credentials regularly

API Scopes

Request only the OAuth2 scopes you need:
  • view:ramp-request - View ramp requests
  • create:ramp-request - Create ramp requests
  • approve:ramp-request - Approve ramp requests
  • manage:company-wallet - Manage wallets
  • manage:company-bank-account - Manage bank accounts

Next Steps

API Reference

Explore full API documentation

Accounts Guide

Manage bank accounts & wallets

Transactions

Create and manage ramp requests

Fees

Understand fee structure

Security

Security best practices

Quick Reference

Quick API overview

Multi-Rail Routing

Understand how payments are automatically routed across rails

Support

Need help with integration?
  • Email: support@venly.io
  • API Status: Check system status for any ongoing issues