Skip to main content

Fiat Transfers Quickstart

Set up fiat funding and withdraw flows in the Sandbox environment.

This guides walks you through the steps to send fiat to the Paxos Platform as well as move money to an external bank account using the Fiat Transfers, Transfers and Profiles APIs. Once completed, similar workflows can be implemented in Production. If you already have a Sandbox Account, this guide should take less than one hour to complete.

Authenticate in Sandbox

Both the funding and withdrawal flows require the same scopes, so for simplicity one authentication call should be all you need to complete both flows.

When creating API credentials via the Dashboard, the transfer:write_sandbox_fiat_deposit scope may not appear in the UI. Including the scope when authenticating may result in an invalid_scope error. Contact Support if you run into any issues using this scope.

Add the transfer:read_fiat_account, transfer:write_fiat_account, transfer:read_fiat_deposit_instructions, transfer:write_fiat_deposit_instructions, transfer:write_fiat_withdrawal, transfer:write_sandbox_fiat_deposit, transfer:read_transfer and funding:read_profile scopes to your Sandbox Account under the API Management setting and then authenticate in Sandbox using the scopes.

curl --location 'https://oauth.sandbox.paxos.com/oauth2/token' \
--form grant_type=client_credentials \
--form client_id={paxos_client_id} \
--form client_secret={paxos_secret} \
--form scope='transfer:read_fiat_account transfer:write_fiat_account transfer:read_fiat_deposit_instructions transfer:write_fiat_deposit_instructions transfer:write_fiat_withdrawal transfer:write_sandbox_fiat_deposit transfer:read_transfer funding:read_profile'

Confirm the response includes requisite scopes and save the access_token to use in the request authorization header throughout this guide.

{
"access_token": "{access_token}",
"expires_in": 3599, // Seconds (59 Minutes and 59 Seconds)
"scope": "transfer:read_fiat_account transfer:write_fiat_account transfer:read_fiat_deposit_instructions transfer:write_fiat_deposit_instructions transfer:write_fiat_withdrawal transfer:write_sandbox_fiat_deposit transfer:read_transfer funding:read_profile",
"token_type": "bearer"
}
note

You must include the Authorization header with your bearer token on all API requests -H "Authorization: Bearer $TOKEN".

Funding Flow

To move USD onto the platform, first use Create Fiat Deposit Instructions to retrieve the Paxos banking information and specify which Profile balance to credit. Then, use the returned banking information, found in fiat_network_instructions object, along with the memo_id, to transfer funds to Paxos.

We'll be following the recommended fiat deposit workflow:

1. Create Fiat Deposit Instructions

Get instructions from Paxos on how to deposit fiat using Create Fiat Deposit Instructions.

info
  • For wires, use fiat_network “WIRE”. Specify international (SWIFT) or US (Fedwire) by setting routing_number_type to “ABA” (for Fedwire) or “SWIFT” (for SWIFT).
  • For CUBIX, use fiat_network CUBIX. Do not use routing_number_type.

Retrieve the profile_id and identity_id from your records. Use your omnibus profile_id and your corporate identity_id created for you by Paxos.

Create deposit instructions for international wires. Include the following body parameters in the request:

curl --location 'https://api.sandbox.paxos.com/v2/transfer/fiat-deposit-instructions' \
--request 'POST' \
--header 'Authorization: Bearer {access_token}' \
--data '{
"profile_id": "5fc6d191-193c-4e28-94fa-656bbdbdfaad",
"fiat_network": "WIRE",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"ref_id": "idempotence_id",
"routing_number_type": "SWIFT",
"metadata": {
"my_id": "4024ee50-eefb-4f2e-85c7-e7899c0b7da5"
}
}'

Upon successful request, the acknowledgment response confirms your request has been received.

