Global payouts integration guide

This guide walks through the primary flows for integrating with Latitude’s global payouts product. You’ll learn how to create recipients (individuals with the global_payouts product type), optionally lock exchange rates with quotes, and execute transfers.

Before you start, make sure you’re familiar with the API basics — authentication, idempotency, webhooks, and prefunding.

Summary

The high-level steps are as follows:

  1. Prerequisites
    • Prefund your Latitude account with USD or USDC
    • (Optional) Create a webhook subscription for transfer events
  2. Create a recipient with financial account details via POST /v1/individuals with the global_payouts product type
  3. (Optional) Create a quote to lock an exchange rate for 2 minutes
  4. Create a transfer — either referencing a quote or with transfer parameters directly
  5. Determine the outcome via webhooks or polling

Detailed Steps

Step 0: Prerequisites

a) Prefund your Latitude account

See API basics — Prefunded flows for funding options.

b) (Optional) Create a webhook subscription

Create a webhook subscription to be notified of transfer events. See API basics — Webhooks for details. The relevant event types for this flow are:

  • transfer.completed — sent when a transfer completes successfully
  • transfer.failed — sent when a transfer terminally fails

Step 1: Create a Recipient (Individual) with Financial Accounts

Create a recipient profile with financial account information. The required fields vary by country — see Country-specific details for the full reference.

Request:

1POST /v1/individuals HTTP/1.1
2Content-Type: application/json
3
4{
5 "product_types": ["global_payouts"],
6 "given_name": "Rahul",
7 "family_name": "Patel",
8 "country": "IN",
9 "email": "[email protected]",
10 "phone": "+919876543210",
11 "address": {
12 "line_1": "Flat 304, Building B, Sunshine Apartments",
13 "city": "Bengaluru",
14 "state": "Karnataka",
15 "postal_code": "560001"
16 },
17 "financial_accounts": [
18 {
19 "type": "upi",
20 "details": {
21 "upi_id": "9876543210@paytm"
22 }
23 }
24 ]
25}

Response:

1HTTP/1.1 201 Created
2Content-Type: application/json
3
4{
5 "id": "ind_01h3x5n6z7y8w9v0u1t2s3r4",
6 "given_name": "Rahul",
7 "family_name": "Patel",
8 "email": "[email protected]",
9 "phone": "+919876543210",
10 "country": "IN",
11 "product_types": ["global_payouts"],
12 "address": {
13 "line_1": "Flat 304, Building B, Sunshine Apartments",
14 "line_2": null,
15 "city": "Bengaluru",
16 "state": "Karnataka",
17 "postal_code": "560001"
18 },
19 "document": null,
20 "status": "pending",
21 "status_details": [],
22 "financial_accounts": [
23 {
24 "id": "fa_01h3x5n6z7y8w9v0u1t2s3r4",
25 "type": "upi",
26 "details": {
27 "upi_id": "9876543210@paytm"
28 },
29 "created_at": "2025-01-15T10:30:00Z",
30 "updated_at": "2025-01-15T10:30:00Z"
31 }
32 ],
33 "created_at": "2025-01-15T10:30:00Z",
34 "updated_at": "2025-01-15T10:30:00Z"
35}

Quotes and transfers still refer to this recipient using recipient_id in their responses.

Step 2: (Optional) Create a Quote

Create a quote to lock the conversion rate and fees for 2 minutes. You must specify either source_amount (to send a fixed amount) or destination_amount (to have a specific amount arrive).

Request:

1POST /v1/quotes HTTP/1.1
2Content-Type: application/json
3
4{
5 "financial_account_id": "fa_01h3x5n6z7y8w9v0u1t2s3r4",
6 "payout_method": "upi",
7 "source_amount": "100.00",
8 "source_currency": "usd",
9 "destination_currency": "inr"
10}

Response:

1HTTP/1.1 201 Created
2Content-Type: application/json
3
4{
5 "id": "qu_01h3x5n6z7y8w9v0u1t2s3r4",
6 "recipient_id": "rec_01h3x5n6z7y8w9v0u1t2s3r4",
7 "financial_account_id": "fa_01h3x5n6z7y8w9v0u1t2s3r4",
8 "source_amount": "100.00",
9 "source_currency": "usd",
10 "destination_amount": "8356.42",
11 "destination_currency": "inr",
12 "exchange_rate": "83.5642",
13 "payout_method": "upi",
14 "total_fee": "1.05",
15 "fee_currency": "usd",
16 "total_tax": "0.00",
17 "tax_currency": "usd",
18 "expires_at": "2025-01-15T10:32:00Z",
19 "created_at": "2025-01-15T10:30:00Z"
20}

Step 3: Create a Transfer

You can create a transfer in two ways:

Reference the quote ID to use the locked exchange rate and fees.

Request:

1POST /v1/transfers HTTP/1.1
2Content-Type: application/json
3
4{
5 "quote_id": "qu_01h3x5n6z7y8w9v0u1t2s3r4"
6}

Option B: Without a quote

Provide the transfer parameters directly. The exchange rate will be determined at the time the transfer is processed. You may specify either source_amount or destination_amount.

Request:

1POST /v1/transfers HTTP/1.1
2Content-Type: application/json
3
4{
5 "source_amount": "100.00",
6 "source_currency": "usd",
7 "destination_currency": "inr",
8 "financial_account_id": "fa_02j4y6p7a8b9c0d1e2f3g4h5",
9 "payout_method": "upi"
10}

Response (both options):

1HTTP/1.1 201 Created
2Content-Type: application/json
3
4{
5 "id": "tr_01h3x5n6z7y8w9v0u1t2s3r4",
6 "client_reference_id": null,
7 "source_amount": "100.00",
8 "source_currency": "usd",
9 "destination_amount": "8356.42",
10 "destination_currency": "inr",
11 "exchange_rate": "83.5642",
12 "recipient_id": "rec_01h3x5n6z7y8w9v0u1t2s3r4",
13 "financial_account_id": "fa_01h3x5n6z7y8w9v0u1t2s3r4",
14 "payout_method": "upi",
15 "status": "processing",
16 "total_fee": "1.05",
17 "fee_currency": "usd",
18 "total_tax": "0.00",
19 "tax_currency": "usd",
20 "completed_in": null,
21 "created_at": "2025-01-15T10:30:00Z",
22 "updated_at": "2025-01-15T10:30:00Z"
23}

Step 4: Determine the Outcome

Once you’ve created a transfer, there are two options to determine the outcome:

  1. Webhooks (recommended): Listen for transfer.completed or transfer.failed events. See API basics — Webhooks.
  2. Polling: Call GET /v1/transfers/{id} to check the current status.