{
"id": "f190b163-208f-4d73-8deb-4fb8b24add00",
"profile_id": "5fc6d191-193c-4e28-94fa-656bbdbdfaad",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"created_at": "2024-01-28T04:23:11.738801Z",
"ref_id": "idempotence_id",
"status": "VALID",
"memo_id": "9CFXQSCMSPLFHXLZ",
"fiat_network_instructions": {
"wire": {
"account_number": "7339119",
"fiat_account_owner_address": {
"country": "US",
"address1": "450 Lexington Ave. #3952",
"city": "New York",
"province": "NY",
"zip_code": "10163"
},
"routing_details": {
"routing_number_type": "SWIFT",
"routing_number": "031302971",
"bank_name": "Customers Bank",
"bank_address": {
"country": "USA",
"address1": "701 Reading Avenue",
"city": "West Reading",
"province": "PA",
"zip_code": "19611"
}
}
},
"fiat_account_owner": {
"institution_details": {
"name": "Paxos Trust Company, LLC"
}
},
"metadata": {
"my_id": "4024ee50-eefb-4f2e-85c7-e7899c0b7da5"
}
}
}

You will need the memo_id from the response on the next step in order to fund the Profile.

2. Send Fiat to Paxos

Send a wire (SWIFT, Fedwire) or CUBIX transfer to Paxos, referencing the memo_id to fund your Profile.

For Sandbox environment emulate the wire deposit using Initiate Sandbox Fiat Deposit.

curl --location 'https://api.sandbox.paxos.com/v2/sandbox/fiat-deposits' \
--request 'POST' \
--header 'Authorization: Bearer {access_token}' \
--data '{
"amount": "150.33",
"asset": "USD",
"memo_id": "9CFXQSCMSPLFHXLZ",
"fiat_network_instructions": {
"wire": {
"account_number": "1234567",
"fiat_account_owner_address": {
"country": "US",
"address1": "456 Main Street",
"city": "New York",
"province": "NY",
"zip_code": "10101"
},
"routing_details": {
"routing_number_type": "SWIFT",
"routing_number": "031302971",
"bank_name": "Customers Bank",
"bank_address": {
"country": "USA",
"address1": "123 Bank Street",
"city": "New York",
"province": "NY",
"zip_code": "10101"
}
}
}
},
"fiat_account_owner": {
"institution_details": {
"name": "Paxos Trust Company, LLC"
}
}
}'

You should get an empty response with 200 status code.

It can take a minute to process the deposit on the backend.

note

In production, send a real wire (SWIFT, Fedwire) or CUBIX transfer to Paxos, referencing the production memo_id (not sandbox) to fund your Profile.

3. Check Status of Deposit

Find the deposit using List Transfers.

Include the profile_id query parameter to filter out transfers to all other Profiles.

curl --location 'https://api.sandbox.paxos.com/v2/transfer/transfers?order=DESC&type=WIRE_DEPOSIT&limit=2&profile_ids=5fc6d191-193c-4e28-94fa-656bbdbdfaad&limit=1' \
--request 'GET' \
--header 'Authorization: Bearer {access_token}'

Response:

{   "items": [
{ "account_id": "91f91384-30d4-46c2-9118-7f3cec676a2c",
"amount": "150.33",
"asset": "USD",
"auto_conversion": {},
"balance_asset": "USD",
"created_at": "2024-01-28T00:48:00.222744Z",
"customer_id": "4eaffe58-df0e-4559-8dec-fdae231684e9",
"direction": "CREDIT",
"fee": "30",
"id": "cca46bf3-2dab-4ab5-a4f1-7b1b75956a29",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"profile_id": "5fc6d191-193c-4e28-94fa-656bbdbdfaad",
"status": "COMPLETED",
"total": "120.33",
"type": "WIRE_DEPOSIT",
"updated_at": "2024-01-28T00:48:00.332602Z"
}
],
"next_page_cursor": "TAISDAiA-9qtBhCQtcyeARjCwa8M"
}

4. View Updated Balances

View updated balances using Get Profile Balance.

curl --location 'https://api.sandbox.paxos.com/v2/profiles/5fc6d191-193c-4e28-94fa-656bbdbdfaad/balances/USD' \
--request 'GET' \
--header 'Authorization: Bearer {access_token}'

Response:

{
"asset": "USD",
"available": "120.33",
"trading": "0"
}

Withdrawal Flow

To move USD off the Platform, first use Create Fiat Account to let Paxos know where to transfer the funds. Then, use the returned Fiat Account id with Create Fiat Withdrawal to transfer funds to the external account.

We'll be following the recommended fiat withdrawal workflow:

1. Create Fiat Account

Save your external bank account information on Paxos using Create Fiat Account.

note

For CUBIX, the wallet_address on fiat_network_instructions is not a crypto wallet address, it is a Customers Bank account wallet address.

Include the following body parameters in your request to create fiat accounts for US domestic wires:

curl --location 'https://api.sandbox.paxos.com/v2/transfer/fiat-accounts' \
--request 'POST' \
--header 'Authorization: Bearer {access_token}' \
--data '{
"ref_id": "idempotence_id",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"fiat_account_owner": {
"institution_details": {
"name": "Company"
}
},
"fiat_network_instructions": {
"wire": {
"account_number": "74600021314512",
"fiat_account_owner_address": {
"country": "USA",
"address1": "456 Main Street, NY",
"city": "New York",
"province": "NY",
"zip_code": "10101"
},
"routing_details": {
"routing_number_type": "ABA",
"routing_number": "031302971",
"bank_name": "Customers Bank",
"bank_address": {
"country": "USA",
"address1": "123 Bank Street",
"city": "New York",
"province": "NY",
"zip_code": "10101"
}
}
}
},
"metadata": {
"test_ref_id": "47aa7538-e2d2-47b3-8600-44a7965dd357",
"key_2": "2"
}
}'

Upon successful request, the acknowledgment response confirms your request has been received.

{
"id": "cc1b6606-a8a3-4a8f-8b9b-5456d96448bf",
"ref_id": "idempotence_id",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"fiat_account_owner": {
"person_details": {
"name": "Company"
},
"fiat_network_instructions": {
"wire": {
"account_number": "74600021314512",
"fiat_account_owner_address": {
"country": "USA",
"address1": "456 Main Street, NY",
"city": "New York",
"province": "NY",
"zip_code": "10101"
},
"routing_details": {
"routing_number_type": "ABA",
"routing_number": "031302971",
"bank_name": "Customers Bank",
"bank_address": {
"country": "USA",
"address1": "123 Bank Street",
"city": "New York",
"province": "NY",
"zip_code": "10101"
}
}
}
}
},
"status": "PENDING",
"metadata": {
"test_ref_id": "47aa7538-e2d2-47b3-8600-44a7965dd357",
"key_2": "2"
},
"created_at": "2024-01-28T22:14:25.731494Z"
}

Note the id in the response, it will be required to check the Account status in the next steps.

2. Confirm Sufficient Funds

Confirm sufficient funds in the profile to process the withdrawal using Get Profile Balance.

curl --location 'https://api.sandbox.paxos.com/v2/profiles/5fc6d191-193c-4e28-94fa-656bbdbdfaad/balances/USD' \
--request 'GET' \
--header 'Authorization: Bearer {access_token}'

Response:

{
"asset": "USD",
"available": "120.33",
"trading": "0"
}

3. Retrieve Bank Account Status

Retrieve the status of your external bank account using Get Fiat Account and providing the id from the Create Fiat Account response.

info

There are three statuses for Fiat Accounts: "PENDING", "APPROVED", "REJECTED". While on "PENDING", Paxos is processing your fiat account. Fiat Account status needs to be "APPROVED" before Fiat Account can be used for withdrawals.

Request:

curl --request 'GET' --location 'https://api.sandbox.paxos.com/v2/transfer/fiat-accounts/cc1b6606-a8a3-4a8f-8b9b-5456d96448bf'

Response:

{   
"account_id": "91f91384-30d4-46c2-9118-7f3cec676a2c",
"created_at": "2024-01-28T22:14:25.731494Z",
"fiat_account_owner": {
"person_details": {
"name": "Company"
}
},
"fiat_network_instructions": {
"wire": {
"account_number": "74600021314512",
"fiat_account_owner_address": {
"country": "USA",
"address1": "456 Main Street, NY",
"city": "New York",
"province": "NY",
"address2": "",
"zip_code": "10101"
},
"routing_details": {
"routing_number_type": "ABA",
"routing_number": "031302971",
"bank_name": "Customers Bank",
"bank_address": {
"country": "USA",
"address1": "123 Bank Street",
"city": "New York",
"province": "NY",
"zip_code": "10101"
}
}
}
},
"id": "cc1b6606-a8a3-4a8f-8b9b-5456d96448bf",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"ref_id": "idempotence_id",
"status": "APPROVED",
"metadata": {
"test_ref_id": "47aa7538-e2d2-47b3-8600-44a7965dd357",
"key_2": "2"
}
}

From the response find the id of the bank record for the user. It must be in APPROVED status.

4. Create Fiat Withdrawal

Initiate a fiat withdrawal from Paxos into your external bank account using Create Fiat Withdrawal.

Initiate a CUBIX withdrawal. Specify the fiat_account_id of the Fiat Account from the Create Fiat Account response.

curl --location 'https://api.sandbox.paxos.com/v2/transfer/fiat-withdrawals' \
--request 'POST' \
--header 'Authorization: Bearer {access_token}' \
--data '{
"ref_id": "idempotence_id",
"amount": "120",
"asset": "USD",
"fiat_account_id": "cc1b6606-a8a3-4a8f-8b9b-5456d96448bf",
"profile_id": "5fc6d191-193c-4e28-94fa-656bbdbdfaad",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"metadata": {
"custom_key": "custom_value"
}
}'

Response:

{
"amount": "100",
"asset": "USD",
"auto_conversion": {},
"balance_asset": "USD",
"created_at": "2024-01-28T22:39:02.279268Z",
"customer_id": "4eaffe58-df0e-4559-8dec-fdae231684e1",
"direction": "DEBIT",
"fee": "20",
"fiat_account_id": "cc1b6606-a8a3-4a8f-8b9b-5456d96448bf",
"id": "11a6f6e9-4219-4698-9d79-abfc1e346246",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"metadata": {
"custom_key": "custom_value"
},
"profile_id": "5fc6d191-193c-4e28-94fa-656bbdbdfaad",
"ref_id": "idempotence_id",
"status": "PENDING",
"total": "120",
"type": "CUBIX_WITHDRAWAL",
"updated_at": "2024-01-28T22:39:02.279268Z"
}
tip

It is recommended to have JWS request signing for Fiat Withdrawals. JWS request signing uses a public-key cryptography with a client-controlled private key. It adds an additional layer of security to withdrawals. It can prevent malicious withdrawals even if the API key is compromised. When used, all API calls with this key will require a JWS signature.

5. Check Status of Withdrawal

Check the status of the withdrawal using Get Transfer with the id from the previous step.

curl --location 'https://api.sandbox.paxos.com/v2/transfer/transfers/11a6f6e9-4219-4698-9d79-abfc1e346246' \
--request 'GET' \
--header 'Authorization: Bearer {access_token}'

Response:

{  "account_id": "91f91384-30d4-46c2-9118-7f3cec676a2c",
"amount": "100",
"asset": "USD",
"auto_conversion": {},
"balance_asset": "USD",
"created_at": "2024-01-28T22:39:02.279268Z",
"customer_id": "4eaffe58-df0e-4559-8dec-fdae231684e1",
"direction": "DEBIT",
"fee": "20",
"fiat_account_id": "cc1b6606-a8a3-4a8f-8b9b-5456d96448bf",
"id": "11a6f6e9-4219-4698-9d79-abfc1e346246",
"identity_id": "8a398cb6-4e3b-4868-9cea-a1c567856e68",
"metadata": {
"custom_key": "custom_value"
},
"profile_id": "5fc6d191-193c-4e28-94fa-656bbdbdfaad",
"ref_id": "idempotence_id",
"status": "COMPLETE",
"total": "120",
"type": "WIRE_WITHDRAWAL",
"updated_at": "2024-01-28T22:39:05.613881Z"}

6. View Updated Balances

View updated balances using Get Profile Balance and passing the profile_id and USD asset in the endpoint's path.

curl --location 'https://api.sandbox.paxos.com/v2/profiles/5fc6d191-193c-4e28-94fa-656bbdbdfaad/balances/USD \'
--request 'GET' \
--header 'Authorization: Bearer {access_token}'

Response:

{
"asset": "USD",
"available": "0.33",
"trading": "0"
}